///|
/// Unified evaluation context shared by render, audio, and event consumers.
pub struct EvaluationContext2 {
time : Double
frame : Int
normalized : Double
delta : Double
direction : Int
} derive(Debug)
///|
pub fn evaluation_context2(
time : Double,
frame : Int,
normalized : Double,
delta : Double,
direction : Int,
) -> EvaluationContext2 {
{
time,
frame,
normalized: clamp01(normalized),
delta: delta.max(0.0),
direction: if direction < 0 {
-1
} else {
1
},
}
}
///|
pub fn EvaluationContext2::time(self : EvaluationContext2) -> Double {
self.time
}
///|
pub fn EvaluationContext2::frame(self : EvaluationContext2) -> Int {
self.frame
}
///|
pub fn EvaluationContext2::normalized(self : EvaluationContext2) -> Double {
self.normalized
}
///|
pub fn EvaluationContext2::delta(self : EvaluationContext2) -> Double {
self.delta
}
///|
pub fn EvaluationContext2::direction(self : EvaluationContext2) -> Int {
self.direction
}
///|
pub struct TimelineEvaluation2 {
context : EvaluationContext2
active_nodes : Array[TimelineGraphNode]
render_frame : RenderFrame2
events : Array[MotionEvent2]
} derive(Debug)
///|
pub fn TimelineEvaluation2::context(
self : TimelineEvaluation2,
) -> EvaluationContext2 {
self.context
}
///|
pub fn TimelineEvaluation2::active_nodes(
self : TimelineEvaluation2,
) -> Array[TimelineGraphNode] {
self.active_nodes.copy()
}
///|
pub fn TimelineEvaluation2::render_frame(
self : TimelineEvaluation2,
) -> RenderFrame2 {
self.render_frame
}
///|
pub fn TimelineEvaluation2::events(
self : TimelineEvaluation2,
) -> Array[MotionEvent2] {
self.events.copy()
}
///|
pub struct TimelineEvaluator2 {
graph : TimelineGraph
render_plan : RenderPlan2
event_queue : MotionEventQueue2
mut previous_time : Double
} derive(Debug)
///|
pub fn timeline_evaluator2(
graph : TimelineGraph,
render_plan : RenderPlan2,
) -> TimelineEvaluator2 {
{ graph, render_plan, event_queue: motion_event_queue2(), previous_time: 0.0 }
}
///|
pub fn TimelineEvaluator2::graph(self : TimelineEvaluator2) -> TimelineGraph {
self.graph
}
///|
pub fn TimelineEvaluator2::render_plan(
self : TimelineEvaluator2,
) -> RenderPlan2 {
self.render_plan
}
///|
pub fn TimelineEvaluator2::queue(
self : TimelineEvaluator2,
) -> MotionEventQueue2 {
self.event_queue
}
///|
pub fn TimelineEvaluator2::add_event(
self : TimelineEvaluator2,
event : MotionEvent2,
) -> Unit {
self.event_queue.push(event)
}
///|
pub fn TimelineEvaluator2::seek(
self : TimelineEvaluator2,
time : Double,
) -> Unit {
self.previous_time = time
self.event_queue.reset(time)
}
///|
pub fn TimelineEvaluator2::evaluate(
self : TimelineEvaluator2,
time : Double,
frame : Int,
) -> TimelineEvaluation2 {
let delta = (time - self.previous_time).abs()
let range = self.graph.time_range()
let normalized = if range.1 == range.0 {
0.0
} else {
(time - range.0) / (range.1 - range.0)
}
let direction = if time >= self.previous_time { 1 } else { -1 }
let context = evaluation_context2(time, frame, normalized, delta, direction)
let active_nodes = self.graph.active_at(time)
let render_frame = self.render_plan.frame(time)
let events = if direction > 0 {
self.event_queue.poll_until(time)
} else {
self.event_queue.poll_window(time, self.previous_time)
}
self.previous_time = time
{ context, active_nodes, render_frame, events }
}
///|
pub fn TimelineEvaluator2::evaluate_schedule(
self : TimelineEvaluator2,
schedule : FrameSchedule2,
) -> Array[TimelineEvaluation2] {
let result : Array[TimelineEvaluation2] = []
for index in 0.. Int {
self.graph.active_at(time).length()
}
///|
pub struct EvaluationStats2 {
frames : Int
active_nodes : Int
render_passes : Int
events : Int
duration : Double
} derive(Debug)
///|
pub fn EvaluationStats2::frames(self : EvaluationStats2) -> Int {
self.frames
}
///|
pub fn EvaluationStats2::active_nodes(self : EvaluationStats2) -> Int {
self.active_nodes
}
///|
pub fn EvaluationStats2::render_passes(self : EvaluationStats2) -> Int {
self.render_passes
}
///|
pub fn EvaluationStats2::events(self : EvaluationStats2) -> Int {
self.events
}
///|
pub fn EvaluationStats2::duration(self : EvaluationStats2) -> Double {
self.duration
}
///|
pub fn summarize_evaluations(
values : Array[TimelineEvaluation2],
) -> EvaluationStats2 {
let mut nodes = 0
let mut passes = 0
let mut events = 0
let mut first = 0.0
let mut last = 0.0
for index in 0.. Array[Double] {
let result : Array[Double] = []
for value in values {
result.push(value.context.normalized)
}
result
}
///|
pub fn evaluation_times(values : Array[TimelineEvaluation2]) -> Array[Double] {
let result : Array[Double] = []
for value in values {
result.push(value.context.time)
}
result
}
///|
pub fn evaluate_scalar_track(
track : ScalarTrack,
schedule : FrameSchedule2,
) -> ScalarSeries2 {
let times = schedule.timestamps()
let values : Array[Double] = []
for time in times {
values.push(track.sample(time))
}
scalar_series2(times, values)
}
///|
pub fn evaluate_point2_track(
track : Point2Track,
schedule : FrameSchedule2,
) -> PointSeries2 {
let times = schedule.timestamps()
let values : Array[Point2] = []
for time in times {
values.push(track.sample(time))
}
point_series2(times, values)
}
///|
pub fn evaluate_color_track(
track : RgbaTrack,
schedule : FrameSchedule2,
) -> ColorSeries2 {
let times = schedule.timestamps()
let values : Array[Rgba] = []
for time in times {
values.push(track.sample(time))
}
color_series2(times, values)
}