Symbols, not timelines; no symbol is special
Everything that holds nodes is a symbol (domain/timeline -> domain/symbol, :timelines -> :symbols) and a node that places one is :kind :instance. The reserved :main root is gone: which symbol is on screen is editor state ([:ui :open]), every domain function that needs a symbol is told which, and a document opens on the longest symbol nothing else places. Saved projects move to schema 2 through migration 0007, which rewrites leaf paths, instance kinds and the feature :symbol key; the client refuses a schema it does not read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
179770d7d4
commit
5dff490162
61 changed files with 1587 additions and 1431 deletions
|
|
@ -116,8 +116,14 @@ projects the server holds; the built-in scenes are under their own heading,
|
|||
italic, and are not projects — they are compiled into the bundle and the server
|
||||
has never heard of them.
|
||||
|
||||
Selection lives in app-db under `:ui`, as `[:node <timeline> <node>]`,
|
||||
`[:timeline <id>]` or `[:subject|:feature|:group <id>]` — four panes ask what is
|
||||
Everything that holds nodes is a **symbol**, and none is special: a new document
|
||||
has one called `main` because it has to be called something. Which symbol is on
|
||||
screen is editor state, `[:ui :open]`, not a fact about the document — the stage
|
||||
draws it, the timeline lists it, the transport plays it and a new shape goes into
|
||||
it. A document opens on the longest symbol nothing else places.
|
||||
|
||||
Selection lives in app-db under `:ui`, as `[:node <symbol> <node>]`,
|
||||
`[:symbol <id>]` or `[:subject|:feature|:group <id>]` — four panes ask what is
|
||||
selected, and a ratom private to one of them can only be shared by making the
|
||||
other three require it.
|
||||
|
||||
|
|
@ -125,12 +131,12 @@ other three require it.
|
|||
into detection. Dragging a symbol out of the pool onto the stage places an
|
||||
instance of it at the playhead.
|
||||
|
||||
The timeline's rows are the open clip's nodes, front-most first, with a dot per
|
||||
The timeline's rows are the open symbol's nodes, front-most first, with a dot per
|
||||
keyframe and a bar over the frames the node exists on; a dense channel is hatched
|
||||
rather than ticked, because one value per frame is a solid block that says less
|
||||
than the bar does. Opening a row shows its channels; opening a **symbol** row
|
||||
shows the timeline it instances, with every frame number mapped back into the
|
||||
stage's own frame space — see the namespace docstring in `ui/timeline.cljs`, which
|
||||
than the bar does. Opening a row shows its channels; opening an **instance** row
|
||||
shows the symbol it places, with every frame number mapped back into the open
|
||||
symbol's frame space — see the namespace docstring in `ui/timeline.cljs`, which
|
||||
is where that mapping is argued.
|
||||
|
||||
### Paint sketch
|
||||
|
|
@ -168,9 +174,9 @@ and real footage use `src/arthur/flow/take.cljs` for the measurement order and
|
|||
`src/arthur/flow/freeze.cljs` for the landmark-to-channel conversion.
|
||||
|
||||
**8625 stage study**, in the open menu, loads the locally saved `IMG_8625.MOV` project and places its
|
||||
post-processed timeline twice. The stage layout is
|
||||
post-processed face symbol twice. The stage layout is
|
||||
`src/arthur/demo/stage_8625.edn`: the right picture and sound start at frame 48,
|
||||
and the two pictures overlap slightly in stage space. Audio has its own timeline
|
||||
and the two pictures overlap slightly in stage space. Audio has its own
|
||||
nodes, linked to the picture instances but with independent spans and gain
|
||||
channels. The right sound swells and pans across the stage, then fades out at
|
||||
frame 260 while its picture continues to
|
||||
|
|
@ -357,12 +363,12 @@ them is `clips/templates/clips/index.html`.
|
|||
|
||||
## Two evaluators, on purpose
|
||||
|
||||
`domain/timeline` has both `eval-frame` and `resolver`, and they are not
|
||||
`domain/symbol` has both `eval-frame` and `resolver`, and they are not
|
||||
alternatives:
|
||||
|
||||
- **`(eval-frame timeline f store)`** is the specification. Allocating, order-free,
|
||||
- **`(eval-frame symbol f store)`** is the specification. Allocating, order-free,
|
||||
obviously correct. Tests and one-off renders use it.
|
||||
- **`(resolver timeline store)` -> `(fn [f] ops)`** is what playback uses. It caches
|
||||
- **`(resolver symbol store)` -> `(fn [f] ops)`** is what playback uses. It caches
|
||||
the topological order and the z paths, holds a cursor per channel and reuses
|
||||
one point buffer per node, so a frame allocates the op maps and nothing else.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue