(defn frame-maker
"Takes:
- `c->e`, a function mapping coordinates to events
- `e->c`, a function mapping events to coordinates
and returns a function that takes:
- a symbolic name
- an ancestor frame
- a dictionary of params
and returns instance of [[IFrame]].
Both `c->e` and `e->c` must accept three arguments:
- `ancestor-frame`
- the [[IFrame]] instance
- a map of parameters supplied to the returned function (possibly empty!)."
[c->e e->c]
(fn call
([name]
(call name nil {}))
([name ancestor-frame]
(call name ancestor-frame {}))
([name ancestor-frame params]
(reify IFrame
(ancestor-frame [_] ancestor-frame)
(frame-name [_] name)
(params [_] params)
(coords->event [this coords]
(assert (= (frame-owner coords) this))
(let [event ((c->e ancestor-frame this params) coords)]
(assert (event? event))
event))
(event->coords [this event]
(assert (event? event))
(let [coords ((e->c ancestor-frame this params) event)]
(assert (= (frame-owner coords) this))
coords))))))