cog_task/action/core/
seq.rs1use crate::action::{Action, ActionSignal, Props, StatefulAction, DEFAULT};
2use crate::comm::{QWriter, Signal, SignalId};
3use crate::resource::{IoManager, ResourceAddr, ResourceManager};
4use crate::server::{AsyncSignal, Config, State, SyncSignal};
5use eframe::egui;
6use eyre::{eyre, Result};
7use itertools::Itertools;
8use serde::{Deserialize, Serialize};
9use std::collections::{BTreeSet, VecDeque};
10
11#[derive(Debug, Deserialize, Serialize)]
12pub struct Seq(Vec<Box<dyn Action>>);
13
14stateful!(Seq {
15 children: VecDeque<Box<dyn StatefulAction>>,
16});
17
18impl Seq {
19 pub fn new(children: Vec<Box<dyn Action>>) -> Self {
20 Self(children)
21 }
22}
23
24impl Action for Seq {
25 #[inline]
26 fn in_signals(&self) -> BTreeSet<SignalId> {
27 let mut signals = BTreeSet::new();
28 for c in self.0.iter() {
29 signals.extend(c.in_signals());
30 }
31 signals
32 }
33
34 #[inline]
35 fn out_signals(&self) -> BTreeSet<SignalId> {
36 let mut signals = BTreeSet::new();
37 for c in self.0.iter() {
38 signals.extend(c.out_signals());
39 }
40 signals
41 }
42
43 #[inline]
44 fn resources(&self, config: &Config) -> Vec<ResourceAddr> {
45 self.0
46 .iter()
47 .flat_map(|c| c.resources(config))
48 .unique()
49 .collect()
50 }
51
52 fn stateful(
53 &self,
54 io: &IoManager,
55 res: &ResourceManager,
56 config: &Config,
57 sync_writer: &QWriter<SyncSignal>,
58 async_writer: &QWriter<AsyncSignal>,
59 ) -> Result<Box<dyn StatefulAction>> {
60 let mut children: VecDeque<_> = VecDeque::with_capacity(self.0.len());
61 for c in self.0.iter() {
62 children.push_back(c.stateful(io, res, config, sync_writer, async_writer)?);
63 }
64
65 for c in children.iter().take(children.len() - 1) {
66 if c.props().infinite() {
67 return Err(eyre!("Only the final action in a `Seq` can be infinite."));
68 }
69 }
70
71 Ok(Box::new(StatefulSeq {
72 done: false,
73 children,
74 }))
75 }
76}
77
78impl StatefulSeq {
79 pub fn push(&mut self, child: impl Into<Box<dyn StatefulAction>>) {
80 self.children.push_back(child.into());
81 }
82}
83
84impl StatefulAction for StatefulSeq {
85 impl_stateful!();
86
87 #[inline(always)]
88 fn props(&self) -> Props {
89 if let Some(c) = self.children.get(0) {
90 c.props()
91 } else {
92 DEFAULT.into()
93 }
94 }
95
96 #[inline]
97 fn start(
98 &mut self,
99 sync_writer: &mut QWriter<SyncSignal>,
100 async_writer: &mut QWriter<AsyncSignal>,
101 state: &State,
102 ) -> Result<Signal> {
103 if let Some(c) = self.children.get_mut(0) {
104 c.start(sync_writer, async_writer, state)
105 } else {
106 self.done = true;
107 sync_writer.push(SyncSignal::UpdateGraph);
108 Ok(Signal::none())
109 }
110 }
111
112 #[inline]
113 fn update(
114 &mut self,
115 signal: &ActionSignal,
116 sync_writer: &mut QWriter<SyncSignal>,
117 async_writer: &mut QWriter<AsyncSignal>,
118 state: &State,
119 ) -> Result<Signal> {
120 if let Some(c) = self.children.get_mut(0) {
121 let mut news = vec![];
122 news.extend(c.update(signal, sync_writer, async_writer, state)?);
123
124 if c.is_over()? {
125 news.extend(self.children.pop_front().unwrap().stop(
126 sync_writer,
127 async_writer,
128 state,
129 )?);
130
131 if let Some(c) = self.children.get_mut(0) {
132 news.extend(c.start(sync_writer, async_writer, state)?);
133 } else {
134 self.done = true;
135 }
136 }
137
138 Ok(news.into())
139 } else {
140 Ok(Signal::none())
141 }
142 }
143
144 fn show(
145 &mut self,
146 ui: &mut egui::Ui,
147 sync_writer: &mut QWriter<SyncSignal>,
148 async_writer: &mut QWriter<AsyncSignal>,
149 state: &State,
150 ) -> Result<()> {
151 if let Some(c) = self.children.get_mut(0) {
152 c.show(ui, sync_writer, async_writer, state)
153 } else {
154 Ok(())
155 }
156 }
157
158 #[inline]
159 fn stop(
160 &mut self,
161 sync_writer: &mut QWriter<SyncSignal>,
162 async_writer: &mut QWriter<AsyncSignal>,
163 state: &State,
164 ) -> Result<Signal> {
165 if let Some(c) = self.children.get_mut(0) {
166 c.stop(sync_writer, async_writer, state)
167 } else {
168 Ok(Signal::none())
169 }
170 }
171}