An options map for the resolvers, and sid beside the clip it is in
Finishing the last commit, which traded a simpler definition for noisier call
sites: deleting the arity ladders left `(symbol/resolver sym st pal/index-of
nil nil)` at twenty-odd places, and two trailing nils tell a reader nothing
except to go and count positions.
The ladder was a symptom. The disease is five positional parameters, and the
split that matters is which of them are OPTIONAL:
store, palette positional, because neither is optional. A dense channel
cannot be read without the store it names — that is the
crash two commits ago — and every op carries a colour.
pose-tracks one call site, in `clip/resolver`'s own recursion
source/picture-fps two call sites
So the last three become one `opts` map, and the common call loses a nil. The
point is not the nil: it is that the sixth option, whenever it arrives, is a
key at one call site rather than a nil at fifty.
`clip/resolver` also had `sid` FOURTH, behind two arguments that say nothing
about which symbol is being resolved. It is second now, beside the clip it is
in: `(clip/resolver c :main store pal/index-of nil)`.
62 call sites rewritten by parsing the forms rather than by regex, because
`clip/resolver`'s arguments move past each other and a regex cannot see that.
An earlier attempt at this dropped `palette` on the floor and still compiled
at 62 sites — it only surfaced as an arity error, so if that had been a
same-arity mistake the tests would have been the last line of defence.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ee66680a0c
commit
624242b407
20 changed files with 84 additions and 81 deletions
|
|
@ -26,4 +26,4 @@
|
||||||
"Draw ops for one frame, via the specification path. The page uses
|
"Draw ops for one frame, via the specification path. The page uses
|
||||||
`symbol/resolver` instead; this is here for the REPL."
|
`symbol/resolver` instead; this is here for the REPL."
|
||||||
[f]
|
[f]
|
||||||
(symbol/eval-frame main f nil pal/index-of nil nil))
|
(symbol/eval-frame main f nil pal/index-of nil))
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@
|
||||||
own frame. Nil for a node that was not on that frame. It is how something
|
own frame. Nil for a node that was not on that frame. It is how something
|
||||||
drawn beside the picture, like a tracing photo, rides a node inside it without
|
drawn beside the picture, like a tracing photo, rides a node inside it without
|
||||||
resolving anything a second time."
|
resolving anything a second time."
|
||||||
[clip store palette sid {:keys [picture-fps] :as opts}]
|
[clip sid store palette {:keys [picture-fps] :as opts}]
|
||||||
(letfn [(build [sid chain pose-tracks]
|
(letfn [(build [sid chain pose-tracks]
|
||||||
(when (some #{sid} chain)
|
(when (some #{sid} chain)
|
||||||
(throw (ex-info "symbol cycle" {:chain (conj chain sid)})))
|
(throw (ex-info "symbol cycle" {:chain (conj chain sid)})))
|
||||||
|
|
@ -183,8 +183,9 @@
|
||||||
nodes (:nodes sym)
|
nodes (:nodes sym)
|
||||||
rank (symbol/draw-rank nodes (symbol/order nodes))
|
rank (symbol/draw-rank nodes (symbol/order nodes))
|
||||||
ids (sort-by rank (keys nodes))
|
ids (sort-by rank (keys nodes))
|
||||||
own (symbol/resolver sym store palette pose-tracks
|
own (symbol/resolver sym store palette
|
||||||
(assoc opts :source-fps (:fps clip)))
|
(assoc opts :pose-tracks pose-tracks
|
||||||
|
:source-fps (:fps clip)))
|
||||||
children (into {}
|
children (into {}
|
||||||
(for [[id n] nodes :when (= :instance (:kind n))]
|
(for [[id n] nodes :when (= :instance (:kind n))]
|
||||||
[id (build (:of n) (conj chain sid)
|
[id (build (:of n) (conj chain sid)
|
||||||
|
|
@ -243,7 +244,7 @@
|
||||||
Effects' anchor point are set once and left. A symbol that grows later keeps
|
Effects' anchor point are set once and left. A symbol that grows later keeps
|
||||||
its instances' pivots where they were, so nothing on screen moves."
|
its instances' pivots where they were, so nothing on screen moves."
|
||||||
[clip store sid]
|
[clip store sid]
|
||||||
(let [resolve (resolver clip store pal/index-of sid nil)
|
(let [resolve (resolver clip sid store pal/index-of nil)
|
||||||
bounds (fn [[x0 y0 x1 y1 :as b] x y]
|
bounds (fn [[x0 y0 x1 y1 :as b] x y]
|
||||||
(if b [(min x0 x) (min y0 y) (max x1 x) (max y1 y)] [x y x y]))
|
(if b [(min x0 x) (min y0 y) (max x1 x) (max y1 y)] [x y x y]))
|
||||||
[x0 y0 x1 y1]
|
[x0 y0 x1 y1]
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
[clip store sid frame id]
|
[clip store sid frame id]
|
||||||
(let [sym (clip/symbol clip sid)
|
(let [sym (clip/symbol clip sid)
|
||||||
sym (update sym :nodes select-keys (symbol/lineage (:nodes sym) id))
|
sym (update sym :nodes select-keys (symbol/lineage (:nodes sym) id))
|
||||||
r (symbol/resolver sym store pal/index-of nil {:source-fps (:fps clip)})]
|
r (symbol/resolver sym store pal/index-of {:source-fps (:fps clip)})]
|
||||||
(r frame)
|
(r frame)
|
||||||
r))
|
r))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@
|
||||||
(let [sid (:of n)
|
(let [sid (:of n)
|
||||||
frames (clip/frames document sid)
|
frames (clip/frames document sid)
|
||||||
loop? (get-in n [:time :loop?])
|
loop? (get-in n [:time :loop?])
|
||||||
resolve (clip/resolver document store pal/index-of sid nil)]
|
resolve (clip/resolver document sid store pal/index-of nil)]
|
||||||
(fn [f]
|
(fn [f]
|
||||||
(let [f (if loop? (mod f frames) f)]
|
(let [f (if loop? (mod f frames) f)]
|
||||||
(when (< -1 f frames)
|
(when (< -1 f frames)
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,13 @@
|
||||||
|
|
||||||
Two ways to evaluate one at a frame:
|
Two ways to evaluate one at a frame:
|
||||||
|
|
||||||
(eval-frame sym f store) THE SPECIFICATION. Allocating, order-free,
|
(eval-frame sym f store palette opts)
|
||||||
|
THE SPECIFICATION. Allocating, order-free,
|
||||||
obviously correct. Use it in tests and for a
|
obviously correct. Use it in tests and for a
|
||||||
one-off render.
|
one-off render.
|
||||||
|
|
||||||
(resolver sym store) -> (fn [f] ops). What playback uses. Caches the
|
(resolver sym store palette opts)
|
||||||
|
-> (fn [f] ops). What playback uses. Caches the
|
||||||
topological order and the z paths, holds one
|
topological order and the z paths, holds one
|
||||||
CURSOR per channel and one PREALLOCATED point
|
CURSOR per channel and one PREALLOCATED point
|
||||||
buffer per node, so a frame allocates the op
|
buffer per node, so a frame allocates the op
|
||||||
|
|
@ -422,11 +424,10 @@
|
||||||
the only place the space changes.
|
the only place the space changes.
|
||||||
|
|
||||||
This is the definition of what a frame means. `resolver` is what plays it."
|
This is the definition of what a frame means. `resolver` is what plays it."
|
||||||
[sym f store palette pose-tracks opts]
|
[sym f store palette {:keys [pose-tracks source-fps picture-fps]}]
|
||||||
(let [nodes (nodes-of sym)
|
(let [nodes (nodes-of sym)
|
||||||
choices (pose/prepare pose-tracks)
|
choices (pose/prepare pose-tracks)
|
||||||
traces (prepared-traces nodes)
|
traces (prepared-traces nodes)
|
||||||
{:keys [source-fps picture-fps]} opts
|
|
||||||
ord (order nodes)]
|
ord (order nodes)]
|
||||||
(eval-into {:read (fn [id path c lf]
|
(eval-into {:read (fn [id path c lf]
|
||||||
(ch/value-at c (channel-frame choices traces nodes
|
(ch/value-at c (channel-frame choices traces nodes
|
||||||
|
|
@ -481,8 +482,15 @@
|
||||||
|
|
||||||
The op maps themselves are allocated fresh, and deliberately: there are a dozen
|
The op maps themselves are allocated fresh, and deliberately: there are a dozen
|
||||||
of them per frame against hundreds of points, so pooling them would buy
|
of them per frame against hundreds of points, so pooling them would buy
|
||||||
nothing and cost the ability to hand an op list around as plain data."
|
nothing and cost the ability to hand an op list around as plain data.
|
||||||
[sym store palette pose-tracks {:keys [source-fps picture-fps]}]
|
|
||||||
|
`store` and `palette` are POSITIONAL because neither is optional: a dense
|
||||||
|
channel cannot be read without the store it names, and every op carries a
|
||||||
|
colour index. `opts` is a map because the rest genuinely are optional, and
|
||||||
|
because a fifth of them later is then a key rather than a nil at every one of
|
||||||
|
these call sites — which is what the arity ladder that used to be here was
|
||||||
|
standing in for."
|
||||||
|
[sym store palette {:keys [pose-tracks source-fps picture-fps]}]
|
||||||
(let [nodes (nodes-of sym)
|
(let [nodes (nodes-of sym)
|
||||||
choices (pose/prepare pose-tracks)
|
choices (pose/prepare pose-tracks)
|
||||||
traces (prepared-traces nodes)
|
traces (prepared-traces nodes)
|
||||||
|
|
|
||||||
|
|
@ -195,8 +195,7 @@
|
||||||
;; inside it still resolve — clip/resolver is the function that knows
|
;; inside it still resolve — clip/resolver is the function that knows
|
||||||
;; how.
|
;; how.
|
||||||
doc (assoc-in clip [:symbols sid] sym)
|
doc (assoc-in clip [:symbols sid] sym)
|
||||||
resolve-frame (clip/resolver doc store palette sid
|
resolve-frame (clip/resolver doc sid store palette {:picture-fps picture-fps})
|
||||||
{:picture-fps picture-fps})
|
|
||||||
ras (raster/make width height)
|
ras (raster/make width height)
|
||||||
bg (get palette :bg 0)]
|
bg (get palette :bg 0)]
|
||||||
(-> (audio! doc sid store audio-url)
|
(-> (audio! doc sid store audio-url)
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
:<- [::playback/display-fps]
|
:<- [::playback/display-fps]
|
||||||
(fn [[document sid store palette picture-fps] _]
|
(fn [[document sid store palette picture-fps] _]
|
||||||
(when (and document (clip/symbol document sid))
|
(when (and document (clip/symbol document sid))
|
||||||
(clip/resolver document store palette sid {:picture-fps picture-fps}))))
|
(clip/resolver document sid store palette {:picture-fps picture-fps}))))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
::shown
|
::shown
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
:disc (select-keys op [:kind :cx :cy :r])
|
:disc (select-keys op [:kind :cx :cy :r])
|
||||||
:rect (select-keys op [:kind :cx :cy :size])
|
:rect (select-keys op [:kind :cx :cy :size])
|
||||||
nil))
|
nil))
|
||||||
((clip/resolver document st pal/index-of sid nil) 0))))
|
((clip/resolver document sid st pal/index-of nil) 0))))
|
||||||
|
|
||||||
(defn symbol!
|
(defn symbol!
|
||||||
"Start carrying symbol `sid` of the loaded document into the open symbol."
|
"Start carrying symbol `sid` of the loaded document into the open symbol."
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
(/ dt n))))
|
(/ dt n))))
|
||||||
|
|
||||||
(deftest bench
|
(deftest bench
|
||||||
(let [res (symbol/resolver (clip/symbol @swarm/clip :main) @swarm/store pal/index-of nil nil)
|
(let [res (symbol/resolver (clip/symbol @swarm/clip :main) @swarm/store pal/index-of nil)
|
||||||
ras (raster/make 320 200)
|
ras (raster/make 320 200)
|
||||||
dest (js/Uint8ClampedArray. (* 320 200 4))
|
dest (js/Uint8ClampedArray. (* 320 200 4))
|
||||||
n 120]
|
n 120]
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
(defn- drawn [c path]
|
(defn- drawn [c path]
|
||||||
(partition 2 (take 6 (array-seq (:pts (first (filter #(= path (:node %))
|
(partition 2 (take 6 (array-seq (:pts (first (filter #(= path (:node %))
|
||||||
((clip/resolver c nil pal/index-of :main nil) 16))))))))
|
((clip/resolver c :main nil pal/index-of nil) 16))))))))
|
||||||
|
|
||||||
(defn- near? [a b] (every? #(< (js/Math.abs %) 1e-9) (map - (flatten a) (flatten b))))
|
(defn- near? [a b] (every? #(< (js/Math.abs %) 1e-9) (map - (flatten a) (flatten b))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
:channels {[:xform :pos] (ch/framed [120 50])}}}})
|
:channels {[:xform :pos] (ch/framed [120 50])}}}})
|
||||||
(assoc-in [:symbols :sym/test]
|
(assoc-in [:symbols :sym/test]
|
||||||
(assoc (get-in source [:symbols :main]) :id :sym/test)))
|
(assoc (get-in source [:symbols :main]) :id :sym/test)))
|
||||||
resolve (clip/resolver document nil pal/index-of :main nil)
|
resolve (clip/resolver document :main nil pal/index-of nil)
|
||||||
at (fn [f] (mapv (juxt :node :cx) (resolve f)))]
|
at (fn [f] (mapv (juxt :node :cx) (resolve f)))]
|
||||||
(is (empty? (clip/problems document)))
|
(is (empty? (clip/problems document)))
|
||||||
(is (= [[[:left :mark] 110]] (at 1)))
|
(is (= [[[:left :mark] 110]] (at 1)))
|
||||||
|
|
@ -75,9 +75,9 @@
|
||||||
:parent :root :z "a2"
|
:parent :root :z "a2"
|
||||||
:playback {:tracks {:mouth {0 0, 8 8}}}}}}
|
:playback {:tracks {:mouth {0 0, 8 8}}}}}}
|
||||||
:sym/poses symbol}}
|
:sym/poses symbol}}
|
||||||
resolve (clip/resolver document {"sizes" {:data values}} pal/index-of :main nil)
|
store {"sizes" {:data values}}
|
||||||
low-resolve (clip/resolver document {"sizes" {:data values}}
|
resolve (clip/resolver document :main store pal/index-of nil)
|
||||||
pal/index-of :main {:picture-fps 8})
|
low-resolve (clip/resolver document :main store pal/index-of {:picture-fps 8})
|
||||||
at (fn [f] (into {} (map (fn [op] [(:node op) op])) (resolve f)))
|
at (fn [f] (into {} (map (fn [op] [(:node op) op])) (resolve f)))
|
||||||
low-at (fn [f] (into {} (map (fn [op] [(:node op) op])) (low-resolve f)))]
|
low-at (fn [f] (into {} (map (fn [op] [(:node op) op])) (low-resolve f)))]
|
||||||
(is (empty? (clip/problems document)))
|
(is (empty? (clip/problems document)))
|
||||||
|
|
@ -98,14 +98,12 @@
|
||||||
"an explicit cut occurs at its exact local frame, even off the picture grid")
|
"an explicit cut occurs at its exact local frame, even off the picture grid")
|
||||||
(is (= 8 (:cx (get (low-at 8) [:first :eye])))
|
(is (= 8 (:cx (get (low-at 8) [:first :eye])))
|
||||||
"authored position ignores the picture grid")
|
"authored position ignores the picture grid")
|
||||||
(let [sym (get-in document [:symbols :sym/poses])
|
(let [sym (get-in document [:symbols :sym/poses])
|
||||||
opts {:source-fps 30 :picture-fps 8}]
|
opts {:source-fps 30 :picture-fps 8 :pose-tracks {:mouth {0 0, 8 20}}}]
|
||||||
(is (= (mapv #(select-keys % [:node :cx :size])
|
(is (= (mapv #(select-keys % [:node :cx :size])
|
||||||
(symbol/eval-frame sym 8 {"sizes" {:data values}}
|
(symbol/eval-frame sym 8 store pal/index-of opts))
|
||||||
pal/index-of {:mouth {0 0, 8 20}} opts))
|
|
||||||
(mapv #(select-keys % [:node :cx :size])
|
(mapv #(select-keys % [:node :cx :size])
|
||||||
((symbol/resolver sym {"sizes" {:data values}}
|
((symbol/resolver sym store pal/index-of opts) 8)))
|
||||||
pal/index-of {:mouth {0 0, 8 20}} opts) 8)))
|
|
||||||
"pure evaluation and playback apply the same pose choice"))))
|
"pure evaluation and playback apply the same pose choice"))))
|
||||||
|
|
||||||
(deftest stage-pose-edits-preserve-earlier-motion-and-survive-save
|
(deftest stage-pose-edits-preserve-earlier-motion-and-survive-save
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
{:keys [sid frame pts]} (nest/drawn-inside c nil :main [u] 16 drawn)
|
{:keys [sid frame pts]} (nest/drawn-inside c nil :main [u] 16 drawn)
|
||||||
c (paint/new-shape c sid :shape frame pts :brow)
|
c (paint/new-shape c sid :shape frame pts :brow)
|
||||||
[op] (filter #(= [u :shape] (:node %))
|
[op] (filter #(= [u :shape] (:node %))
|
||||||
((clip/resolver c nil pal/index-of :main nil) 16))]
|
((clip/resolver c :main nil pal/index-of nil) 16))]
|
||||||
(is (= :box sid))
|
(is (= :box sid))
|
||||||
(is (= 6 frame) "frame 16 of main is frame 6 of an instance placed at 10")
|
(is (= 6 frame) "frame 16 of main is frame 6 of an instance placed at 10")
|
||||||
(is (every? #(< (js/Math.abs %) 1e-9)
|
(is (every? #(< (js/Math.abs %) 1e-9)
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
(turn :mid v [5 -3] 0.3 1.5)
|
(turn :mid v [5 -3] 0.3 1.5)
|
||||||
(paint/new-shape :box :shape 4 [0 0 10 0 5 10] :brow))
|
(paint/new-shape :box :shape 4 [0 0 10 0 5 10] :brow))
|
||||||
draw #(take 6 (array-seq (:pts (first (filter (fn [op] (= [u v :shape] (:node op)))
|
draw #(take 6 (array-seq (:pts (first (filter (fn [op] (= [u v :shape] (:node op)))
|
||||||
((clip/resolver % nil pal/index-of :main nil) 16))))))
|
((clip/resolver % :main nil pal/index-of nil) 16))))))
|
||||||
{:keys [frame matrix time]} (nest/inside c nil :main [u v :shape] 16)
|
{:keys [frame matrix time]} (nest/inside c nil :main [u v :shape] 16)
|
||||||
out (js/Float64Array. 2)
|
out (js/Float64Array. 2)
|
||||||
seen (mapcat (fn [[x y]] (vec (array-seq (node/apply-pt! out 0 matrix x y))))
|
seen (mapcat (fn [[x y]] (vec (array-seq (node/apply-pt! out 0 matrix x y))))
|
||||||
|
|
@ -105,7 +105,7 @@
|
||||||
"What `sid` draws at each of `fs`, without the node paths a move changes:
|
"What `sid` draws at each of `fs`, without the node paths a move changes:
|
||||||
per frame, the sorted marks with their points rounded to a thousandth."
|
per frame, the sorted marks with their points rounded to a thousandth."
|
||||||
[c sid fs]
|
[c sid fs]
|
||||||
(let [resolve (clip/resolver c nil pal/index-of sid nil)
|
(let [resolve (clip/resolver c sid nil pal/index-of nil)
|
||||||
round #(/ (js/Math.round (* 1000 %)) 1000)]
|
round #(/ (js/Math.round (* 1000 %)) 1000)]
|
||||||
(mapv (fn [f]
|
(mapv (fn [f]
|
||||||
(sort-by str (map (fn [op]
|
(sort-by str (map (fn [op]
|
||||||
|
|
@ -251,7 +251,7 @@
|
||||||
(is (= [0 8] (:span heard))
|
(is (= [0 8] (:span heard))
|
||||||
"own frames 0-8: it starts on inner's 2 and inner ends on 10")
|
"own frames 0-8: it starts on inner's 2 and inner ends on 10")
|
||||||
(is (= [7 15] (node/placed-span heard)) "inner starts on 5 of outer")
|
(is (= [7 15] (node/placed-span heard)) "inner starts on 5 of outer")
|
||||||
(is (empty? ((clip/resolver c nil pal/index-of :inner nil) 3))
|
(is (empty? ((clip/resolver c :inner nil pal/index-of nil) 3))
|
||||||
"and it draws nothing")
|
"and it draws nothing")
|
||||||
(is (= c (clip/place-sound c :inner {:sound "tone"} "tone.mp3" 40 1 10 (random-uuid)))
|
(is (= c (clip/place-sound c :inner {:sound "tone"} "tone.mp3" 40 1 10 (random-uuid)))
|
||||||
"nor lands past the end of its symbol")
|
"nor lands past the end of its symbol")
|
||||||
|
|
|
||||||
|
|
@ -31,5 +31,5 @@
|
||||||
(is (empty? (channel/problems mixed)))
|
(is (empty? (channel/problems mixed)))
|
||||||
;; The demo's root is exposed on 2s. Paint at frame 3 must still appear at 3.
|
;; The demo's root is exposed on 2s. Paint at frame 3 must still appear at 3.
|
||||||
(is (some #(= :paint-test (:node %))
|
(is (some #(= :paint-test (:node %))
|
||||||
(symbol/eval-frame (get-in c2 [:symbols :main]) 3 nil pal/index-of nil nil)))
|
(symbol/eval-frame (get-in c2 [:symbols :main]) 3 nil pal/index-of nil)))
|
||||||
(is (= mixed-clip (leaf/clip :c1 (leaf/leaves :c1 mixed-clip))))))
|
(is (= mixed-clip (leaf/clip :c1 (leaf/leaves :c1 mixed-clip))))))
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@
|
||||||
;; frame rather than hidden, and its partner is not.
|
;; frame rather than hidden, and its partner is not.
|
||||||
(let [back (wired :c1 @gappy)
|
(let [back (wired :c1 @gappy)
|
||||||
drawn (into #{} (map :node)
|
drawn (into #{} (map :node)
|
||||||
((symbol/resolver (face-symbol (:clip back)) (:store back) pal/index-of nil nil) 12))]
|
((symbol/resolver (face-symbol (:clip back)) (:store back) pal/index-of nil) 12))]
|
||||||
(is (not (contains? drawn :eye-r)))
|
(is (not (contains? drawn :eye-r)))
|
||||||
(is (contains? drawn :eye-l))
|
(is (contains? drawn :eye-l))
|
||||||
(is (contains? drawn :mouth))))
|
(is (contains? drawn :mouth))))
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
{:nodes (into {} (map (juxt :id identity)) nodes)})
|
{:nodes (into {} (map (juxt :id identity)) nodes)})
|
||||||
|
|
||||||
(defn- ids-at [scene f]
|
(defn- ids-at [scene f]
|
||||||
(mapv :node (symbol/eval-frame scene f nil pal/index-of nil nil)))
|
(mapv :node (symbol/eval-frame scene f nil pal/index-of nil)))
|
||||||
|
|
||||||
(def ^:private pts-of ops/points)
|
(def ^:private pts-of ops/points)
|
||||||
|
|
||||||
|
|
@ -70,9 +70,9 @@
|
||||||
(is (identical? (get-in s [:nodes :b]) (get-in s' [:nodes :b]))
|
(is (identical? (get-in s [:nodes :b]) (get-in s' [:nodes :b]))
|
||||||
"and so is the new one")
|
"and so is the new one")
|
||||||
(is (= [[0 0] [10 0] [10 10]]
|
(is (= [[0 0] [10 0] [10 10]]
|
||||||
(pts-of (first (filter #(= :c (:node %)) (symbol/eval-frame s 0 nil pal/index-of nil nil))))))
|
(pts-of (first (filter #(= :c (:node %)) (symbol/eval-frame s 0 nil pal/index-of nil))))))
|
||||||
(is (= [[100 0] [110 0] [110 10]]
|
(is (= [[100 0] [110 0] [110 10]]
|
||||||
(pts-of (first (filter #(= :c (:node %)) (symbol/eval-frame s' 0 nil pal/index-of nil nil))))))))
|
(pts-of (first (filter #(= :c (:node %)) (symbol/eval-frame s' 0 nil pal/index-of nil))))))))
|
||||||
|
|
||||||
;; ---- draw order ----
|
;; ---- draw order ----
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
:channels {[:xform :pos] (ch/framed [100 50])
|
:channels {[:xform :pos] (ch/framed [100 50])
|
||||||
[:xform :scale] (ch/framed [2 2])}}
|
[:xform :scale] (ch/framed [2 2])}}
|
||||||
(poly :p :g "a1" [0 0 10 0 10 10 0 10] :skin-base))
|
(poly :p :g "a1" [0 0 10 0 10 10 0 10] :skin-base))
|
||||||
op (first (symbol/eval-frame s 0 nil pal/index-of nil nil))]
|
op (first (symbol/eval-frame s 0 nil pal/index-of nil))]
|
||||||
(is (= [[100 50] [120 50] [120 70] [100 70]] (pts-of op)))))
|
(is (= [[100 50] [120 50] [120 70] [100 70]] (pts-of op)))))
|
||||||
|
|
||||||
(deftest a-keyed-group-position-moves-its-children-and-holds-between-keys
|
(deftest a-keyed-group-position-moves-its-children-and-holds-between-keys
|
||||||
|
|
@ -139,7 +139,7 @@
|
||||||
:channels {[:xform :pos]
|
:channels {[:xform :pos]
|
||||||
(ch/keyed {0 [0 0], 4 [10 0], 8 [10 10], 12 [0 10]} :hold)}}
|
(ch/keyed {0 [0 0], 4 [10 0], 8 [10 10], 12 [0 10]} :hold)}}
|
||||||
(poly :p :g "a1" [0 0 2 0 2 2] :skin-base))
|
(poly :p :g "a1" [0 0 2 0 2 2] :skin-base))
|
||||||
at #(first (pts-of (first (symbol/eval-frame s % nil pal/index-of nil nil))))]
|
at #(first (pts-of (first (symbol/eval-frame s % nil pal/index-of nil))))]
|
||||||
(is (= [0 0] (at 0)))
|
(is (= [0 0] (at 0)))
|
||||||
(is (= [0 0] (at 3)) "held")
|
(is (= [0 0] (at 3)) "held")
|
||||||
(is (= [10 0] (at 4)))
|
(is (= [10 0] (at 4)))
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
{:id :g :kind :group :parent :root :z "a1"
|
{:id :g :kind :group :parent :root :z "a1"
|
||||||
:channels {[:xform :pos] (ch/keyed (into {} (map (juxt identity #(vector % 0))) (range 12)) :hold)}}
|
:channels {[:xform :pos] (ch/keyed (into {} (map (juxt identity #(vector % 0))) (range 12)) :hold)}}
|
||||||
(poly :p :g "a1" [0 0 1 0 1 1] :skin-base))
|
(poly :p :g "a1" [0 0 1 0 1 1] :skin-base))
|
||||||
x-at #(first (first (pts-of (first (symbol/eval-frame s % nil pal/index-of nil nil)))))]
|
x-at #(first (first (pts-of (first (symbol/eval-frame s % nil pal/index-of nil)))))]
|
||||||
(is (= [0 0 0 3 3 3 6 6 6 9 9 9] (mapv x-at (range 12)))))
|
(is (= [0 0 0 3 3 3 6 6 6 9 9 9] (mapv x-at (range 12)))))
|
||||||
|
|
||||||
(testing "and a node may set its own grid, which the model permits deliberately"
|
(testing "and a node may set its own grid, which the model permits deliberately"
|
||||||
|
|
@ -164,7 +164,7 @@
|
||||||
{:id :g :kind :group :parent :root :z "a1" :time {:mode :map :expose 4}
|
{:id :g :kind :group :parent :root :z "a1" :time {:mode :map :expose 4}
|
||||||
:channels {[:xform :pos] (ch/keyed (into {} (map (juxt identity #(vector % 0))) (range 12)) :hold)}}
|
:channels {[:xform :pos] (ch/keyed (into {} (map (juxt identity #(vector % 0))) (range 12)) :hold)}}
|
||||||
(poly :p :g "a1" [0 0 1 0 1 1] :skin-base))
|
(poly :p :g "a1" [0 0 1 0 1 1] :skin-base))
|
||||||
x-at #(first (first (pts-of (first (symbol/eval-frame s % nil pal/index-of nil nil)))))]
|
x-at #(first (first (pts-of (first (symbol/eval-frame s % nil pal/index-of nil)))))]
|
||||||
(is (= [0 0 0 0 4 4 4 4 8 8 8 8] (mapv x-at (range 12)))))))
|
(is (= [0 0 0 0 4 4 4 4 8 8 8 8] (mapv x-at (range 12)))))))
|
||||||
|
|
||||||
(deftest offset-is-per-node-which-is-the-entire-point-of-mouth-lead
|
(deftest offset-is-per-node-which-is-the-entire-point-of-mouth-lead
|
||||||
|
|
@ -178,7 +178,7 @@
|
||||||
{:id :mouth :kind :group :parent :root :z "a2" :time {:mode :map :offset 2}
|
{:id :mouth :kind :group :parent :root :z "a2" :time {:mode :map :offset 2}
|
||||||
:channels {[:xform :pos] (ch/keyed keys :hold)}}
|
:channels {[:xform :pos] (ch/keyed keys :hold)}}
|
||||||
(poly :mouth-p :mouth "a1" [0 0 1 0 1 1] :mouth-dark))
|
(poly :mouth-p :mouth "a1" [0 0 1 0 1 1] :mouth-dark))
|
||||||
x-of (fn [f id] (->> (symbol/eval-frame s f nil pal/index-of nil nil)
|
x-of (fn [f id] (->> (symbol/eval-frame s f nil pal/index-of nil)
|
||||||
(filter #(= id (:node %))) first pts-of first first))]
|
(filter #(= id (:node %))) first pts-of first first))]
|
||||||
(is (= [0 1 2 3] (mapv #(x-of % :plate-p) (range 4))))
|
(is (= [0 1 2 3] (mapv #(x-of % :plate-p) (range 4))))
|
||||||
(is (= [2 3 4 5] (mapv #(x-of % :mouth-p) (range 4))) "the mouth reads ahead")))
|
(is (= [2 3 4 5] (mapv #(x-of % :mouth-p) (range 4))) "the mouth reads ahead")))
|
||||||
|
|
@ -221,11 +221,11 @@
|
||||||
:dense {:store "pts" :offset 0 :stride 6 :frames 2}}
|
:dense {:store "pts" :offset 0 :stride 6 :frames 2}}
|
||||||
[:style :color] (ch/framed :mouth-dark)}}
|
[:style :color] (ch/framed :mouth-dark)}}
|
||||||
(poly :teeth :m "a2" [0 0 1 0 1 1] :teeth))]
|
(poly :teeth :m "a2" [0 0 1 0 1 1] :teeth))]
|
||||||
(is (= [:child] (mapv :node (symbol/eval-frame absent-pos 0 store pal/index-of nil nil))))
|
(is (= [:child] (mapv :node (symbol/eval-frame absent-pos 0 store pal/index-of nil))))
|
||||||
(is (= [] (mapv :node (symbol/eval-frame absent-pos 1 store pal/index-of nil nil)))
|
(is (= [] (mapv :node (symbol/eval-frame absent-pos 1 store pal/index-of nil)))
|
||||||
"an absent transform gives the children nowhere to be")
|
"an absent transform gives the children nowhere to be")
|
||||||
(is (= [:m :teeth] (mapv :node (symbol/eval-frame absent-pts 0 store pal/index-of nil nil))))
|
(is (= [:m :teeth] (mapv :node (symbol/eval-frame absent-pts 0 store pal/index-of nil))))
|
||||||
(is (= [:teeth] (mapv :node (symbol/eval-frame absent-pts 1 store pal/index-of nil nil)))
|
(is (= [:teeth] (mapv :node (symbol/eval-frame absent-pts 1 store pal/index-of nil)))
|
||||||
"an absent outline removes only itself")))
|
"an absent outline removes only itself")))
|
||||||
|
|
||||||
;; ---- stencils ----
|
;; ---- stencils ----
|
||||||
|
|
@ -239,7 +239,7 @@
|
||||||
{:id :iris :kind :disc :parent :root :stencil :sclera :z "a2"
|
{:id :iris :kind :disc :parent :root :stencil :sclera :z "a2"
|
||||||
:channels {[:geom :radius] (ch/framed 4)
|
:channels {[:geom :radius] (ch/framed 4)
|
||||||
[:style :color] (ch/framed :iris)}})
|
[:style :color] (ch/framed :iris)}})
|
||||||
ops (symbol/eval-frame s 0 nil pal/index-of nil nil)]
|
ops (symbol/eval-frame s 0 nil pal/index-of nil)]
|
||||||
(is (= [:sclera :iris] (mapv :node ops)))
|
(is (= [:sclera :iris] (mapv :node ops)))
|
||||||
(is (= (:eye-white pal/index-of) (:stencil (second ops))))))
|
(is (= (:eye-white pal/index-of) (:stencil (second ops))))))
|
||||||
|
|
||||||
|
|
@ -266,7 +266,7 @@
|
||||||
:channels {[:geom :radius] (ch/framed 3) [:style :color] (ch/framed :iris)}}
|
:channels {[:geom :radius] (ch/framed 3) [:style :color] (ch/framed :iris)}}
|
||||||
{:id :r :kind :rect :parent :g :z "a2"
|
{:id :r :kind :rect :parent :g :z "a2"
|
||||||
:channels {[:geom :size] (ch/framed 1.7) [:style :color] (ch/framed :pupil)}})
|
:channels {[:geom :size] (ch/framed 1.7) [:style :color] (ch/framed :pupil)}})
|
||||||
[d r] (symbol/eval-frame s 0 nil pal/index-of nil nil)]
|
[d r] (symbol/eval-frame s 0 nil pal/index-of nil)]
|
||||||
(is (= [50 60 6] [(:cx d) (:cy d) (:r d)]))
|
(is (= [50 60 6] [(:cx d) (:cy d) (:r d)]))
|
||||||
(is (= 3.4 (:size r)))))
|
(is (= 3.4 (:size r)))))
|
||||||
|
|
||||||
|
|
@ -291,7 +291,7 @@
|
||||||
(deftest the-resolver-reuses-one-buffer-per-node
|
(deftest the-resolver-reuses-one-buffer-per-node
|
||||||
;; At 30fps per-frame allocation is the only thing that will make this stutter,
|
;; At 30fps per-frame allocation is the only thing that will make this stutter,
|
||||||
;; and fixed topology is what makes the buffer size knowable at all.
|
;; and fixed topology is what makes the buffer size knowable at all.
|
||||||
(let [res (symbol/resolver demo/main nil pal/index-of nil nil)
|
(let [res (symbol/resolver demo/main nil pal/index-of nil)
|
||||||
buf-of (fn [f id] (->> (res f) (filter #(= id (:node %))) first :pts))]
|
buf-of (fn [f id] (->> (res f) (filter #(= id (:node %))) first :pts))]
|
||||||
(is (identical? (buf-of 0 :card) (buf-of 30 :card)))))
|
(is (identical? (buf-of 0 :card) (buf-of 30 :card)))))
|
||||||
|
|
||||||
|
|
@ -308,15 +308,15 @@
|
||||||
;; The mistake this split makes easy: both are maps with an :id, and the wrong
|
;; The mistake this split makes easy: both are maps with an :id, and the wrong
|
||||||
;; one resolves to no ops rather than to an error.
|
;; one resolves to no ops rather than to an error.
|
||||||
(is (thrown-with-msg? ExceptionInfo #"not a symbol"
|
(is (thrown-with-msg? ExceptionInfo #"not a symbol"
|
||||||
(symbol/resolver demo/clip nil pal/index-of nil nil)))
|
(symbol/resolver demo/clip nil pal/index-of nil)))
|
||||||
(is (thrown-with-msg? ExceptionInfo #"not a symbol"
|
(is (thrown-with-msg? ExceptionInfo #"not a symbol"
|
||||||
(symbol/eval-frame demo/clip 0 nil pal/index-of nil nil)))))
|
(symbol/eval-frame demo/clip 0 nil pal/index-of nil)))))
|
||||||
|
|
||||||
(deftest the-hand-written-clip-renders-and-moves
|
(deftest the-hand-written-clip-renders-and-moves
|
||||||
;; port-plan step 2's done condition, as an assertion rather than a look: the
|
;; port-plan step 2's done condition, as an assertion rather than a look: the
|
||||||
;; scene rasterises, it writes only palette indices, and the pixels are not the
|
;; scene rasterises, it writes only palette indices, and the pixels are not the
|
||||||
;; same on every frame.
|
;; same on every frame.
|
||||||
(let [res (symbol/resolver demo/main nil pal/index-of nil nil)
|
(let [res (symbol/resolver demo/main nil pal/index-of nil)
|
||||||
render (fn [f]
|
render (fn [f]
|
||||||
(let [r (raster/make (:width demo/clip) (:height demo/clip))]
|
(let [r (raster/make (:width demo/clip) (:height demo/clip))]
|
||||||
(raster/clear! r (:bg pal/index-of))
|
(raster/clear! r (:bg pal/index-of))
|
||||||
|
|
@ -334,7 +334,7 @@
|
||||||
;; Exposure 2 on the clip root, inherited, so odd frames are identical to the
|
;; Exposure 2 on the clip root, inherited, so odd frames are identical to the
|
||||||
;; even frame before them. If this fails, exposure is being applied somewhere
|
;; even frame before them. If this fails, exposure is being applied somewhere
|
||||||
;; other than the frame the channels are sampled at.
|
;; other than the frame the channels are sampled at.
|
||||||
(let [res (symbol/resolver demo/main nil pal/index-of nil nil)
|
(let [res (symbol/resolver demo/main nil pal/index-of nil)
|
||||||
render (fn [f]
|
render (fn [f]
|
||||||
(let [r (raster/make (:width demo/clip) (:height demo/clip))]
|
(let [r (raster/make (:width demo/clip) (:height demo/clip))]
|
||||||
(raster/clear! r (:bg pal/index-of))
|
(raster/clear! r (:bg pal/index-of))
|
||||||
|
|
@ -351,7 +351,7 @@
|
||||||
(deftest the-hand-written-clip-keeps-the-iris-and-pupil-inside-the-card
|
(deftest the-hand-written-clip-keeps-the-iris-and-pupil-inside-the-card
|
||||||
;; The stencil chain, on real pixels: the iris is clipped by the card and the
|
;; The stencil chain, on real pixels: the iris is clipped by the card and the
|
||||||
;; pupil by the iris, and neither is expressed anywhere as a chain.
|
;; pupil by the iris, and neither is expressed anywhere as a chain.
|
||||||
(let [res (symbol/resolver demo/main nil pal/index-of nil nil)]
|
(let [res (symbol/resolver demo/main nil pal/index-of nil)]
|
||||||
(doseq [f (range 0 demo/frames 4)]
|
(doseq [f (range 0 demo/frames 4)]
|
||||||
(let [before (raster/make (:width demo/clip) (:height demo/clip))
|
(let [before (raster/make (:width demo/clip) (:height demo/clip))
|
||||||
after (raster/make (:width demo/clip) (:height demo/clip))
|
after (raster/make (:width demo/clip) (:height demo/clip))
|
||||||
|
|
@ -384,9 +384,9 @@
|
||||||
(poly :p :root "a1" [0 0 10 0 10 10] :skin-base))
|
(poly :p :root "a1" [0 0 10 0 10 10] :skin-base))
|
||||||
day {:skin-base 1}
|
day {:skin-base 1}
|
||||||
night {:skin-base 17}]
|
night {:skin-base 17}]
|
||||||
(is (= 1 (:color (first (symbol/eval-frame s 0 nil day nil nil)))))
|
(is (= 1 (:color (first (symbol/eval-frame s 0 nil day nil)))))
|
||||||
(is (= 17 (:color (first (symbol/eval-frame s 0 nil night nil nil)))))
|
(is (= 17 (:color (first (symbol/eval-frame s 0 nil night nil)))))
|
||||||
(is (= 17 (:color (first ((symbol/resolver s nil night nil nil) 0))))
|
(is (= 17 (:color (first ((symbol/resolver s nil night nil) 0))))
|
||||||
"and the playback path agrees")))
|
"and the playback path agrees")))
|
||||||
|
|
||||||
(deftest a-tone-the-ramp-does-not-define-is-loudly-wrong
|
(deftest a-tone-the-ramp-does-not-define-is-loudly-wrong
|
||||||
|
|
@ -394,7 +394,7 @@
|
||||||
;; authored data and should be impossible to miss.
|
;; authored data and should be impossible to miss.
|
||||||
(let [s (sc {:id :root :kind :group :z "a1"}
|
(let [s (sc {:id :root :kind :group :z "a1"}
|
||||||
(poly :p :root "a1" [0 0 10 0 10 10] :skin-base))]
|
(poly :p :root "a1" [0 0 10 0 10 10] :skin-base))]
|
||||||
(is (= 255 (:color (first (symbol/eval-frame s 0 nil {} nil nil)))))))
|
(is (= 255 (:color (first (symbol/eval-frame s 0 nil {} nil)))))))
|
||||||
|
|
||||||
(deftest partitioning-the-index-space-stops-two-palettes-colliding-on-a-stencil
|
(deftest partitioning-the-index-space-stops-two-palettes-colliding-on-a-stencil
|
||||||
;; A stencil is a colour key, so two nodes sharing a tone share a stencil —
|
;; A stencil is a colour key, so two nodes sharing a tone share a stencil —
|
||||||
|
|
@ -407,6 +407,6 @@
|
||||||
[:style :color] (ch/framed :iris)}})
|
[:style :color] (ch/framed :iris)}})
|
||||||
;; :night's tones sit above :day's in one concatenated space
|
;; :night's tones sit above :day's in one concatenated space
|
||||||
night {:eye-white 14 :iris 15}
|
night {:eye-white 14 :iris 15}
|
||||||
ops (symbol/eval-frame s 0 nil night nil nil)]
|
ops (symbol/eval-frame s 0 nil night nil)]
|
||||||
(is (= 14 (:stencil (second ops)))
|
(is (= 14 (:stencil (second ops)))
|
||||||
"the stencil resolves to the index the stencil node actually drew in")))
|
"the stencil resolves to the index the stencil node actually drew in")))
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
(defn- photo-at
|
(defn- photo-at
|
||||||
"The photo matrix of face-1 alone at frame `f`, the still being 1000px tall."
|
"The photo matrix of face-1 alone at frame `f`, the still being 1000px tall."
|
||||||
[c f]
|
[c f]
|
||||||
(let [r (symbol/resolver (clip/symbol c :face-1) @store pal/index-of nil nil)
|
(let [r (symbol/resolver (clip/symbol c :face-1) @store pal/index-of nil)
|
||||||
h (head c)]
|
h (head c)]
|
||||||
(r f)
|
(r f)
|
||||||
(vec (array-seq (trace/photo-matrix (symbol/world-of r :head) h @store
|
(vec (array-seq (trace/photo-matrix (symbol/world-of r :head) h @store
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
;; The same answer as `nest/placement`, which walks and resolves the path all
|
;; The same answer as `nest/placement`, which walks and resolves the path all
|
||||||
;; over again — the resolver has it already, from drawing the frame.
|
;; over again — the resolver has it already, from drawing the frame.
|
||||||
(let [c (wrapped)
|
(let [c (wrapped)
|
||||||
r (clip/resolver c @store pal/index-of :wrap nil)
|
r (clip/resolver c :wrap @store pal/index-of nil)
|
||||||
path [:m :face-1 :head]]
|
path [:m :face-1 :head]]
|
||||||
(doseq [f [0 17 60]]
|
(doseq [f [0 17 60]]
|
||||||
(r f)
|
(r f)
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
(is (not (ch/nothing? (sample :eye-l f))))
|
(is (not (ch/nothing? (sample :eye-l f))))
|
||||||
(is (not (ch/nothing? (sample :mouth f)))))
|
(is (not (ch/nothing? (sample :mouth f)))))
|
||||||
(let [drawn (into #{} (map :node)
|
(let [drawn (into #{} (map :node)
|
||||||
((symbol/resolver (clip/symbol clip :face-1) store pal/index-of nil nil) 11))]
|
((symbol/resolver (clip/symbol clip :face-1) store pal/index-of nil) 11))]
|
||||||
(is (not (contains? drawn :eye-r)))
|
(is (not (contains? drawn :eye-r)))
|
||||||
(is (not (contains? drawn :iris-r)))
|
(is (not (contains? drawn :iris-r)))
|
||||||
(is (contains? drawn :eye-l))
|
(is (contains? drawn :eye-l))
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
(defn- ops-at
|
(defn- ops-at
|
||||||
"Ops for one frame of a TIMELINE."
|
"Ops for one frame of a TIMELINE."
|
||||||
[sym f]
|
[sym f]
|
||||||
((symbol/resolver sym @store pal/index-of nil nil) f))
|
((symbol/resolver sym @store pal/index-of nil) f))
|
||||||
|
|
||||||
(defn- render
|
(defn- render
|
||||||
"One frame of a CLIP into a byte buffer. The stage's size comes off the clip and
|
"One frame of a CLIP into a byte buffer. The stage's size comes off the clip and
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
[c f]
|
[c f]
|
||||||
(let [r (raster/make (:width c) (:height c))]
|
(let [r (raster/make (:width c) (:height c))]
|
||||||
(raster/clear! r (get pal/index-of :bg))
|
(raster/clear! r (get pal/index-of :bg))
|
||||||
(raster/draw-ops! r ((clip/resolver c @store pal/index-of :main nil) f))
|
(raster/draw-ops! r ((clip/resolver c :main @store pal/index-of nil) f))
|
||||||
(vec (array-seq (:buf r)))))
|
(vec (array-seq (:buf r)))))
|
||||||
|
|
||||||
(defn- drawn
|
(defn- drawn
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
;; checking arithmetic against itself; this checks `node/local!`, `node/world!`
|
;; checking arithmetic against itself; this checks `node/local!`, `node/world!`
|
||||||
;; and `emit` as well.
|
;; and `emit` as well.
|
||||||
(let [c (freeze/head-mode {} @frozen)
|
(let [c (freeze/head-mode {} @frozen)
|
||||||
res (clip/resolver c @store pal/index-of :main nil)
|
res (clip/resolver c :main @store pal/index-of nil)
|
||||||
k (first (:value (chan :face [:xform :scale])))
|
k (first (:value (chan :face [:xform :scale])))
|
||||||
anc (:value (chan :face [:xform :anchor]))
|
anc (:value (chan :face [:xform :anchor]))
|
||||||
pos (:value (chan :face [:xform :pos]))
|
pos (:value (chan :face [:xform :pos]))
|
||||||
|
|
@ -249,14 +249,11 @@
|
||||||
"the trace survives the document round trip")))
|
"the trace survives the document round trip")))
|
||||||
|
|
||||||
(deftest trace-keys-hold-the-whole-measured-transform
|
(deftest trace-keys-hold-the-whole-measured-transform
|
||||||
(let [free (symbol/resolver (face-symbol (freeze/head-mode {} @frozen))
|
(let [free (symbol/resolver (face-symbol (freeze/head-mode {} @frozen)) @store pal/index-of nil)
|
||||||
@store pal/index-of nil nil)
|
|
||||||
held (symbol/resolver (face-symbol
|
held (symbol/resolver (face-symbol
|
||||||
(freeze/head-mode {:trace {:origin :keys :frames [12 88]}} @frozen))
|
(freeze/head-mode {:trace {:origin :keys :frames [12 88]}} @frozen)) @store pal/index-of nil)
|
||||||
@store pal/index-of nil nil)
|
|
||||||
start (symbol/resolver (face-symbol
|
start (symbol/resolver (face-symbol
|
||||||
(freeze/head-mode {:trace {:origin :start :frames [12 88]}} @frozen))
|
(freeze/head-mode {:trace {:origin :start :frames [12 88]}} @frozen)) @store pal/index-of nil)
|
||||||
@store pal/index-of nil nil)
|
|
||||||
world (fn [resolver frame]
|
world (fn [resolver frame]
|
||||||
(resolver frame)
|
(resolver frame)
|
||||||
(vec (array-seq (symbol/world-of resolver :head))))]
|
(vec (array-seq (symbol/world-of resolver :head))))]
|
||||||
|
|
@ -511,7 +508,7 @@
|
||||||
(is (not (ch/nothing? (at :eye-r 60))))
|
(is (not (ch/nothing? (at :eye-r 60))))
|
||||||
(is (not (ch/nothing? (at :eye-l 50))))
|
(is (not (ch/nothing? (at :eye-l 50))))
|
||||||
(is (not (ch/nothing? (at :mouth 50))))
|
(is (not (ch/nothing? (at :mouth 50))))
|
||||||
(let [drawn-nodes (into #{} (map :node) ((symbol/resolver sym (:store c) pal/index-of nil nil) 50))]
|
(let [drawn-nodes (into #{} (map :node) ((symbol/resolver sym (:store c) pal/index-of nil) 50))]
|
||||||
(is (not (contains? drawn-nodes :eye-r)))
|
(is (not (contains? drawn-nodes :eye-r)))
|
||||||
(is (contains? drawn-nodes :eye-l))
|
(is (contains? drawn-nodes :eye-l))
|
||||||
(is (contains? drawn-nodes :mouth)))
|
(is (contains? drawn-nodes :mouth)))
|
||||||
|
|
@ -586,7 +583,7 @@
|
||||||
;; Hoisted: the resolver caches its order and reuses its buffers, so the
|
;; Hoisted: the resolver caches its order and reuses its buffers, so the
|
||||||
;; node ids come out before the next frame is asked for.
|
;; node ids come out before the next frame is asked for.
|
||||||
nodes-at (fn [c]
|
nodes-at (fn [c]
|
||||||
(let [r (symbol/resolver (face-symbol (:clip c)) (:store c) pal/index-of nil nil)]
|
(let [r (symbol/resolver (face-symbol (:clip c)) (:store c) pal/index-of nil)]
|
||||||
(fn [f] (into #{} (map :node) (r f)))))
|
(fn [f] (into #{} (map :node) (r f)))))
|
||||||
ref-at (nodes-at ref)
|
ref-at (nodes-at ref)
|
||||||
occ-at (nodes-at occ)
|
occ-at (nodes-at occ)
|
||||||
|
|
@ -623,7 +620,7 @@
|
||||||
c (freeze/clip (assoc take/params :name "gappy")
|
c (freeze/clip (assoc take/params :name "gappy")
|
||||||
{:face-1 (assoc @take/measured :detected det)})
|
{:face-1 (assoc @take/measured :detected det)})
|
||||||
sym (face-symbol (:clip c))
|
sym (face-symbol (:clip c))
|
||||||
res (symbol/resolver sym (:store c) pal/index-of nil nil)]
|
res (symbol/resolver sym (:store c) pal/index-of nil)]
|
||||||
(doseq [f [39 40 50 59 60]]
|
(doseq [f [39 40 50 59 60]]
|
||||||
(let [ops (res f)]
|
(let [ops (res f)]
|
||||||
(if (contains? gap f)
|
(if (contains? gap f)
|
||||||
|
|
@ -682,7 +679,7 @@
|
||||||
shot (fn [f]
|
shot (fn [f]
|
||||||
(let [r (raster/make W H)
|
(let [r (raster/make W H)
|
||||||
mouth (filter #(= [:face-1 :mouth] (:node %))
|
mouth (filter #(= [:face-1 :mouth] (:node %))
|
||||||
((clip/resolver locked @store pal/index-of :main nil) f))]
|
((clip/resolver locked :main @store pal/index-of nil) f))]
|
||||||
(raster/clear! r (get pal/index-of :bg))
|
(raster/clear! r (get pal/index-of :bg))
|
||||||
(raster/draw-ops! r mouth)
|
(raster/draw-ops! r mouth)
|
||||||
(vec (array-seq (:buf r)))))
|
(vec (array-seq (:buf r)))))
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
(defn channel [entry subject node path]
|
(defn channel [entry subject node path]
|
||||||
(get-in entry [:clip :symbols subject :nodes node :channels path]))
|
(get-in entry [:clip :symbols subject :nodes node :channels path]))
|
||||||
(defn snapshot [c store f] (ops/snapshot ((clip/resolver c store pal/index-of :main nil) f)))
|
(defn snapshot [c store f] (ops/snapshot ((clip/resolver c :main store pal/index-of nil) f)))
|
||||||
(defn by-node [c store f] (into {} (map (juxt :node identity)) (snapshot c store f)))
|
(defn by-node [c store f] (into {} (map (juxt :node identity)) (snapshot c store f)))
|
||||||
|
|
||||||
(deftest subjects-share-local-names-without-sharing-blocks
|
(deftest subjects-share-local-names-without-sharing-blocks
|
||||||
|
|
@ -178,8 +178,8 @@
|
||||||
(merge (dissoc (:nodes (clip/symbol clip :main)) :face-1)
|
(merge (dissoc (:nodes (clip/symbol clip :main)) :face-1)
|
||||||
(assoc-in (get-in clip [:symbols :face-1 :nodes])
|
(assoc-in (get-in clip [:symbols :face-1 :nodes])
|
||||||
[:head :parent] :face)))
|
[:head :parent] :face)))
|
||||||
nested (clip/resolver clip store pal/index-of :main nil)
|
nested (clip/resolver clip :main store pal/index-of nil)
|
||||||
reference (clip/resolver flat store pal/index-of :main nil)]
|
reference (clip/resolver flat :main store pal/index-of nil)]
|
||||||
(doseq [f [0 1 7 20 39]]
|
(doseq [f [0 1 7 20 39]]
|
||||||
(let [a (ops/snapshot (nested f)) b (ops/snapshot (reference f))]
|
(let [a (ops/snapshot (nested f)) b (ops/snapshot (reference f))]
|
||||||
(is (= (mapv (comp second :node) a) (mapv :node b)))
|
(is (= (mapv (comp second :node) a) (mapv :node b)))
|
||||||
|
|
|
||||||
|
|
@ -52,11 +52,11 @@
|
||||||
"(fn [f] -> snapshot) through `eval-frame`, the specification."
|
"(fn [f] -> snapshot) through `eval-frame`, the specification."
|
||||||
([sym store] (specified sym store pal/index-of))
|
([sym store] (specified sym store pal/index-of))
|
||||||
([sym store palette]
|
([sym store palette]
|
||||||
(fn [f] (snapshot (symbol/eval-frame sym f store palette nil nil)))))
|
(fn [f] (snapshot (symbol/eval-frame sym f store palette nil)))))
|
||||||
|
|
||||||
(defn resolved
|
(defn resolved
|
||||||
"(fn [f] -> snapshot) through `resolver`, the playback path."
|
"(fn [f] -> snapshot) through `resolver`, the playback path."
|
||||||
([sym store] (resolved sym store pal/index-of))
|
([sym store] (resolved sym store pal/index-of))
|
||||||
([sym store palette]
|
([sym store palette]
|
||||||
(let [res (symbol/resolver sym store palette nil nil)]
|
(let [res (symbol/resolver sym store palette nil)]
|
||||||
(fn [f] (snapshot (res f))))))
|
(fn [f] (snapshot (res f))))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue