Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
StateMachineNode.cs
1using System;
3using System.Threading.Tasks;
4using System.Xml;
10
12{
19 public delegate bool ForEachCallback(IStateMachineNode Node, object State);
20
24 [TypeName(TypeNameSerialization.FullName)]
25 public abstract class StateMachineNode : IStateMachineNode
26 {
27 private IStateMachineNode[] childNodes;
28 private StateMachine stateMachine;
29
34 {
35 }
36
40 public abstract string LocalName { get; }
41
46
50 public StateMachine StateMachine => this.stateMachine;
51
55 [DefaultValueNull]
57 {
58 get => this.childNodes;
59 set
60 {
61 this.childNodes = value;
63 }
64 }
65
69 protected virtual void OnChildNodesUpdated()
70 {
71 // Do nothing by default.
72 }
73
78 public abstract IStateMachineNode Create();
79
84 public virtual async Task Parse(XmlElement Xml)
85 {
86 List<IStateMachineNode> Children = null;
87
88 foreach (XmlNode N in Xml.ChildNodes)
89 {
90 if (N is XmlElement E)
91 {
92 Children ??= new List<IStateMachineNode>();
93 Children.Add(await StateMachineProcessor.Create(E));
94 }
95 }
96
97 this.ChildNodes = Children?.ToArray();
98 }
99
106 protected T GetChildElement<T>(bool Required)
107 where T : StateMachineNode
108 {
109 T Result = this.GetChildElement<T>();
110 if (!(Result is null))
111 return Result;
112
113 if (Required)
114 throw new StateMachineException(this.stateMachine, "Expected element: " + typeof(T).FullName);
115
116 return default;
117 }
118
124 protected T GetChildElement<T>()
125 where T : IStateMachineNode
126 {
127 if (this.ChildNodes is null)
128 return default;
129
130 foreach (IStateMachineNode Node in this.ChildNodes)
131 {
132 if (Node is T Item)
133 return Item;
134 }
135
136 return default;
137 }
138
144 protected T[] GetChildElements<T>()
145 where T : IStateMachineNode
146 {
147 if (this.ChildNodes is null)
148 return Array.Empty<T>();
149
150 List<T> Result = null;
151
152 foreach (IStateMachineNode Node in this.ChildNodes)
153 {
154 if (Node is T Item)
155 {
156 Result ??= new List<T>();
157 Result.Add(Item);
158 }
159 }
160
161 return Result?.ToArray() ?? Array.Empty<T>();
162 }
163
174 protected void ConvertValueAttributeToElement<ValueType>(XmlElement Xml, bool Required)
175 where ValueType : Value
176 {
177 this.ConvertValueAttributesToElements(Xml, new Type[] { typeof(ValueType) }, new bool[] { Required });
178 }
179
190 protected void ConvertValueAttributesToElements(XmlElement Xml, Type[] ValueTypes, bool[] Required)
191 {
192 Dictionary<Type, bool> Types = new Dictionary<Type, bool>();
193 int i, c = ValueTypes.Length;
194
195 if (c != Required.Length)
196 throw new ArgumentException("Array lengths must match.", nameof(Required));
197
198 for (i = 0; i < c; i++)
199 Types[ValueTypes[i]] = Required[i];
200
201 if (!(this.ChildNodes is null))
202 {
203 foreach (IStateMachineNode Node in this.ChildNodes)
204 Types.Remove(Node.GetType());
205 }
206
207 List<IStateMachineNode> ToAdd = null;
208
209 foreach (KeyValuePair<Type, bool> P in Types)
210 {
211 Value Result = (Value)Runtime.Inventory.Types.Instantiate(P.Key);
212 string s = Result.LocalName;
213
214 if (!string.IsNullOrEmpty(s))
215 {
216 s = s[..1].ToLower() + s[1..];
217 if (Xml.HasAttribute(s))
218 {
219 Result.Node = Value.ParseAttributeValue(Xml.GetAttribute(s));
220
221 ToAdd ??= new List<IStateMachineNode>();
222 ToAdd.Add(Result);
223 }
224 else if (P.Value)
225 throw new StateMachineException(this.stateMachine, "Required child element (or corresponding attribute) missing: " + Result.LocalName);
226 }
227 }
228
229 if (!(ToAdd is null))
230 {
231 if (this.childNodes is null)
232 this.childNodes = ToAdd.ToArray();
233 else
234 {
235 c = this.childNodes.Length;
236 i = c + ToAdd.Count;
237
238 Array.Resize(ref this.childNodes, i);
239 ToAdd.CopyTo(this.childNodes, c);
240 }
241
242 this.OnChildNodesUpdated();
243 }
244 }
245
251 protected T GetValueElement<T>()
252 where T : Value
253 {
254 if (!(this.ChildNodes is null))
255 {
256 foreach (IStateMachineNode Node in this.ChildNodes)
257 {
258 if (Node is T Element)
259 return Element;
260 }
261 }
262
263 return null;
264 }
265
272 public bool ForEach(ForEachCallback Callback, object State)
273 {
274 if (!Callback(this, State))
275 return false;
276
277 if (!(this.ChildNodes is null))
278 {
279 foreach (IStateMachineNode Node in this.ChildNodes)
280 {
281 if (!Node.ForEach(Callback, State))
282 return false;
283 }
284 }
285
286 return true;
287 }
288
293 public virtual void IndexElement(StateMachine Machine)
294 {
295 this.stateMachine = Machine;
296 }
297
302 public virtual void CheckReferences(StateMachine Machine, Token Token)
303 {
304 // Do nothing by default.
305 }
306
307 }
308}
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:15
Abstract base class for State-Machine nodes.
bool ForEach(ForEachCallback Callback, object State)
Iterates through th node and all its child nodes.
virtual void CheckReferences(StateMachine Machine, Token Token)
Checks references in the node.
IStateMachineNode[] ChildNodes
Child nodes, if available. Null if no children.
void ConvertValueAttributeToElement< ValueType >(XmlElement Xml, bool Required)
Converts a value attribute to parsed element. The XML definition has to be parsed before,...
abstract IStateMachineNode Create()
Creates a new node of the corresponding type.
virtual void OnChildNodesUpdated()
Method called whenever ChildNodes is updated.
virtual void IndexElement(StateMachine Machine)
Indexes the element in the state-machine.
T GetChildElement< T >()
Gets a child items of a specific type.
T GetValueElement< T >()
Gets a value element from the list of child elements.
virtual async Task Parse(XmlElement Xml)
Parses the State-machine node.
StateMachineNode()
Abstract base class for State-Machine nodes.
T[] GetChildElements< T >()
Gets an array of child items of a specific type.
void ConvertValueAttributesToElements(XmlElement Xml, Type[] ValueTypes, bool[] Required)
Converts value attributes to parsed elements. The XML definition has to be parsed before,...
Abstract base class for nodes with a value.
Definition: Value.cs:14
Class representing a state machine.
Definition: StateMachine.cs:43
const string StateMachineNamespace
https://paiwise.tagroot.io/Schema/StateMachines.xsd
bool ForEach(ForEachCallback Callback, object State)
Iterates through th node and all its child nodes.
TypeNameSerialization
How the type name should be serialized.
delegate bool ForEachCallback(IStateMachineNode Node, object State)
Delegate or callback methods when iterating through nodes in a state-machine.