prime_forge/
soul_thread.rs

1#[derive(Clone, Copy, PartialEq, PartialOrd)]
2pub struct TemporalPause {
3    pub amount_in_seconds: f32,
4}
5
6#[derive(Clone, Copy, PartialEq, PartialOrd)]
7pub enum EssenceAspect {
8    Running,
9    Yielded(TemporalPause),
10    Finished,
11}
12
13pub struct SoulThread {
14    name: String,
15    state: EssenceAspect,
16    generator: Box<dyn FnMut() -> EssenceAspect + 'static>,
17    is_waiting: bool,
18    amount_to_wait: f32,
19}
20
21impl SoulThread {
22    // Constructor to create a new coroutine
23    pub fn new(name: &str, generator: impl FnMut() -> EssenceAspect + 'static) -> Self {
24        Self {
25            name: name.to_owned(),
26            state: EssenceAspect::Running,
27            generator: Box::new(generator),
28            is_waiting: false,
29            amount_to_wait: 0.0,
30        }
31    }
32
33    // Function to resume execution of the coroutine
34    fn resume(&mut self) -> Option<TemporalPause> {
35        match self.state {
36            EssenceAspect::Running => {
37                let next_state = (self.generator)();
38                self.state = next_state;
39                self.resume()
40            }
41            EssenceAspect::Yielded(value) => {
42                self.state = EssenceAspect::Running;
43                Some(value)
44            }
45            EssenceAspect::Finished => {
46                self.state = EssenceAspect::Finished;
47                None
48            }
49        }
50    }
51
52    pub fn update(&mut self, delta_time: f32) {
53        if self.is_waiting {
54            self.amount_to_wait -= delta_time;
55
56            if self.amount_to_wait > 0.0 {
57                return;
58            }
59            self.is_waiting = false;
60        }
61
62        if let Some(res) = self.resume() {
63            self.is_waiting = true;
64            self.amount_to_wait = res.amount_in_seconds;
65        }
66    }
67
68    pub fn stop(&mut self) {
69        self.state = EssenceAspect::Finished;
70    }
71}
72
73pub struct SoulThreadManager {
74    soul_threads: Vec<SoulThread>,
75}
76
77impl SoulThreadManager {
78    pub fn new() -> Self {
79        Self {
80            soul_threads: Vec::new(),
81        }
82    }
83
84    pub fn add_thread(&mut self, thread: SoulThread) {
85        self.soul_threads.push(thread);
86    }
87
88    pub fn update(&mut self, delta_time: f32) {
89        for thread in self.soul_threads.iter_mut() {
90            if thread.state == EssenceAspect::Finished {
91                continue;
92            }
93            thread.update(delta_time);
94        }
95
96        self.soul_threads
97            .retain(|thread| thread.state != EssenceAspect::Finished);
98    }
99
100    pub fn stop_all(&mut self) {
101        self.soul_threads
102            .iter_mut()
103            .for_each(|thread| thread.stop());
104    }
105
106    pub fn stop_by_name(&mut self, name: &str) {
107        let soul_thread = self
108            .soul_threads
109            .iter_mut()
110            .find(|thread| thread.name == name);
111        if let Some(soul_thread) = soul_thread {
112            soul_thread.stop();
113        }
114    }
115}