1use std::{
3 any::{Any, TypeId},
4 collections::HashMap,
5 sync::Arc,
6};
7
8use crate::{
9 stage::{EvalStrategy, ReevaluationRule, Stage}, types::{DataLabel, NodeOutput}, InjectionError, RefType
10};
11
12pub(crate) const UNNAMED_OUTPUT_NAME: DataLabel = DataLabel::new_const("_");
14
15#[derive(Debug)]
20pub struct Node<S: Stage> {
21 pub(super) stage: S,
22 pub(super) state: S::State,
25 pub(super) inputs: HashMap<DataLabel, (Arc<dyn Any + Send + Sync>, ReevaluationRule)>,
26 pub(super) outputs: HashMap<DataLabel, Arc<dyn Any + Send + Sync>>,
27 pub(super) input_changed: bool,
28}
29
30impl<S: Stage> Node<S> {
31 pub fn new(stage: S, initial_state: S::State) -> Self {
32 Self {
33 stage,
34 state: initial_state,
35 inputs: HashMap::new(),
36 outputs: HashMap::new(),
37 input_changed: true,
38 }
39 }
40}
41
42pub trait AnyNode: Any {
46 fn into_any(self: Box<Self>) -> Box<dyn Any>;
48 fn as_any(&self) -> &dyn Any;
50 fn as_any_mut(&mut self) -> &mut dyn Any;
52 fn eval(&mut self) -> Result<HashMap<DataLabel, Arc<dyn Any + Send + Sync>>, InjectionError>;
54 fn eval_strategy(&self) -> EvalStrategy;
55 fn reeval_rule(&self) -> ReevaluationRule;
56 fn replace_output(
59 &mut self,
60 key: &DataLabel,
61 output: Arc<dyn Any + Send + Sync>,
62 ) -> Result<Option<Arc<dyn Any + Send + Sync>>, InjectionError>;
63 fn flow_data(
66 &mut self,
67 parent: &mut Box<dyn AnyNode>,
68 output: DataLabel,
69 input: DataLabel,
70 ) -> Result<(), InjectionError>;
71 fn inputs_mut(
73 &mut self,
74 ) -> &mut HashMap<DataLabel, (Arc<dyn Any + Send + Sync>, ReevaluationRule)>;
75 fn outputs_mut(&mut self) -> &mut HashMap<DataLabel, Arc<dyn Any + Send + Sync>>;
77 fn input_reftype(&self, name: &DataLabel) -> Option<RefType>;
79 fn set_input_changed(&mut self, val: bool);
81 fn input_changed(&self) -> bool;
83 fn input_names(&self) -> std::iter::Cloned<std::collections::hash_map::Keys<'_, DataLabel, (TypeId, RefType)>>;
84 fn output_names(&self) -> std::iter::Cloned<std::collections::hash_map::Keys<'_, DataLabel, TypeId>>;
85 fn stage_name(&self) -> &str;
86}
87
88impl<S: Stage + 'static> AnyNode for Node<S> {
89 fn into_any(self: Box<Self>) -> Box<dyn Any> {
90 Box::new(*self)
91 }
92
93 fn as_any(&self) -> &dyn Any {
94 self as &dyn Any
95 }
96
97 fn as_any_mut(&mut self) -> &mut dyn Any {
98 self as &mut dyn Any
99 }
100
101 fn eval_strategy(&self) -> EvalStrategy {
102 self.stage.eval_strategy()
103 }
104
105 fn reeval_rule(&self) -> ReevaluationRule {
106 self.stage.reeval_rule()
107 }
108
109 fn replace_output(
110 &mut self,
111 key: &DataLabel,
112 output: Arc<dyn Any + Send + Sync>,
113 ) -> Result<Option<Arc<dyn Any + Send + Sync>>, InjectionError> {
114 let output_type = self
115 .stage
116 .outputs()
117 .get(key)
118 .ok_or_else(|| InjectionError::OutputNotFound(key.clone()))?;
119 match (&*output).type_id() {
120 id if id != *output_type => {
121 return Err(InjectionError::OutputTypeMismatch(key.clone()));
122 }
123 _ => Ok(self.outputs.insert(key.clone(), output)),
124 }
125 }
126
127 fn eval(&mut self) -> Result<HashMap<DataLabel, Arc<dyn Any + Send + Sync>>, InjectionError> {
128 let mut old_outputs = HashMap::new();
129 let outputs = self.stage.evaluate(&mut self.state, &mut self.inputs)?;
131
132 match outputs {
133 NodeOutput::Standard(val) => {
134 if let Some(old_output) = self.replace_output(&UNNAMED_OUTPUT_NAME, val)? {
135 old_outputs.insert(UNNAMED_OUTPUT_NAME, old_output);
136 }
137 }
138 NodeOutput::Named(hash_map) => {
139 for (key, val) in hash_map.into_iter() {
140 if let Some(old_output) = self.replace_output(&key, val)? {
141 old_outputs.insert(key, old_output);
142 }
143 }
144 }
145 }
146 Ok(old_outputs)
147 }
148
149 fn flow_data(
150 &mut self,
151 parent: &mut Box<dyn AnyNode>,
152 output: DataLabel,
153 input: DataLabel,
154 ) -> Result<(), InjectionError> {
155 let stage_clone = self.stage.clone();
156 stage_clone.inject_input(self, parent, output, input)
157 }
158
159 fn inputs_mut(
160 &mut self,
161 ) -> &mut HashMap<DataLabel, (Arc<dyn Any + Send + Sync>, ReevaluationRule)> {
162 &mut self.inputs
163 }
164
165 fn outputs_mut(&mut self) -> &mut HashMap<DataLabel, Arc<dyn Any + Send + Sync>> {
166 &mut self.outputs
167 }
168
169 fn set_input_changed(&mut self, val: bool) {
170 self.input_changed = val;
171 }
172
173 fn input_changed(&self) -> bool {
174 self.input_changed
175 }
176
177 fn input_reftype(&self, name: &DataLabel) -> Option<RefType> {
178 self.stage.inputs().get(name).map(|input| input.1)
179 }
180
181 fn input_names(&self) -> std::iter::Cloned<std::collections::hash_map::Keys<'_, DataLabel, (TypeId, RefType)>> {
182 self.stage.inputs().keys().cloned()
183 }
184
185 fn output_names(&self) -> std::iter::Cloned<std::collections::hash_map::Keys<'_, DataLabel, TypeId>> {
186 self.stage.outputs().keys().cloned()
187 }
188
189 fn stage_name(&self) -> &str {
190 self.stage.name()
191 }
192}