1use std::cell::RefCell;
4use std::future::Future;
5use std::rc::Rc;
6
7use gwr_track::entity::{Entity, toplevel};
8use gwr_track::tracker::stdout_tracker;
9use gwr_track::{Tracker, trace};
10
11use crate::executor::{self, Executor, Spawner};
12use crate::time::clock::Clock;
13use crate::types::{Component, Eventable, SimResult};
14
15const DEFAULT_CLOCK_MHZ: f64 = 1000.0;
17
18pub struct Registry {
19 pub entity: Rc<Entity>,
20 components: RefCell<Vec<Component>>,
21}
22
23impl Registry {
24 fn new(parent: &Rc<Entity>) -> Self {
25 Self {
26 entity: Rc::new(Entity::new(parent, "registry")),
27 components: RefCell::new(Vec::new()),
28 }
29 }
30
31 pub fn spawn_components(&self, spawner: &Spawner) {
32 let mut guard = self.components.borrow_mut();
33
34 trace!(self.entity ; "Spawning {} components", guard.len());
35
36 for component in guard.drain(..) {
37 spawner.spawn(async move { component.run().await });
38 }
39 }
40
41 pub fn register(&self, component: Component) {
42 let mut guard = self.components.borrow_mut();
43 guard.push(component);
44 }
45}
46
47pub struct Engine {
48 pub executor: Executor,
49 spawner: Spawner,
50 toplevel: Rc<Entity>,
51 tracker: Tracker,
52 registry: Registry,
53}
54
55impl Engine {
56 pub fn new(tracker: &Tracker) -> Self {
58 let toplevel = toplevel(tracker, "top");
59 let (executor, spawner) = executor::new_executor_and_spawner(&toplevel);
60 let registry = Registry::new(&toplevel);
61 Self {
62 executor,
63 spawner,
64 toplevel,
65 tracker: tracker.clone(),
66 registry,
67 }
68 }
69
70 pub fn register(&self, component: Component) {
72 self.registry.register(component);
73 }
74
75 pub fn run(&mut self) -> SimResult {
76 self.registry.spawn_components(&self.spawner);
77
78 let finished = Rc::new(RefCell::new(false));
80 self.executor.run(&finished)
81 }
82
83 pub fn run_until<T: Default + Copy + 'static>(&mut self, event: Eventable<T>) -> SimResult {
84 self.registry.spawn_components(&self.spawner);
85
86 let finished = Rc::new(RefCell::new(false));
88 {
89 let finished = finished.clone();
90 self.spawner.spawn(async move {
91 event.listen().await;
92 *finished.borrow_mut() = true;
93 Ok(())
94 });
95 }
96
97 self.executor.run(&finished)
98 }
99
100 #[must_use]
101 pub fn spawner(&self) -> Spawner {
102 self.spawner.clone()
103 }
104
105 pub fn spawn(&self, future: impl Future<Output = SimResult> + 'static) {
106 self.spawner.spawn(future);
107 }
108
109 #[must_use]
110 pub fn default_clock(&mut self) -> Clock {
111 self.executor.get_clock(DEFAULT_CLOCK_MHZ)
112 }
113
114 #[must_use]
115 pub fn clock_mhz(&mut self, freq_mhz: f64) -> Clock {
116 self.executor.get_clock(freq_mhz)
117 }
118
119 #[must_use]
120 pub fn clock_ghz(&mut self, freq_ghz: f64) -> Clock {
121 self.executor.get_clock(freq_ghz * 1000.0)
122 }
123
124 #[must_use]
125 pub fn time_now_ns(&self) -> f64 {
126 self.executor.time_now_ns()
127 }
128
129 #[must_use]
130 pub fn top(&self) -> &Rc<Entity> {
131 &self.toplevel
132 }
133
134 #[must_use]
135 pub fn tracker(&self) -> Tracker {
136 self.tracker.clone()
137 }
138}
139
140impl Default for Engine {
146 fn default() -> Self {
147 let tracker = stdout_tracker(log::Level::Info);
148 Self::new(&tracker)
149 }
150}
151
152impl Drop for Engine {
153 fn drop(&mut self) {
154 self.tracker.shutdown();
157 }
158}