cog_task/action/core/
counter.rs1use crate::action::{Action, Props, StatefulAction, VISUAL};
2use crate::comm::{QWriter, Signal};
3use crate::gui::{style_ui, Style};
4use crate::resource::{IoManager, ResourceManager};
5use crate::server::{AsyncSignal, Config, State, SyncSignal};
6use eframe::egui;
7use egui_extras::{Size, StripBuilder};
8use eyre::Result;
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Deserialize, Serialize)]
12#[serde(deny_unknown_fields)]
13pub struct Counter(#[serde(default = "defaults::from")] u32);
14
15stateful!(Counter { count: u32 });
16
17mod defaults {
18 #[inline(always)]
19 pub fn from() -> u32 {
20 3
21 }
22}
23
24impl From<u32> for Counter {
25 fn from(i: u32) -> Self {
26 Self(i)
27 }
28}
29
30impl Action for Counter {
31 fn stateful(
32 &self,
33 _io: &IoManager,
34 _res: &ResourceManager,
35 _config: &Config,
36 _sync_writer: &QWriter<SyncSignal>,
37 _async_writer: &QWriter<AsyncSignal>,
38 ) -> Result<Box<dyn StatefulAction>> {
39 Ok(Box::new(StatefulCounter {
40 done: false,
41 count: self.0,
42 }))
43 }
44}
45
46impl StatefulAction for StatefulCounter {
47 impl_stateful!();
48
49 #[inline(always)]
50 fn props(&self) -> Props {
51 VISUAL.into()
52 }
53
54 fn start(
55 &mut self,
56 sync_writer: &mut QWriter<SyncSignal>,
57 _async_writer: &mut QWriter<AsyncSignal>,
58 _state: &State,
59 ) -> Result<Signal> {
60 if self.count == 0 {
61 self.done = true;
62 sync_writer.push(SyncSignal::UpdateGraph);
63 } else {
64 sync_writer.push(SyncSignal::Repaint);
65 }
66
67 Ok(Signal::none())
68 }
69
70 fn show(
71 &mut self,
72 ui: &mut egui::Ui,
73 sync_writer: &mut QWriter<SyncSignal>,
74 _async_writer: &mut QWriter<AsyncSignal>,
75 _state: &State,
76 ) -> Result<()> {
77 enum Interaction {
78 None,
79 Decrement,
80 }
81
82 let mut interaction = Interaction::None;
83
84 let button = egui::Button::new(format!("Click me {} more times", self.count));
85
86 StripBuilder::new(ui)
87 .size(Size::remainder())
88 .size(Size::exact(420.0))
89 .size(Size::remainder())
90 .horizontal(|mut strip| {
91 strip.empty();
92 strip.strip(|builder| {
93 builder
94 .size(Size::remainder())
95 .size(Size::exact(80.0))
96 .size(Size::remainder())
97 .vertical(|mut strip| {
98 strip.empty();
99 strip.cell(|ui| {
100 ui.centered_and_justified(|ui| {
101 style_ui(ui, Style::SelectButton);
102 if ui.add(button).clicked() {
103 interaction = Interaction::Decrement;
104 }
105 });
106 });
107 strip.empty();
108 });
109 });
110 strip.empty();
111 });
112
113 match interaction {
114 Interaction::None => {}
115 Interaction::Decrement => {
116 self.count = self.count.saturating_sub(1);
117 if self.count == 0 {
118 self.done = true;
119 sync_writer.push(SyncSignal::UpdateGraph);
120 }
121 }
122 }
123
124 Ok(())
125 }
126
127 fn debug(&self) -> Vec<(&str, String)> {
128 <dyn StatefulAction>::debug(self)
129 .into_iter()
130 .chain([("count", format!("{:?}", self.count))])
131 .collect()
132 }
133}