ToC

Reference Frames, from frame_maker.scm.

Every frame has a name, and a frame that it is built on (which may be false). Every frame owns coordinates that it may coerce to an absolute event or that it may export as its representation of an absolute event.

(defprotocol IFrame
(coords->event [this coords]
"Accepts a coordinate representation `coords` of some `event` and returns a
coordinate-free representation of the event.
`coords` must be owned this this reference frame; [[coords->event]] will throw
if not.")
(event->coords [this event]
"Accepts a reference frame and an `event`, and returns this reference
frame's coordinate representation of the supplied `event`.")
(ancestor-frame [_]
"Returns the ancestor [[IFrame]] instance of this frame, or nil if there is
no ancestor.")
(frame-name [_]
"Returns the symbolic name of the suppplied frame.")
(params [_]
"Returns the parameters registered with the supplied frame."))
{:method-builders {#'emmy.calculus.frame/coords->event #object[emmy.calculus.frame$eval80363$fn__80364 0x263eaed9 "
emmy.calculus.frame$eval80363$fn__80364@263eaed9"
]
#'emmy.calculus.frame/params #object[emmy.calculus.frame$eval80363$fn__80377 0x7884fdb4 "
emmy.calculus.frame$eval80363$fn__80377@7884fdb4"
]
#'emmy.calculus.frame/frame-name #object[emmy.calculus.frame$eval80363$fn__80388 0x2b556598 "
emmy.calculus.frame$eval80363$fn__80388@2b556598"
]
#'emmy.calculus.frame/event->coords #object[emmy.calculus.frame$eval80363$fn__80399 0x7303f536 "
emmy.calculus.frame$eval80363$fn__80399@7303f536"
]
#'emmy.calculus.frame/ancestor-frame #object[emmy.calculus.frame$eval80363$fn__80412 0x2018c5e9 "
emmy.calculus.frame$eval80363$fn__80412@2018c5e9"
]
}
:method-map {:ancestor-frame :ancestor-frame :coords->event :coords->event :event->coords :event->coords :frame-name :frame-name :params :params} :on emmy.calculus.frame.IFrame :on-interface emmy.calculus.frame.IFrame :sigs {:ancestor-frame {:arglists ([_]) :col 4 :doc "
Returns the ancestor [[IFrame]] instance of this frame, or nil if there is↩︎ n10+ more elided"
:end-col 18 :end-row 13 :name ancestor-frame :row 13 :tag nil}
:coords->event {:arglists ([this coords]) :col 4 :doc "
Accepts a coordinate representation `coords` of some `event` and returns a↩︎ coor10+ more elided"
:end-col 17 :end-row 2 :name coords->event :row 2 :tag nil}
:event->coords {:arglists ([this event]) :col 4 :doc "
Accepts a reference frame and an `event`, and returns this reference↩︎ frame's10+ more elided"
:end-col 17 :end-row 9 :name event->coords :row 9 :tag nil}
:frame-name {:arglists ([_]) :col 4 :doc "
Returns the symbolic name of the suppplied frame."
:end-col 14 :end-row 17 :name frame-name :row 17 :tag nil}
:params {:arglists ([_]) :col 4 :doc "
Returns the parameters registered with the supplied frame."
:end-col 10 :end-row 20 :name params :row 20 :tag nil}}
:var #'emmy.calculus.frame/IFrame}
(defn frame?
"Returns true if `x` implements [[IFrame]], false otherwise."
[x]
(satisfies? IFrame x))
#object[emmy.calculus.frame$frame_QMARK_ 0x7f2ee503 "
emmy.calculus.frame$frame_QMARK_@7f2ee503"
]
(defn make-event
"Marks the input event `e` as an event via its metadata. The return value will
return `true` when passed to [[event?]]."
[e]
(vary-meta e assoc ::event? true))
#object[emmy.calculus.frame$make_event 0x7f5726db "
emmy.calculus.frame$make_event@7f5726db"
]
(defn event?
"Returns true if `e` is an event, false otherwise.
Make new events with [[make-event]]."
[e]
(::event? (meta e) false))
#object[emmy.calculus.frame$event_QMARK_ 0x1311d642 "
emmy.calculus.frame$event_QMARK_@1311d642"
]
(defn frame-owner
"Returns the owning [[IFrame]] instance of the supplied coordinates `coords`,
nil if there's no owner otherwise."
[coords]
(::owner (meta coords)))
#object[emmy.calculus.frame$frame_owner 0x75406e44 "
emmy.calculus.frame$frame_owner@75406e44"
]
(defn claim
"Marks (via metadata) the supplied set of `coords` as being owned by `owner`. If
`coords` already has an owner (that is not equal to `owner`), throws."
[coords owner]
(if-let [other (frame-owner coords)]
(if (= other owner)
coords
(u/illegal (str "Someone else owns these coords: " coords owner)))
(vary-meta coords assoc ::owner owner)))
#object[emmy.calculus.frame$claim 0x7dce9b12 "
emmy.calculus.frame$claim@7dce9b12"
]
(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))))))
#object[emmy.calculus.frame$frame_maker 0x3be91b8e "
emmy.calculus.frame$frame_maker@3be91b8e"
]