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 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 pub fn set_randomize_task_order(&self, randomize: bool) {
110 self.executor.set_randomize_task_order(randomize);
111 }
112
113 pub fn set_task_order_seed(&self, seed: u64) {
114 self.executor.set_task_order_seed(seed);
115 }
116
117 #[must_use]
118 pub fn default_clock(&mut self) -> Clock {
119 self.executor.get_clock(DEFAULT_CLOCK_MHZ)
120 }
121
122 #[must_use]
123 pub fn clock_hz(&mut self, freq_hz: f64) -> Clock {
124 self.executor.get_clock(freq_hz / 1_000_000.0)
125 }
126
127 #[must_use]
128 pub fn clock_khz(&mut self, freq_khz: f64) -> Clock {
129 self.executor.get_clock(freq_khz / 1000.0)
130 }
131
132 #[must_use]
133 pub fn clock_mhz(&mut self, freq_mhz: f64) -> Clock {
134 self.executor.get_clock(freq_mhz)
135 }
136
137 #[must_use]
138 pub fn clock_ghz(&mut self, freq_ghz: f64) -> Clock {
139 self.executor.get_clock(freq_ghz * 1000.0)
140 }
141
142 #[must_use]
143 pub fn time_now_ns(&self) -> f64 {
144 self.executor.time_now_ns()
145 }
146
147 #[must_use]
148 pub fn top(&self) -> &Rc<Entity> {
149 &self.toplevel
150 }
151
152 #[must_use]
153 pub fn tracker(&self) -> Tracker {
154 self.tracker.clone()
155 }
156}
157
158impl Default for Engine {
164 fn default() -> Self {
165 let tracker = stdout_tracker(log::Level::Info);
166 Self::new(&tracker)
167 }
168}
169
170impl Drop for Engine {
171 fn drop(&mut self) {
172 self.tracker.shutdown();
175 }
176}