(ns unheard.time-object (:require [missionary.core :as m] [helins.interval.map :as imap])) ;; TODO: Update description (defn time-object "A time-object takes a start time, and end time, and a value. Value is a flow that will be consumed when the corresponding time tree is consumed at a point in time within the time-object's interval. " [start duration value] {:start start, :duration duration, :value value}) (defn lift "Lift collection of time objects to a phrase" [& children] {:start 0, :time-objects children}) ;; BUG c9be408 (defn phrase ;; TODO: Description [& children] (fn [start] {:start start, :time-objects (for [child children time-object (:time-objects child)] (update time-object :start (partial + start)))})) (comment (def a (phrase (lift (time-object 0 4 :x)) (lift (time-object 0 4 :a)))) (def b (phrase (a 0) (a 1) (lift (time-object 10 2 :x) (time-object 10 2 :b)) (lift (time-object 0 2 :y)))) (def c (phrase (b 0) (b 3))) (c 0)) (defn timeline "Primary timeline bookkeeping mehanism." [phrase] (let [{:keys [time-objects]} (phrase 0) m imap/empty] (if (seq? time-objects) (loop [time-objects time-objects m m] (let [{:keys [start duration value]} (first time-objects) m (imap/mark m start (+ start duration) value) rem (rest time-objects)] (if (seq rem) (recur rem m) m))) m))) (comment (def t (timeline a)) (def t (timeline c)) (get t 1)) (defn point-query "Query a timeline. Returns a flow of time objects." [timeline >at] (m/stream (m/ap (let [at (m/?< >at)] (get timeline at))))) (comment (def at (atom 0)) (def >at (m/watch at)) (def cancel ((m/reduce prn nil (point-query t >at)) prn prn)) (reset! at 1) (reset! at 14) (cancel))