Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Attribute.cs
1using System;
2using System.Xml;
3using Waher.Script;
5using System.Threading.Tasks;
6
8{
13 public abstract class Attribute<T>
14 {
15 private T evaluatedValue = default;
16 private bool hasEvaluated = false;
17 private bool hasEvaluatedValue = false;
18 private readonly T presetValue;
19 private readonly bool hasPresetValue;
20 private readonly Expression expression;
21 private readonly string name;
22 private readonly Layout2DDocument document;
23
30 public Attribute(string AttributeName, T Value, Layout2DDocument Document)
31 {
32 this.name = AttributeName;
33 this.presetValue = Value;
34 this.hasPresetValue = true;
35 this.expression = null;
36 this.document = Document;
37 }
38
46 public Attribute(XmlElement E, string AttributeName, bool CanEmbedScript, Layout2DDocument Document)
47 {
48 this.name = AttributeName;
49 this.document = Document;
50
51 if (E.HasAttribute(this.name))
52 {
53 string Value = E.GetAttribute(this.name);
54
55 int c = Value.Length;
56
57 if (CanEmbedScript && c >= 2 && Value[0] == '{' && Value[c - 1] == '}')
58 {
59 try
60 {
61 Expression Exp = new Expression(Value.Substring(1, c - 2));
62
63 this.presetValue = default;
64 this.hasPresetValue = false;
65 this.expression = Exp;
66 Document.Dynamic = true;
67
68 return;
69 }
70 catch (Exception)
71 {
72 // Ignore
73 }
74 }
75
76 if (this.TryParse(Value, out T ParsedValue))
77 {
78 this.presetValue = ParsedValue;
79 this.hasPresetValue = true;
80 this.expression = null;
81 }
82 else
83 throw new LayoutSyntaxException("Invalid value of attribute " + this.name + ": " + Value);
84 }
85 else
86 {
87 this.presetValue = default;
88 this.expression = null;
89 this.hasPresetValue = false;
90 }
91 }
92
99 protected Attribute(string AttributeName, Expression Expression, Layout2DDocument Document)
100 {
101 this.name = AttributeName;
102 this.presetValue = default;
103 this.hasPresetValue = false;
104 this.expression = Expression;
105 this.document = Document;
106
107 if (!(this.expression is null))
108 this.document.Dynamic = true;
109 }
110
114 public string Name => this.name;
115
119 public T PresetValue => this.presetValue;
120
124 public Expression Expression => this.expression;
125
129 public bool HasPresetValue => this.hasPresetValue;
130
134 public bool HasExpression => !(this.expression is null);
135
139 public bool Undefined => !this.hasPresetValue && this.expression is null;
140
144 public bool Defined => this.hasPresetValue || !(this.expression is null);
145
149 public Layout2DDocument Document => this.document;
150
157 public abstract bool TryParse(string StringValue, out T Value);
158
165 public virtual bool TryConvert(object Result, out T Value)
166 {
167 if (Result is string s && this.TryParse(s, out Value))
168 return true;
169 else
170 {
171 Value = default;
172 return false;
173 }
174 }
175
181 public abstract string ToString(T Value);
182
187 public void Export(XmlWriter Output)
188 {
189 if (this.hasPresetValue)
190 Output.WriteAttributeString(this.name, this.ToString(this.presetValue));
191 else if (!(this.expression is null))
192 Output.WriteAttributeString(this.name, "{" + this.expression.Script + "}");
193 }
194
199 public void ExportState(XmlWriter Output)
200 {
201 if (this.hasPresetValue)
202 Output.WriteAttributeString(this.name, this.ToString(this.presetValue));
203 else if (this.hasEvaluatedValue)
204 Output.WriteAttributeString(this.name, this.ToString(this.evaluatedValue));
205 }
206
213 public async Task<T> EvaluateAsync(Variables Session, T DefaultValue)
214 {
215 if (this.hasPresetValue)
216 return this.presetValue;
217 else if (this.hasEvaluatedValue)
218 return this.evaluatedValue;
219 else if (this.hasEvaluated)
220 return DefaultValue;
221 else if (this.expression is null)
222 return DefaultValue;
223 else
224 {
225 try
226 {
227 object Value = await this.expression.EvaluateAsync(Session);
228 if (Value is T Eval || this.TryConvert(Value, out Eval))
229 {
230 this.evaluatedValue = Eval;
231 this.hasEvaluated = true;
232 this.hasEvaluatedValue = true;
233
234 return Eval;
235 }
236 else
237 {
238 this.hasEvaluated = true;
239 return DefaultValue;
240 }
241 }
242 catch (Exception)
243 {
244 this.hasEvaluated = true;
245 return DefaultValue;
246 }
247 }
248 }
249
256 public static async Task<EvaluationResult<T>> TryEvaluate(Attribute<T> Attribute, Variables Session)
257 {
258 if (Attribute is null)
260 else if (Attribute.hasPresetValue)
261 return new EvaluationResult<T>(Attribute.presetValue);
262 else if (Attribute.hasEvaluatedValue)
263 return new EvaluationResult<T>(Attribute.evaluatedValue);
264 else if (Attribute.hasEvaluated)
266 else if (!(Attribute.expression is null))
267 {
268 try
269 {
270 object Value = await Attribute.expression.EvaluateAsync(Session);
271 if (Value is T Eval || Attribute.TryConvert(Value, out Eval))
272 {
273 Attribute.evaluatedValue = Eval;
274 Attribute.hasEvaluated = true;
275 Attribute.hasEvaluatedValue = true;
276
277 return new EvaluationResult<T>(Eval);
278 }
279 else
280 {
281 Attribute.hasEvaluated = true;
283 }
284 }
285 catch (Exception)
286 {
287 Attribute.hasEvaluated = true;
289 }
290 }
291 else
293 }
294
296 public override string ToString()
297 {
298 if (this.hasPresetValue)
299 return this.presetValue?.ToString();
300 else if (this.hasEvaluatedValue)
301 return this.evaluatedValue?.ToString();
302 else if (this.hasEvaluated)
303 return "<Evaluation error>";
304 else if (!(this.expression is null))
305 return this.expression.Script;
306 else
307 return "<Not set>";
308 }
309
310 }
311}
Contains a 2D layout document.
Manages an attribute value or expression.
Definition: Attribute.cs:14
bool Undefined
If the attribute is undefined.
Definition: Attribute.cs:139
bool HasExpression
If the attribute is defined by an expression.
Definition: Attribute.cs:134
bool Defined
If the attribute is defined.
Definition: Attribute.cs:144
bool HasPresetValue
If the attribute has a preset value.
Definition: Attribute.cs:129
Layout2DDocument Document
Document hosting the attribute.
Definition: Attribute.cs:149
abstract string ToString(T Value)
Converts a value to a string.
Attribute(string AttributeName, Expression Expression, Layout2DDocument Document)
Defines an undefined attribute.
Definition: Attribute.cs:99
virtual bool TryConvert(object Result, out T Value)
Tries to convert script result to a value of type T .
Definition: Attribute.cs:165
async Task< T > EvaluateAsync(Variables Session, T DefaultValue)
Evaluate the attribute value.
Definition: Attribute.cs:213
void Export(XmlWriter Output)
Exports the attribute.
Definition: Attribute.cs:187
Attribute(string AttributeName, T Value, Layout2DDocument Document)
Manages an attribute value or expression.
Definition: Attribute.cs:30
void ExportState(XmlWriter Output)
Exports the state of the attribute.
Definition: Attribute.cs:199
T PresetValue
Preset Value of attribute.
Definition: Attribute.cs:119
abstract bool TryParse(string StringValue, out T Value)
Tries to parse a string value
static async Task< EvaluationResult< T > > TryEvaluate(Attribute< T > Attribute, Variables Session)
Tries to evaluate the attribute value.
Definition: Attribute.cs:256
Attribute(XmlElement E, string AttributeName, bool CanEmbedScript, Layout2DDocument Document)
Manages an attribute value or expression.
Definition: Attribute.cs:46
static readonly EvaluationResult< T > Empty
No result
Class managing a script expression.
Definition: Expression.cs:39
async Task< object > EvaluateAsync(Variables Variables)
Evaluates the expression, using the variables provided in the Variables collection....
Definition: Expression.cs:4275
Collection of variables.
Definition: Variables.cs:25