1use crate::{Output, OutputFormat, Scene, SceneConfig};
3use ranim_core::RanimScene;
4
5#[cfg(target_arch = "wasm32")]
6use wasm_bindgen::prelude::*;
7
8#[doc(hidden)]
10pub struct StaticScene {
11 pub name: &'static str,
13 pub constructor: fn(&mut RanimScene),
15 pub config: StaticSceneConfig,
17 pub outputs: &'static [StaticOutput],
19}
20
21#[doc(hidden)]
23pub struct StaticSceneConfig {
24 pub clear_color: &'static str,
26}
27
28#[doc(hidden)]
30pub struct StaticOutput {
31 pub width: u32,
33 pub height: u32,
35 pub fps: u32,
37 pub save_frames: bool,
39 pub name: Option<&'static str>,
41 pub name_template: Option<&'static str>,
43 pub dir: &'static str,
45 pub format: OutputFormat,
47}
48
49impl StaticOutput {
50 pub const DEFAULT: Self = Self {
52 width: 1920,
53 height: 1080,
54 fps: 60,
55 save_frames: false,
56 name: None,
57 name_template: None,
58 dir: "./output",
59 format: OutputFormat::Mp4,
60 };
61}
62
63pub use inventory;
66
67inventory::collect!(StaticScene);
68
69#[doc(hidden)]
70#[unsafe(no_mangle)]
71pub extern "C" fn get_scene(idx: usize) -> *const StaticScene {
72 inventory::iter::<StaticScene>()
73 .skip(idx)
74 .take(1)
75 .next()
76 .unwrap()
77}
78
79#[doc(hidden)]
80#[unsafe(no_mangle)]
81pub extern "C" fn scene_cnt() -> usize {
82 inventory::iter::<StaticScene>().count()
83}
84
85#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
87pub fn find_scene(name: &str) -> Option<Scene> {
88 inventory::iter::<StaticScene>()
89 .find(|s| s.name == name)
90 .map(Scene::from)
91}
92
93impl From<&StaticScene> for Scene {
96 fn from(s: &StaticScene) -> Self {
97 Self {
98 name: s.name.to_string(),
99 constructor: s.constructor,
100 config: SceneConfig::from(&s.config),
101 outputs: s.outputs.iter().map(Output::from).collect(),
102 }
103 }
104}
105
106impl From<&StaticSceneConfig> for SceneConfig {
107 fn from(c: &StaticSceneConfig) -> Self {
108 Self {
109 clear_color: c.clear_color.to_string(),
110 }
111 }
112}
113
114impl From<&StaticOutput> for Output {
115 fn from(o: &StaticOutput) -> Self {
116 Self {
117 width: o.width,
118 height: o.height,
119 fps: o.fps,
120 save_frames: o.save_frames,
121 name: o.name.map(|n| n.to_string()),
122 name_template: o.name_template.map(|n| n.to_string()),
123 dir: o.dir.to_string(),
124 format: o.format,
125 }
126 }
127}