Skip to main content

lumen_engine/
composition.rs

1use crate::{audio::AudioTimeline, error::LumenError, graph::Graph};
2
3#[derive(Debug, Clone)]
4pub struct TimelineSettings {
5    pub fps: f32,
6    pub duration_frames: u32,
7}
8
9impl TimelineSettings {
10    pub fn time_seconds(&self, frame: u32) -> f64 {
11        if self.fps <= 0.0 {
12            return 0.0;
13        }
14        frame as f64 / self.fps as f64
15    }
16}
17
18#[derive(Debug, Clone)]
19pub struct RenderSettings {
20    pub width: u32,
21    pub height: u32,
22    pub background_color: [u8; 4],
23}
24
25#[derive(Debug, Clone, Default)]
26pub struct CompositionMetadata {
27    pub name: Option<String>,
28}
29
30#[derive(Debug)]
31pub struct Composition {
32    pub graph: Graph,
33    pub timeline: TimelineSettings,
34    pub render_settings: RenderSettings,
35    pub metadata: Option<CompositionMetadata>,
36    pub audio: Option<AudioTimeline>,
37}
38
39unsafe impl Sync for Composition {}
40unsafe impl Send for Composition {}
41
42impl Composition {
43    pub fn new(graph: Graph, timeline: TimelineSettings, render_settings: RenderSettings) -> Self {
44        Self {
45            graph,
46            timeline,
47            render_settings,
48            metadata: None,
49            audio: None,
50        }
51    }
52
53    pub fn validate_structure(&self) -> Result<(), Vec<LumenError>> {
54        let mut errors = Vec::new();
55
56        match self.graph.validate() {
57            Ok(_) => {}
58            Err(graph_errors) => errors.extend(graph_errors),
59        }
60
61        if errors.is_empty() {
62            Ok(())
63        } else {
64            Err(errors)
65        }
66    }
67}