1use crate::action::{Action, ActionSignal, Props, StatefulAction, DEFAULT, INFINITE, VISUAL};
2use crate::comm::{QWriter, Signal, SignalId};
3use crate::resource::{IoManager, ResourceAddr, ResourceManager};
4use crate::server::{AsyncSignal, Config, State, SyncSignal};
5use eframe::egui;
6use eyre::Result;
7use itertools::Itertools;
8use serde::{Deserialize, Serialize};
9use std::collections::BTreeSet;
10
11#[derive(Debug, Deserialize, Serialize)]
12pub struct Par(
13 Vec<Box<dyn Action>>,
14 #[serde(default)] Vec<Box<dyn Action>>,
15 #[serde(default)] Require,
16);
17
18stateful!(Par {
19 primary: Vec<Box<dyn StatefulAction>>,
20 secondary: Vec<Box<dyn StatefulAction>>,
21 require: Require,
22});
23
24#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
25#[serde(rename_all = "snake_case")]
26pub enum Require {
27 All,
28 Any,
29}
30
31impl Default for Require {
32 fn default() -> Self {
33 Require::All
34 }
35}
36
37impl Par {
38 pub fn new(
39 primary: Vec<Box<dyn Action>>,
40 secondary: Vec<Box<dyn Action>>,
41 require: Require,
42 ) -> Self {
43 Self(primary, secondary, require)
44 }
45}
46
47impl Action for Par {
48 #[inline]
49 fn in_signals(&self) -> BTreeSet<SignalId> {
50 let mut signals = BTreeSet::new();
51 for c in self.0.iter() {
52 signals.extend(c.in_signals());
53 }
54 for c in self.1.iter() {
55 signals.extend(c.in_signals());
56 }
57 signals
58 }
59
60 #[inline]
61 fn out_signals(&self) -> BTreeSet<SignalId> {
62 let mut signals = BTreeSet::new();
63 for c in self.0.iter() {
64 signals.extend(c.out_signals());
65 }
66 for c in self.1.iter() {
67 signals.extend(c.out_signals());
68 }
69 signals
70 }
71
72 #[inline]
73 fn resources(&self, config: &Config) -> Vec<ResourceAddr> {
74 self.0
75 .iter()
76 .chain(self.1.iter())
77 .flat_map(|c| c.resources(config))
78 .unique()
79 .collect()
80 }
81
82 fn stateful(
83 &self,
84 io: &IoManager,
85 res: &ResourceManager,
86 config: &Config,
87 sync_writer: &QWriter<SyncSignal>,
88 async_writer: &QWriter<AsyncSignal>,
89 ) -> Result<Box<dyn StatefulAction>> {
90 let mut primary = vec![];
91 for c in self.0.iter() {
92 primary.push(c.stateful(io, res, config, sync_writer, async_writer)?);
93 }
94
95 let mut secondary = vec![];
96 for c in self.1.iter() {
97 secondary.push(c.stateful(io, res, config, sync_writer, async_writer)?);
98 }
99
100 Ok(Box::new(StatefulPar {
101 done: false,
102 primary,
103 secondary,
104 require: self.2,
105 }))
106 }
107}
108
109impl StatefulPar {
110 pub fn push_primary(&mut self, child: impl Into<Box<dyn StatefulAction>>) {
111 self.primary.push(child.into());
112 }
113
114 pub fn push_secondary(&mut self, child: impl Into<Box<dyn StatefulAction>>) {
115 self.secondary.push(child.into());
116 }
117}
118
119impl StatefulAction for StatefulPar {
120 impl_stateful!();
121
122 #[inline]
123 fn props(&self) -> Props {
124 let mut props = DEFAULT;
125
126 for c in self.primary.iter() {
127 let c = c.props();
128 if c.visual() {
129 props |= VISUAL;
130 }
131 if c.infinite() {
132 props |= INFINITE;
133 }
134 }
135
136 for c in self.secondary.iter() {
137 let c = c.props();
138 if c.visual() {
139 props |= VISUAL;
140 }
141 }
142
143 props.into()
144 }
145
146 #[inline]
147 fn start(
148 &mut self,
149 sync_writer: &mut QWriter<SyncSignal>,
150 async_writer: &mut QWriter<AsyncSignal>,
151 state: &State,
152 ) -> Result<Signal> {
153 let mut news = vec![];
154 if self.primary.is_empty() {
155 self.done = true;
156 sync_writer.push(SyncSignal::UpdateGraph);
157 } else {
158 for c in self.primary.iter_mut().chain(self.secondary.iter_mut()) {
159 news.extend(c.start(sync_writer, async_writer, state)?);
160 }
161 }
162
163 Ok(news.into())
164 }
165
166 #[inline]
167 fn update(
168 &mut self,
169 signal: &ActionSignal,
170 sync_writer: &mut QWriter<SyncSignal>,
171 async_writer: &mut QWriter<AsyncSignal>,
172 state: &State,
173 ) -> Result<Signal> {
174 let mut done = vec![];
175 let mut news = vec![];
176 let mut finished = false;
177 for (i, c) in self.primary.iter_mut().enumerate() {
178 news.extend(c.update(signal, sync_writer, async_writer, state)?);
179
180 if c.is_over()? {
181 news.extend(c.stop(sync_writer, async_writer, state)?);
182 done.push(i);
183 }
184 }
185 if matches!(self.require, Require::Any) && !done.is_empty() {
186 finished = true;
187 }
188 for i in done.into_iter().rev() {
189 self.primary.remove(i);
190 }
191 if self.primary.is_empty() {
192 finished = true;
193 }
194
195 let mut done = vec![];
196 for (i, c) in self.secondary.iter_mut().enumerate() {
197 news.extend(c.update(signal, sync_writer, async_writer, state)?);
198
199 if c.is_over()? {
200 news.extend(c.stop(sync_writer, async_writer, state)?);
201 done.push(i);
202 }
203 }
204 for i in done.into_iter().rev() {
205 self.secondary.remove(i);
206 }
207
208 if finished {
209 self.done = true;
210 }
211
212 Ok(news.into())
213 }
214
215 fn show(
216 &mut self,
217 ui: &mut egui::Ui,
218 sync_writer: &mut QWriter<SyncSignal>,
219 async_writer: &mut QWriter<AsyncSignal>,
220 state: &State,
221 ) -> Result<()> {
222 if let Some(c) = self.primary.iter_mut().find(|c| c.props().visual()) {
223 c.show(ui, sync_writer, async_writer, state)
224 } else if let Some(c) = self.secondary.iter_mut().find(|c| c.props().visual()) {
225 c.show(ui, sync_writer, async_writer, state)
226 } else {
227 Ok(())
228 }
229 }
230
231 #[inline]
232 fn stop(
233 &mut self,
234 sync_writer: &mut QWriter<SyncSignal>,
235 async_writer: &mut QWriter<AsyncSignal>,
236 state: &State,
237 ) -> Result<Signal> {
238 let mut news = vec![];
239 let children = self.primary.iter_mut().chain(self.secondary.iter_mut());
240 for c in children {
241 news.extend(c.stop(sync_writer, async_writer, state)?);
242 }
243 Ok(news.into())
244 }
245}