1#[macro_use]
2mod macros;
3pub mod core;
4pub mod de;
5pub mod extra;
6pub mod include;
7pub mod props;
8
9pub use include::*;
10pub use props::*;
11
12use crate::comm::{QWriter, Signal, SignalId};
13use crate::resource::{IoManager, Key, ResourceAddr, ResourceManager};
14use crate::server::{AsyncSignal, Config, State, SyncSignal};
15use eframe::egui;
16use eyre::Result;
17use itertools::Itertools;
18use std::any::Any;
19use std::collections::BTreeSet;
20use std::fmt::{Debug, Formatter};
21use std::time::Instant;
22
23pub trait Action: Debug + Any {
24 #[inline(always)]
25 fn init(self) -> Result<Box<dyn Action>>
26 where
27 Self: 'static + Sized,
28 {
29 Ok(Box::new(self))
30 }
31
32 #[inline(always)]
33 fn in_signals(&self) -> BTreeSet<SignalId> {
34 BTreeSet::new()
35 }
36
37 #[inline(always)]
38 fn out_signals(&self) -> BTreeSet<SignalId> {
39 BTreeSet::new()
40 }
41
42 #[inline(always)]
43 #[allow(unused_variables)]
44 fn resources(&self, config: &Config) -> Vec<ResourceAddr> {
45 vec![]
46 }
47
48 fn stateful(
49 &self,
50 io: &IoManager,
51 res: &ResourceManager,
52 config: &Config,
53 sync_writer: &QWriter<SyncSignal>,
54 async_writer: &QWriter<AsyncSignal>,
55 ) -> Result<Box<dyn StatefulAction>>;
56}
57
58pub trait StatefulAction: Send {
59 fn is_over(&self) -> Result<bool>;
60
61 fn type_str(&self) -> String;
62
63 fn props(&self) -> Props {
64 DEFAULT.into()
65 }
66
67 #[allow(unused_variables)]
68 fn start(
69 &mut self,
70 sync_writer: &mut QWriter<SyncSignal>,
71 async_writer: &mut QWriter<AsyncSignal>,
72 state: &State,
73 ) -> Result<Signal> {
74 if self.props().visual() {
75 sync_writer.push(SyncSignal::Repaint);
76 }
77 Ok(Signal::none())
78 }
79
80 #[allow(unused_variables)]
81 fn update(
82 &mut self,
83 signal: &ActionSignal,
84 sync_writer: &mut QWriter<SyncSignal>,
85 async_writer: &mut QWriter<AsyncSignal>,
86 state: &State,
87 ) -> Result<Signal> {
88 Ok(Signal::none())
89 }
90
91 #[allow(unused_variables)]
92 fn show(
93 &mut self,
94 ui: &mut egui::Ui,
95 sync_writer: &mut QWriter<SyncSignal>,
96 async_writer: &mut QWriter<AsyncSignal>,
97 state: &State,
98 ) -> Result<()> {
99 Ok(())
100 }
101
102 #[allow(unused_variables)]
103 fn stop(
104 &mut self,
105 sync_writer: &mut QWriter<SyncSignal>,
106 async_writer: &mut QWriter<AsyncSignal>,
107 state: &State,
108 ) -> Result<Signal> {
109 if self.props().visual() {
110 sync_writer.push(SyncSignal::Repaint);
111 }
112 Ok(Signal::none())
113 }
114
115 fn debug(&self) -> Vec<(&str, String)> {
116 vec![
117 ("type", format!("{:?}", self.type_str())),
118 ("done", format!("{:?}", self.is_over())),
119 ("viz", format!("{:?}", self.props().visual())),
120 ("inf", format!("{:?}", self.props().infinite())),
121 ]
122 }
123}
124
125impl Debug for dyn StatefulAction {
126 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
127 write!(
128 f,
129 "Action({})",
130 self.debug()
131 .iter()
132 .map(|(key, value)| format!("{key}={value}"))
133 .join(", ")
134 )
135 }
136}
137
138pub trait ImplStatefulAction: StatefulAction {}
139
140#[derive(Debug, Clone)]
141pub enum ActionSignal {
142 UpdateGraph,
143 KeyPress(Instant, BTreeSet<Key>),
144 StateChanged(Instant, BTreeSet<SignalId>),
145}