prime_forge/
soul_thread.rs1#[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 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 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}