Skip to main content

Entities

The whole document is one plain struct, vv_core::Project (model.rs). There is no node graph: every clip carries a fixed EffectStack. The project is owned by a vv_session::Session together with its undo History; every change goes through a command (see Commands, Undo/Redo).

Entity diagram

ch2-entities.png

Clip sources

ClipSourceContent
Media(MediaId)A file of the media pool, or a compound clip (a pool item pointing at a timeline).
SolidColorColour from EffectStack::color.
TextTitle from EffectStack::title.
AdjustmentNo content: its effects apply to the composite of the tracks below.

Time on a clip

FieldMeaning
timeline_start, timeline_lenPosition on the timeline, in timeline frames.
source_offsetStart in the media, also in timeline frames: a conformed clip can start mid source frame.
rate, speedPrivate. rate = timeline frames per source frame (fps conform ÷ speed); written only through conform / set_speed so the two never drift.
source_frame_at()The single timeline → source mapping, shared by preview and export.

Invariants

RuleWhy
Track::clips is sorted by timeline_start and never overlaps.At most one clip per track covers a frame; lookups and compositing rely on it.
Track order is compositing order, bottom → top.V1/A1 labels are derived per kind (track_label), never stored.
Each timeline has its own fps and resolution.Clips from other rates are conformed through Clip::rate.
A CrossTransition stores only the two clip ids.Its window is recomputed from the clips' current edges; commands that split, delete or move a clip to another track must call take_crossings_for.
A linked group has no entity.Membership is Clip::linked_group; selection, drag and delete treat the group as a unit.

Compound clips

A timeline is used inside another through a pool MediaItem whose compound is Some(TimelineId). Its meta is recomputed from the nested timeline (sync_compound_meta) and its content_hash is bumped on every change, which invalidates cached composited frames without comparing timelines. would_create_a_cycle forbids nesting a timeline inside itself; MAX_COMPOUND_DEPTH (16) is only a safety net.