gloss_renderer/plugin_manager/
plugins.rs1use crate::scene::Scene;
9use crate::viewer_dummy::RunnerDummy;
10use crate::{
11 viewer::{GpuResources, Runner},
12 viewer_headless::RunnerHeadless,
13};
14
15use gloss_utils::abi_stable_aliases::std_types::{RDuration, RString, RVec, Tuple2};
16#[cfg(not(target_arch = "wasm32"))]
17use gloss_utils::abi_stable_aliases::StableAbi;
18
19use super::GpuSystem;
20use super::{
21 runner::RunnerState,
22 systems::{EventSystem, GuiSystem, LogicSystem, SystemMetadata},
23};
24
25#[repr(C)]
26#[cfg_attr(not(target_arch = "wasm32"), derive(StableAbi))]
27pub enum Event {
28 DroppedFile(RString),
29}
30pub trait Plugin {
33 fn event_systems(&self) -> Vec<EventSystem>;
34 fn logic_systems(&self) -> Vec<LogicSystem>;
35 fn gui_systems(&self) -> Vec<GuiSystem>;
36 fn autorun(&self) -> bool;
37}
38
39pub(crate) trait InternalPlugin {
42 fn gpu_systems(&self) -> Vec<GpuSystem>;
46 fn autorun(&self) -> bool;
47}
48
49#[repr(C)]
50#[cfg_attr(not(target_arch = "wasm32"), derive(StableAbi))]
51pub struct Plugins {
52 pub event_systems: RVec<Tuple2<EventSystem, SystemMetadata>>,
53 pub logic_systems: RVec<Tuple2<LogicSystem, SystemMetadata>>,
54 pub gui_systems: RVec<Tuple2<GuiSystem, SystemMetadata>>,
55}
56
57impl Default for Plugins {
58 fn default() -> Self {
59 Self {
60 event_systems: RVec::new(),
61 logic_systems: RVec::new(),
62 gui_systems: RVec::new(),
63 }
64 }
65}
66impl Plugins {
67 pub fn new() -> Self {
68 Self {
69 event_systems: RVec::new(),
70 logic_systems: RVec::new(),
71 gui_systems: RVec::new(),
72 }
73 }
74 #[allow(clippy::needless_update)]
75 pub fn insert_plugin<T: Plugin + 'static>(&mut self, plugin: &T) {
76 for sys in plugin.event_systems().iter() {
77 let metadata = SystemMetadata {
78 autorun: plugin.autorun(),
79 ..Default::default()
80 };
81 self.event_systems.push(Tuple2(sys.clone(), metadata));
82 }
83 for sys in plugin.logic_systems().iter() {
84 let metadata = SystemMetadata {
85 autorun: plugin.autorun(),
86 ..Default::default()
87 };
88 self.logic_systems.push(Tuple2(sys.clone(), metadata));
89 }
90 for sys in plugin.gui_systems().iter() {
91 let metadata = SystemMetadata {
92 autorun: plugin.autorun(),
93 ..Default::default()
94 };
95 self.gui_systems.push(Tuple2(sys.clone(), metadata));
96 }
97 }
98
99 pub fn run_logic_systems(&mut self, gpu_res: &mut GpuResources, scene: &mut Scene, runner: &mut Runner, autorun_flag: bool) {
100 let mut runner_state = RunnerState::from(runner);
101
102 for system_and_metadata in self.logic_systems.iter_mut() {
105 let metadata = &mut system_and_metadata.1;
106 let sys = &system_and_metadata.0;
107 if metadata.autorun == autorun_flag {
108 let func = sys.f;
109
110 let now = wasm_timer::Instant::now();
112 func(scene, &mut runner_state);
113 metadata.execution_time = RDuration::from(now.elapsed());
115 }
116 }
117 runner_state.to(runner);
118
119 if runner_state.request_redraw {
120 gpu_res.request_redraw();
121 }
122 }
123
124 pub fn run_logic_systems_headless(&mut self, scene: &mut Scene, runner: &mut RunnerHeadless, autorun_flag: bool) {
125 let mut runner_state = RunnerState::from_headless(runner);
126 for system_and_metadata in self.logic_systems.iter_mut() {
127 let metadata = &mut system_and_metadata.1;
128 let sys = &system_and_metadata.0;
129 if metadata.autorun == autorun_flag {
130 let func = sys.f;
131
132 let now = wasm_timer::Instant::now();
134 func(scene, &mut runner_state);
135 metadata.execution_time = RDuration::from(now.elapsed());
136 }
137 }
138 runner_state.to_headless(runner);
139 }
140
141 pub fn run_logic_systems_dummy(&mut self, scene: &mut Scene, runner: &mut RunnerDummy, autorun_flag: bool) {
143 let mut runner_state = RunnerState::from_dummy(runner);
144 for system_and_metadata in self.logic_systems.iter_mut() {
145 let metadata = &mut system_and_metadata.1;
146 let sys = &system_and_metadata.0;
147 if metadata.autorun == autorun_flag {
148 let func = sys.f;
149
150 let now = wasm_timer::Instant::now();
152 func(scene, &mut runner_state);
153 metadata.execution_time = RDuration::from(now.elapsed());
154 }
155 }
156 runner_state.to_dummy(runner);
157 }
158
159 pub fn try_handle_event(&self, scene: &mut Scene, runner: &mut Runner, event: &Event) -> bool {
160 let mut runner_state = RunnerState::from(runner);
161 let mut handled = false;
162 for system_and_metadata in self.event_systems.iter() {
163 let sys = &system_and_metadata.0;
164 let func = sys.f;
165 handled |= func(scene, &mut runner_state, event);
166 }
167 runner_state.to(runner);
168 handled
169 }
170}
171
172pub(crate) struct InternalPlugins {
173 pub gpu_systems: RVec<Tuple2<GpuSystem, SystemMetadata>>,
174}
175
176impl Default for InternalPlugins {
177 fn default() -> Self {
178 Self { gpu_systems: RVec::new() }
179 }
180}
181impl InternalPlugins {
182 pub fn new() -> Self {
183 Self { gpu_systems: RVec::new() }
184 }
185 #[allow(clippy::needless_update)]
186 pub fn insert_plugin<T: InternalPlugin + 'static>(&mut self, plugin: &T) {
187 for sys in plugin.gpu_systems().iter() {
188 let metadata = SystemMetadata {
189 autorun: plugin.autorun(),
190 ..Default::default()
191 };
192 self.gpu_systems.push(Tuple2(sys.clone(), metadata));
193 }
194 }
195
196 pub fn run_gpu_systems(&mut self, gpu_res: &mut GpuResources, scene: &mut Scene, runner: &mut Runner, autorun_flag: bool) {
197 let mut runner_state = RunnerState::from(runner);
198
199 for system_and_metadata in self.gpu_systems.iter_mut() {
200 let metadata = &mut system_and_metadata.1;
201 let sys = &system_and_metadata.0;
202 if metadata.autorun == autorun_flag {
203 let func = sys.f;
204
205 let now = wasm_timer::Instant::now();
207 func(scene, &mut runner_state, gpu_res);
208 metadata.execution_time = RDuration::from(now.elapsed());
209 }
210 }
211 runner_state.to(runner);
212
213 if runner_state.request_redraw {
214 gpu_res.request_redraw();
215 }
216 }
217}