Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Variables.cs
1using System;
4using System.IO;
5using System.Threading;
6using System.Threading.Tasks;
7using Waher.Events;
10
11namespace Waher.Script
12{
19 public delegate Task<string> ValuePrinter(object Value, Variables Variables);
20
24 public class Variables : IEnumerable<Variable>, IContextVariables
25 {
29 protected Dictionary<string, Variable> variables = new Dictionary<string, Variable>();
30
31 private CancellationTokenSource cancellation = new CancellationTokenSource();
32 private Stack<Dictionary<string, Variable>> stack = null;
33 private TextWriter consoleOut = null;
34 private IContextVariables contextVariables = null;
35 private volatile bool active = true;
36 private ValuePrinter printer = null;
37
41 public Variables(params Variable[] Variables)
42 {
43 if ((Variables?.Length ?? 0) > 0)
44 {
45 foreach (Variable Variable in Variables)
46 this.variables[Variable.Name] = Variable;
47 }
48 }
49
56 public virtual bool TryGetVariable(string Name, out Variable Variable)
57 {
58 if (this.active)
59 {
60 lock (this.variables)
61 {
62 if (this.variables.TryGetValue(Name, out Variable))
63 return true;
64 }
65
66 if (!(this.contextVariables is null))
67 return this.contextVariables.TryGetVariable(Name, out Variable);
68
69 return false;
70 }
71 else
72 throw new ScriptAbortedException();
73 }
74
80 public virtual bool ContainsVariable(string Name)
81 {
82 if (this.active)
83 {
84 lock (this.variables)
85 {
86 if (this.variables.ContainsKey(Name))
87 return true;
88 }
89
90 if (!(this.contextVariables is null))
91 return this.contextVariables.ContainsVariable(Name);
92
93 return false;
94 }
95 else
96 throw new ScriptAbortedException();
97 }
98
104 public object this[string Name]
105 {
106 get
107 {
108 if (this.TryGetVariable(Name, out Variable v))
109 return v.ValueObject;
110 else
111 return null;
112 }
113
114 set
115 {
116 this.Add(Name, value);
117 }
118 }
119
126 public virtual Variable Add(string Name, object Value)
127 {
128 Variable Result;
129
130 if (this.active)
131 {
132 lock (this.variables)
133 {
134 if (this.variables.TryGetValue(Name, out Result))
135 Result.SetValue(Value);
136 else
137 this.variables[Name] = Result = new Variable(Name, Value);
138 }
139 }
140 else
141 throw new ScriptAbortedException();
142
143 return Result;
144 }
145
151 public virtual bool Remove(string VariableName)
152 {
153 if (this.active)
154 {
155 lock (this.variables)
156 {
157 return this.variables.Remove(VariableName);
158 }
159 }
160 else
161 throw new ScriptAbortedException();
162 }
163
167 public virtual void Clear()
168 {
169 if (this.active)
170 {
171 lock (this.variables)
172 {
173 this.variables.Clear();
174 }
175 }
176 else
177 throw new ScriptAbortedException();
178 }
179
184 public virtual void Push()
185 {
186 if (this.active)
187 {
188 if (this.stack is null)
189 this.stack = new Stack<Dictionary<string, Variable>>();
190
191 this.stack.Push(this.variables);
192
193 Dictionary<string, Variable> Clone = new Dictionary<string, Variable>();
194 foreach (KeyValuePair<string, Variable> P in this.variables)
195 Clone[P.Key] = new Variable(P.Key, P.Value.ValueElement);
196
197 this.variables = Clone;
198 }
199 else
200 throw new ScriptAbortedException();
201 }
202
206 public virtual void Pop()
207 {
208 if (this.active)
209 {
210 if (this.stack is null)
211 throw new ScriptException("Stack is empty.");
212
213 this.variables = this.stack.Pop();
214 }
215 else
216 throw new ScriptAbortedException();
217 }
218
222 public TextWriter ConsoleOut
223 {
224 get => this.consoleOut;
225 set => this.consoleOut = value;
226 }
227
232 {
233 get => this.contextVariables;
234 set => this.contextVariables = value;
235 }
236
242 {
243 get => this.printer;
244 set => this.printer = value;
245 }
246
251 {
252 get
253 {
254 if (this.active)
255 {
257
258 lock (this.variables)
259 {
260 Variables = new Variable[this.variables.Count];
261 this.variables.Values.CopyTo(Variables, 0);
262 }
263
264 return Variables;
265 }
266 else
267 throw new ScriptAbortedException();
268 }
269 }
270
275 public IEnumerator<Variable> GetEnumerator()
276 {
277 return new VariableEnumerator(this.AvailableVariables);
278 }
279
280 private class VariableEnumerator : IEnumerator<Variable>
281 {
282 private readonly Variable[] variables;
283 private int pos = -1;
284
285 internal VariableEnumerator(Variable[] Variables)
286 {
287 this.variables = Variables;
288 }
289
290 public Variable Current
291 {
292 get
293 {
294 return this.variables[this.pos];
295 }
296 }
297
298 object IEnumerator.Current
299 {
300 get
301 {
302 return this.variables[this.pos];
303 }
304 }
305
306 public void Dispose()
307 {
308 }
309
310 public bool MoveNext()
311 {
312 return ++this.pos < this.variables.Length;
313 }
314
315 public void Reset()
316 {
317 this.pos = -1;
318 }
319 }
320
325 IEnumerator IEnumerable.GetEnumerator()
326 {
327 return this.AvailableVariables.GetEnumerator();
328 }
329
335 {
336 Variable[] VariablesToCopy = this.AvailableVariables;
337 Dictionary<string, Variable> Recipient = Variables.variables;
338
339 lock (Recipient)
340 {
341 foreach (Variable Variable in VariablesToCopy)
342 Recipient[Variable.Name] = Variable;
343 }
344 }
345
349 public void Abort()
350 {
351 if (this.active)
352 {
353 this.active = false;
354 this.cancellation.Cancel();
355 }
356 }
357
361 public void CancelAbort()
362 {
363 if (!this.active)
364 {
365 this.active = true;
366 this.cancellation = new CancellationTokenSource();
367 }
368 }
369
373 public bool Aborted => !this.active;
374
378 public bool Active => this.active;
379
383 public event EventHandlerAsync<PreviewEventArgs> OnPreview;
384
388 public bool HandlesPreview
389 {
390 get
391 {
392 if (!(this.OnPreview is null))
393 return true;
394
395 if (this.contextVariables is Variables v)
396 return v.HandlesPreview;
397 else
398 return false;
399 }
400 }
401
407 public async Task Preview(Expression Expression, IElement Result)
408 {
409 EventHandlerAsync<PreviewEventArgs> h = this.OnPreview;
410
411 if (!(h is null))
412 await h.Raise(this, new PreviewEventArgs(Expression, this, Result));
413
414 if (this.contextVariables is Variables v)
415 await v.Preview(Expression, Result);
416 }
417
418
424 public async Task Status(Expression Expression, string Result)
425 {
426 EventHandlerAsync<StatusEventArgs> h = this.OnStatus;
427 if (!(h is null))
428 await h(this, new StatusEventArgs(Expression, this, Result));
429 }
430
434 public bool HandlesStatus => !(this.OnStatus is null);
435
439 public event EventHandlerAsync<StatusEventArgs> OnStatus = null;
440
444 public CancellationToken CancellationToken => this.cancellation.Token;
445 }
446}
Exception thrown when a script has been aborted.
Base class for script exceptions.
Class managing a script expression.
Definition: Expression.cs:41
Event arguments for preview events.
Event arguments for status events.
Contains information about a variable.
Definition: Variable.cs:10
void SetValue(object Value)
Sets the value of the variable.
Definition: Variable.cs:70
string Name
Name of variable.
Definition: Variable.cs:78
Collection of variables.
Definition: Variables.cs:25
TextWriter ConsoleOut
Console out interface. Can be used by functions and script to output data to the console.
Definition: Variables.cs:223
virtual void Push()
Pushes the current set of variables to the stack. This state is restored by calling Pop....
Definition: Variables.cs:184
virtual void Pop()
Pops a previously stored set of variables from the stack. Variables are stored on the stack by callin...
Definition: Variables.cs:206
async Task Status(Expression Expression, string Result)
Reports current status of execution.
Definition: Variables.cs:424
IContextVariables ContextVariables
Variables available during the current context.
Definition: Variables.cs:232
EventHandlerAsync< StatusEventArgs > OnStatus
Event raised when a status message has been reported.
Definition: Variables.cs:439
bool HandlesPreview
If previews are desired.
Definition: Variables.cs:389
bool Aborted
If the script has been aborted.
Definition: Variables.cs:373
bool HandlesStatus
If status messages are desired.
Definition: Variables.cs:434
void CopyTo(Variables Variables)
Copies available variables to another variable collection.
Definition: Variables.cs:334
void CancelAbort()
Allows new script to be evaluated using this collection of variables.
Definition: Variables.cs:361
async Task Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
Definition: Variables.cs:407
virtual Variable Add(string Name, object Value)
Adds a variable to the collection.
Definition: Variables.cs:126
virtual void Clear()
Removes all variables from the collection.
Definition: Variables.cs:167
ValuePrinter Printer
Delegate that converts values to strings for (implicit) printing. Default is null,...
Definition: Variables.cs:242
virtual bool ContainsVariable(string Name)
If the collection contains a variable with a given name.
Definition: Variables.cs:80
Dictionary< string, Variable > variables
Internal set of variables.
Definition: Variables.cs:29
EventHandlerAsync< PreviewEventArgs > OnPreview
Event raised when there is a new value to preview.
Definition: Variables.cs:383
Variables(params Variable[] Variables)
Collection of variables.
Definition: Variables.cs:41
Variable[] AvailableVariables
Returns an array of available variables.
Definition: Variables.cs:251
CancellationToken CancellationToken
Cancellation token, that can be used to monitor for script abortion.
Definition: Variables.cs:444
virtual bool TryGetVariable(string Name, out Variable Variable)
Tries to get a variable object, given its name.
Definition: Variables.cs:56
virtual bool Remove(string VariableName)
Removes a varaiable from the collection.
Definition: Variables.cs:151
void Abort()
Aborts the execution of script using this collection of variables.
Definition: Variables.cs:349
bool Active
If script is still active (i.e. has not been aborted).
Definition: Variables.cs:378
IEnumerator< Variable > GetEnumerator()
Returns an enumerator that iterates through a collection.
Definition: Variables.cs:275
Basic interface for all types of elements.
Definition: IElement.cs:21
Variables available in a specific context.
bool TryGetVariable(string Name, out Variable Variable)
Tries to get a variable object, given its name.
bool ContainsVariable(string Name)
If the collection contains a variable with a given name.
delegate Task< string > ValuePrinter(object Value, Variables Variables)
Converts a value to a printable string.