BadScript 2
Loading...
Searching...
No Matches
BadTable.cs
Go to the documentation of this file.
1using System.Collections;
2using System.Text;
3
7
9
14{
19
20 private readonly Dictionary<string, BadObjectReference> m_ReferenceCache =
21 new Dictionary<string, BadObjectReference>();
22
23 private Func<string, BadObject, BadObject, bool>? m_OnChangeProperty;
24
28 public BadTable()
29 {
30 InnerTable = new Dictionary<string, BadObject>();
31 PropertyInfos = new Dictionary<string, BadPropertyInfo>();
32 }
33
38 public BadTable(Dictionary<string, BadObject> table)
39 {
40 InnerTable = table;
41 PropertyInfos = new Dictionary<string, BadPropertyInfo>();
42
43 foreach (KeyValuePair<string, BadObject> kvp in InnerTable)
44 {
46 }
47 }
48
50
54 public Dictionary<string, BadObject> InnerTable { get; }
55
59 public Dictionary<string, BadPropertyInfo> PropertyInfos { get; }
60
61#region IBadEnumerable Members
62
67 public IEnumerator<BadObject> GetEnumerator()
68 {
69 return InnerTable
70 .Select(kvp => new BadTable(new Dictionary<string, BadObject>
71 {
72 { "Key", kvp.Key }, { "Value", kvp.Value },
73 }
74 )
75 )
76 .Cast<BadObject>()
78 }
79
84 IEnumerator IEnumerable.GetEnumerator()
85 {
86 return GetEnumerator();
87 }
88
89#endregion
90
91 public event Action<string, BadObject, BadObject> OnChangedProperty = delegate { };
92
93 public void SetChangeInterceptor(Func<string, BadObject, BadObject, bool>? interceptor)
94 {
95 m_OnChangeProperty = interceptor;
96 }
97
98
101 {
102 return Prototype;
103 }
104
110 public BadPropertyInfo GetPropertyInfo(string propName)
111 {
112 return PropertyInfos[propName];
113 }
114
119 public bool RemoveKey(string key)
120 {
121 PropertyInfos.Remove(key);
122
123 return InnerTable.Remove(key);
124 }
125
126
128 public override bool HasProperty(string propName, BadScope? caller = null)
129 {
130 return InnerTable.ContainsKey(propName) || (caller != null && caller.Provider.HasObject<BadTable>(propName));
131 }
132
133
141 public BadObjectReference GetProperty(string propName, bool useExtensions, BadScope? caller = null)
142 {
143 return !useExtensions ? GetLocalReference(propName) : GetProperty(propName, caller);
144 }
145
146 private bool OnChangePropertyInternal(string propName, BadObject oldValue, BadObject newValue)
147 {
148 if (m_OnChangeProperty != null)
149 {
150 return m_OnChangeProperty(propName, oldValue, newValue);
151 }
152
153 return false;
154 }
155
161 private BadObjectReference GetLocalReference(string propName)
162 {
163 if (m_ReferenceCache.TryGetValue(propName, out BadObjectReference reference))
164 {
165 return reference;
166 }
167
168 BadObjectReference r = BadObjectReference.Make($"BadTable.{propName}",
169 (p) =>
170 {
171 if (InnerTable.TryGetValue(propName, out var result))
172 {
173 return result;
174 }
175 throw BadRuntimeException.Create(null, $"Property '{propName}' not found", p);
176 },
177 (o, p, t, noChange) =>
178 {
179 if (InnerTable.TryGetValue(propName,
180 out BadObject? propValue
181 ))
182 {
183 BadPropertyInfo info = GetPropertyInfo(propName);
184
185 if (propValue != Null && info.IsReadOnly)
186 {
187 throw
188 BadRuntimeException.Create(null,$"{propName} is read-only", p);
189 }
190
191 if (info.Type != null && !info.Type.IsAssignableFrom(o))
192 {
193 throw BadRuntimeException.Create(null,$"Cannot assign object {o.GetType().Name} to property '{propName}' of type '{info.Type.Name}'", p);
194 }
195
196 if (propValue is BadObjectReference propRef)
197 {
198 BadObject? oldValueRef = propRef.Dereference(p);
199
200 if (OnChangePropertyInternal(propName,
201 oldValueRef,
202 o
203 ))
204 {
205 return;
206 }
207
208 propRef.Set(o, p, t);
209
210 if (!noChange)
211 {
212 OnChangedProperty(propName, oldValueRef, o);
213 }
214
215 return;
216 }
217 }
218 else
219 {
220 PropertyInfos[propName] =
222
223 if (t?.Type != null && !t.Type.IsAssignableFrom(o))
224 {
225 throw BadRuntimeException.Create(null,$"Cannot assign object {o.GetType().Name} to property '{propName}' of type '{t.Type.Name}'", p);
226 }
227 }
228
229 if (OnChangePropertyInternal(propName, propValue ?? Null, o))
230 {
231 return;
232 }
233
234 InnerTable[propName] = o;
235
236 if (!noChange)
237 {
238 OnChangedProperty(propName, propValue ?? Null, o);
239 }
240 },
241 (p) => { InnerTable.Remove(propName); }
242 );
243
244 m_ReferenceCache[propName] = r;
245
246 return r;
247 }
248
250 public override BadObjectReference GetProperty(string propName, BadScope? caller = null)
251 {
252 if (!InnerTable.ContainsKey(propName) && caller != null && caller.Provider.HasObject<BadTable>(propName))
253 {
254 return caller.Provider.GetObjectReference(GetType(), propName, this, caller);
255 }
256
257 return GetLocalReference(propName);
258 }
259
260
262 public override string ToSafeString(List<BadObject> done)
263 {
264 done.Add(this);
265 StringBuilder sb = new StringBuilder();
266 sb.Append("{");
267 sb.AppendLine();
268
269 foreach (KeyValuePair<string, BadObject> kvp in InnerTable)
270 {
271 if (kvp.Value is BadScope)
272 {
273 sb.AppendLine("RECURSION_PROTECT");
274
275 continue;
276 }
277
278 string kStr = kvp.Key;
279
280 string vStr = "{...}";
281
282 if (!done.Contains(kvp.Value))
283 {
284 vStr = kvp.Value.ToSafeString(done)
285 .Trim();
286 }
287
288 if (kStr.Contains("\n"))
289 {
290 kStr = kStr.Replace("\n", "\n\t");
291 }
292
293 if (vStr.Contains("\n"))
294 {
295 vStr = vStr.Replace("\n", "\n\t");
296 }
297
298 sb.AppendLine($"\t{kStr}: {vStr}");
299 }
300
301 sb.AppendLine("}");
302
303 return sb.ToString();
304 }
305}
Implements the Scope for the Script Engine.
Definition BadScope.cs:16
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
The Base Class for all BadScript Objects.
Definition BadObject.cs:14
static readonly BadObject Null
The Null Value for the BadScript Language.
Definition BadObject.cs:28
Implements the base functionality for a BadScript Reference.
static BadObjectReference Make(string refText, Func< BadSourcePosition?, BadObject > getter, Action< BadObject, BadSourcePosition?, BadPropertyInfo?>? setter=null, Action< BadSourcePosition?>? delete=null)
Creates a new Reference Object.
Stores Meta Information about a Property.
bool IsReadOnly
Indicates if this property is read only.
BadClassPrototype? Type
The (optional) Type used for typechecking if a value gets assigned to this property.
Implements a Table Structure for the BadScript Language.
Definition BadTable.cs:14
BadObjectReference GetProperty(string propName, bool useExtensions, BadScope? caller=null)
Returns a Reference to the Property with the given Name.
Definition BadTable.cs:141
override BadClassPrototype GetPrototype()
Definition BadTable.cs:100
bool OnChangePropertyInternal(string propName, BadObject oldValue, BadObject newValue)
Definition BadTable.cs:146
Func< string, BadObject, BadObject, bool >? m_OnChangeProperty
Definition BadTable.cs:23
static ? BadClassPrototype s_Prototype
The Prototype for the BadScript Table.
Definition BadTable.cs:18
Action< string, BadObject, BadObject > OnChangedProperty
Definition BadTable.cs:91
readonly Dictionary< string, BadObjectReference > m_ReferenceCache
Definition BadTable.cs:20
BadTable(Dictionary< string, BadObject > table)
Creates a new Table Object.
Definition BadTable.cs:38
override string ToSafeString(List< BadObject > done)
Definition BadTable.cs:262
void SetChangeInterceptor(Func< string, BadObject, BadObject, bool >? interceptor)
Definition BadTable.cs:93
Dictionary< string, BadPropertyInfo > PropertyInfos
A Table of additional property information.
Definition BadTable.cs:59
BadTable()
Creates a new Table Object.
Definition BadTable.cs:28
BadObjectReference GetLocalReference(string propName)
Returns a Reference to a Local Property with the given Name.
Definition BadTable.cs:161
static BadClassPrototype Prototype
Definition BadTable.cs:49
IEnumerator< BadObject > GetEnumerator()
Returns the Enumerator for this Table.
Definition BadTable.cs:67
Dictionary< string, BadObject > InnerTable
The Inner Table for this Object.
Definition BadTable.cs:54
bool RemoveKey(string key)
Removes a Property from the Table.
Definition BadTable.cs:119
override bool HasProperty(string propName, BadScope? caller=null)
Returns true if the object contains a given property or there exists an extension for the current Ins...
Definition BadTable.cs:128
BadPropertyInfo GetPropertyInfo(string propName)
Returns Property Information for a given Key.
Definition BadTable.cs:110
override BadObjectReference GetProperty(string propName, BadScope? caller=null)
Returns a Reference to the Property with the given Name.The Property Reference
Definition BadTable.cs:250
The Any Prototype, Base type for all types.
static readonly BadAnyPrototype Instance
The Instance of the BadAnyPrototype.
Implements a Class Prototype for the BadScript Language.
virtual bool IsAssignableFrom(BadObject obj)
Returns true if the provided object is an instance of this class or a subclass of this class.
Helper Class that Builds a Native Class from a Prototype.
static BadClassPrototype GetNative(string name)
Returns a Native Class Prototype for the given Native Type.
Defines a BadScript Enumerable.
Contains the Error Objects for the BadScript2 Language.
Contains the Interop Abstractions and Implementations for the BadScript2 Language.
Contains the Runtime Objects.
Definition BadArray.cs:10