AnimationTimeline¶
Qualified name: algan.animation\_timeline.timeline.AnimationTimeline
- class AnimationTimeline[source]¶
Bases:
objectMethods
add_mob_attrTrace Mob state read or written by
eventuntil restored.Capture attribute writes made by one updater during replay.
Save one replayed write when its updater is being finalized.
clear_buffersOpt
attr_nameinto segment-window description.end_updaterend_updater_dependency_traceend_updater_write_captureget_attrget_indsThe
Lifespanof the mob with the given id, created on first access (start = end = "never").get_timeline_indsWhether frames are currently being materialized from the timeline.
modify_attributemodify_attribute_and_recordWarn if
parent's children just changed underneath a live updater.Mark
mob_idas a Mob that a replayed updater has just built.Rows a read must use while replaying one function.
Render frames without leaving derived state on the timeline.
record_functionRegister an updater starting at the context's current time and lasting until
end_updater()(or forever).register_despawnRegister an edit created by a historical-topology migration.
register_spawnTeach persistent updaters about rows handed to historical clones.
Drop the materialized windows of the wide attributes.
Return the next recorded row set while replaying one function.
The current batch's
SegmentWindowfor one mob's rows ofattr_name, or None when the window was materialized densely.Set the function application that subsequently recorded attribute edits are attributed to, returning the previous one (so callers can restore it).
Materialize animated state at
times.Record one updater Mob access and materialize newly seen rows.
- begin_updater_dependency_trace(event)[source]¶
Trace Mob state read or written by
eventuntil restored.
- begin_updater_write_capture(event)[source]¶
Capture attribute writes made by one updater during replay.
- capture_updater_write(attr_name, indexes, value)[source]¶
Save one replayed write when its updater is being finalized.
- enable_segment_windows(attr_name)[source]¶
Opt
attr_nameinto segment-window description.Called by the attribute’s owner (
Surface.color_texture’s setter) because eligibility is a property of how the attribute is consumed: the primitive build must know how to sample endpoint states, which only the texture path does. Idempotent.
- get_lifespan(mob_id)[source]¶
The
Lifespanof the mob with the given id, created on first access (start = end = “never”).
- is_replaying()[source]¶
Whether frames are currently being materialized from the timeline.
True inside
set_state_to_times(), which re-executes recorded animations and updaters to rebuild the state of a batch of frames. Authoring is over by then, so anything an updater does here must not change the Scene: see_discard_replay_born_mobs().- Return type:
bool
- note_hierarchy_change(parent)[source]¶
Warn if
parent’s children just changed underneath a live updater.A recorded animation stores the rows it resolved (
modify_attribute_and_record()), and replay hands them straight back (replay_inds()), so re-parenting after the fact cannot touch it. The updater loop inset_state_to_times()sets no replay event, so every write inside an updater re-resolves its rows from the hierarchy as it stands when the frames are materialized – which is the hierarchy at the end of the script, not the one in force at the frame being drawn. Editing a subtree a live updater addresses therefore rewrites frames that updater already covered, including frames before the edit.Nothing here changes what is rendered. It says so at the line that did it, while the script is still being authored and the fix is one move of an
add_updater/remove_updaterpair.
- peek_replay_inds(attr_name, mob_id, include_descendants)[source]¶
Rows a read must use while replaying one function.
A replayed function has to read the same rows it will write, or the value it computes is indexed differently from the buffer slots it lands in.
replay_inds()only answers for the edit at the cursor, which is right for writes – they consume the recorded edits in order – but wrong for reads, because a function need not read its attributes in the order it writes them._apply_basis_change()reads the recursivebasisbefore writing the recursivelocation, so an at-the-cursor match misses and the read silently falls back to the current hierarchy’s rows.That fallback is only harmless while the two agree. They stop agreeing as soon as anything reallocates a descendant’s rows after the function was recorded –
detach_history(and so everywave_color()auto-resolution restore) hands the old rows to a clone and appends fresh ones at the end of the buffer, which reorders the sorted descendant union. The read then returns some other Mob’s values, and the write scatters them across unrelated rows.So search forward from the cursor for the edit this read pairs with, without consuming it. Returns
Nonewhen the function records no matching write, in which case the caller’s live-topology rows are the correct answer.
- preserving_authoring_state(preserve_replay_resolution=True)[source]¶
Render frames without leaving derived state on the timeline.
Materializing frames resolves replay windows (
_resolve_replay_windows()), which freezes every edit’s and event’s context-rescaled end time into a plainreplay_endfloat. That is correct once authoring is finished, but a render started from inside an unfinished context bakes in timestamps the enclosing contexts have not rescaled yet (aruntimerescales its block retroactively, on exit). Nothing invalidates those floats afterwards – only recording a new edit does – so the stale, too-early ends survive into the next render, whereAttributeTimeline.prepare_for_queries()uses them verbatim as edit timestamps and the affected animations stop advancing early.Every render that leaves the Scene re-renderable wraps itself in this:
save_frame(),show_frame(), andsave_video()withreset=False. The frames come out of the timeline as it stands, and the Scene carries nothing away from the render, so authoring can continue and render again – including from inside a block that has not finished yet. Lifespans created for the transient mobs a render builds are dropped for the same reason.
- record_updater(function, caller, args, kwargs, animation_context)[source]¶
Register an updater starting at the context’s current time and lasting until
end_updater()(or forever). Returns its id.
- register_migrated_edit(attr_name, attr_timeline, source_edit, migrated_edit)[source]¶
Register an edit created by a historical-topology migration.
Surface resolution changes can split an already-recorded edit and add a replacement carrying the same execution sequence. That is the only path that inserts into (rather than appends to) global edit order, so it marks the order dirty and invalidates a resolved checkpoint only when the changed source lies inside that checkpoint.
- register_updater_history_split(descendant_map)[source]¶
Teach persistent updaters about rows handed to historical clones.
- release_wide_windows()[source]¶
Drop the materialized windows of the wide attributes.
A window materialized on the render device (see
_wide_attr_materialize_device()) is a whole image per frame of the batch, and nothing reads it once the batch’s primitives are built: the primitive holds its own copy (the legacy premultiply’s clone, or under texture_opacity_in_kernel a one-frame clone of a collapsed window – an UNCOLLAPSED window is deliberately aliased there, so for an animating texture this release only drops the timeline’s reference and the memory follows the primitive’s lifetime instead), the merge decodes that into the buffer the arena is filled from, and the next batch’s preparation replaces the window outright. Left in place it would sit beside the next batch’s window while this one renders – two batches of texture frames on the device for one batch of pixels. The narrow attributes are untouched: their windows are small, and the render thread still reads camera and light state from them.
- replay_inds(attr_name, mob_id, include_descendants, consume=False)[source]¶
Return the next recorded row set while replaying one function.
- segment_window_for(attr_name, mob_id)[source]¶
The current batch’s
SegmentWindowfor one mob’s rows ofattr_name, or None when the window was materialized densely. Valid between oneset_state_to_times()and the next.
- set_active_edit_event(event)[source]¶
Set the function application that subsequently recorded attribute edits are attributed to, returning the previous one (so callers can restore it).
- set_state_to_times(times, active_mobs=None)[source]¶
Materialize animated state at
times.active_mobsis the render window’s conservative actor working set. When supplied, built-in animations query only rows reachable from that set while keeping the full global-row buffer layout used by replay. Omitting it preserves the original all-row behavior for public callers.Replay runs inside a non-recording context, because it calls each recorded function’s undecorated body: the
record_funcs=Falsewrap thatanimated_functionnormally applies is absent, so a recorded function whose body calls another animated function (Cylinder.set_start_point->_move_between_points->move_to) would record a new event on every replay – growing the timeline without bound as batches are prepared, and re-resolving replay windows every time. A render never saw this because its batch loop runs inside the same context (_batch_prep_context()); doing it here means every caller is safe, including the benchmarks and probes that drive prep directly.The context matches the render’s exactly, so entering it inside a render is inert – the values are already set and inherited.
- trace_updater_mob_access(mob, include_descendants=False)[source]¶
Record one updater Mob access and materialize newly seen rows.
The initial updater invocation records the common dependency set at authoring time. The same trace remains active during materialization, so time-dependent branches can safely discover extra Mobs on demand.