BadScript 2
Loading...
Searching...
No Matches
BadInteropExtensionProvider.cs
Go to the documentation of this file.
6
8
10{
14 private readonly List<Type> m_ActiveExtensions = new List<Type>();
15
19 private readonly Dictionary<string, Func<BadObject, BadObject>> m_GlobalExtensions =
20 new Dictionary<string, Func<BadObject, BadObject>>();
21
25 private readonly Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>> m_ObjectExtensions =
26 new Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>>();
27
31 private readonly Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>> m_StaticExtensionCache =
32 new Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>>();
33
34 private readonly Dictionary<Type, bool> m_SupportedTypes = new Dictionary<Type, bool>();
35
40
46 {
47 AddExtensions(extensions);
48 }
49
55 {
56 return m_GlobalExtensions.Keys.Select(x => (BadObject)x)
57 .ToArray();
58 }
59
66 {
67 Type t = obj.GetType();
68
69 List<BadObject> objs = new List<BadObject>(GetExtensionNames());
70
71 if (HasTypeExtensions(t))
72 {
73 objs.AddRange(GetTypeExtensions(t)
74 .Keys.Select(x => (BadObject)x)
75 );
76 }
77
78 if (obj is not IBadNative native)
79 {
80 return objs.ToArray();
81 }
82
83 t = native.Type;
84
85 if (HasTypeExtensions(t))
86 {
87 objs.AddRange(GetTypeExtensions(t)
88 .Keys.Select(x => (BadObject)x)
89 );
90 }
91
92 return objs.ToArray();
93 }
94
95
102 {
103 Type t = obj.GetType();
104
105 Dictionary<string, BadObject> objs = new Dictionary<string, BadObject>(m_GlobalExtensions.ToDictionary(x => x.Key, x => x.Value(obj)));
106
107 if (HasTypeExtensions(t))
108 {
109 foreach (KeyValuePair<string,Func<BadObject,BadObject>> kvp in GetTypeExtensions(t))
110 {
111 objs[kvp.Key] = kvp.Value(obj);
112 }
113 }
114
115 if (obj is not IBadNative native)
116 {
117 return new BadTable(objs.ToDictionary(x=>x.Key, x => x.Value));
118 }
119
120 t = native.Type;
121
122 if (HasTypeExtensions(t))
123 {
124 foreach (KeyValuePair<string,Func<BadObject,BadObject>> kvp in GetTypeExtensions(t))
125 {
126 objs[kvp.Key] = kvp.Value(obj);
127 }
128 }
129
130 return new BadTable(objs.ToDictionary(x=>x.Key, x => x.Value));
131 }
132
133 private bool InnerHasTypeExtensions(Type t)
134 {
135 bool r = m_ObjectExtensions.Any(x => x.Key.IsAssignableFrom(t));
136 m_SupportedTypes.Add(t, r);
137
138 return r;
139 }
140
146 private bool HasTypeExtensions(Type t)
147 {
148 return m_SupportedTypes.TryGetValue(t, out bool r) ? r : InnerHasTypeExtensions(t);
149 }
150
156 private bool HasGlobalExtensions(string propName)
157 {
158 return m_GlobalExtensions.ContainsKey(propName);
159 }
160
166 private Dictionary<string, Func<BadObject, BadObject>> GetTypeExtensions(Type type)
167 {
168 if (m_StaticExtensionCache.TryGetValue(type, out Dictionary<string, Func<BadObject, BadObject>>? extensions))
169 {
170 return extensions;
171 }
172
173 Dictionary<string, Func<BadObject, BadObject>>
174 exts = new Dictionary<string, Func<BadObject, BadObject>>();
175
176 foreach (KeyValuePair<Type, Dictionary<string, Func<BadObject, BadObject>>> kvp in
177 m_ObjectExtensions.Where(x => x.Key.IsAssignableFrom(type)))
178 {
179 foreach (KeyValuePair<string, Func<BadObject, BadObject>> keyValuePair in kvp.Value)
180 {
181 exts[keyValuePair.Key] = keyValuePair.Value;
182 }
183 }
184
185 if (BadNativeOptimizationSettings.Instance.UseStaticExtensionCaching)
186 {
187 m_StaticExtensionCache[type] = exts;
188 }
189
190 return exts;
191 }
192
198 public void RegisterGlobal(string propName, Func<BadObject, BadObject> func)
199 {
200 m_GlobalExtensions.Add(propName, func);
201 }
202
208 public void RegisterGlobal(string propName, BadObject obj)
209 {
210 RegisterGlobal(propName, _ => obj);
211 }
212
220 public void RegisterObject<T>(string propName, Func<T, BadObject> obj)
221 {
222 RegisterObject(typeof(T),
223 propName,
224 o =>
225 {
226 return o switch
227 {
228 T t => obj(t),
229 BadNative<T> nT => obj(nT.Value),
230 _ => throw new BadRuntimeException("Cannot cast object to type " + typeof(T)),
231 };
232 }
233 );
234 }
235
243 public void RegisterObject(Type t, string propName, BadObject obj)
244 {
245 RegisterObject(t, propName, _ => obj);
246 }
247
255 public void RegisterObject(Type t, string propName, Func<BadObject, BadObject> obj)
256 {
257 if (m_ObjectExtensions.TryGetValue(t, out Dictionary<string, Func<BadObject, BadObject>>? extension))
258 {
259 extension[propName] = obj;
260 }
261 else
262 {
263 m_ObjectExtensions[t] = new Dictionary<string, Func<BadObject, BadObject>> { { propName, obj } };
264 }
265 }
266
267
274 public bool HasObject(Type t, string propName)
275 {
276 return HasGlobalExtensions(propName) ||
277 (HasTypeExtensions(t) &&
279 .ContainsKey(propName));
280 }
281
288 public bool HasObject<T>(string propName)
289 {
290 return HasObject(typeof(T), propName);
291 }
292
302 string propName,
303 BadObject instance,
304 BadScope? caller)
305 {
306 return BadObjectReference.Make($"{t.Name}.{propName}",
307 (p) => GetObject(t, propName, instance, caller, p)
308 );
309 }
310
319 public BadObject GetObject(Type t, string propName, BadObject instance, BadScope? caller, BadSourcePosition? pos)
320 {
321 Dictionary<string, Func<BadObject, BadObject>> ext = GetTypeExtensions(t);
322
323 if (ext.ContainsKey(propName))
324 {
325 return ext[propName](instance);
326 }
327
328 if (HasGlobalExtensions(propName))
329 {
330 return m_GlobalExtensions[propName](instance);
331 }
332
333 throw BadRuntimeException.Create(caller, $"No property named {propName} for type {t.Name}", pos);
334 }
335
336
345 public BadObject GetObject<T>(string propName, BadObject instance, BadScope? caller = null, BadSourcePosition? pos = null)
346 {
347 return GetObject(typeof(T), propName, instance, caller, pos);
348 }
349
354 public void AddExtension<T>() where T : BadInteropExtension, new()
355 {
356 T t = new T();
357 Initialize(t);
358 }
359
364 public void AddExtensions(params BadInteropExtension[] extensions)
365 {
366 foreach (BadInteropExtension extension in extensions)
367 {
368 AddExtension(extension);
369 }
370 }
371
376 public void AddExtension(BadInteropExtension extension)
377 {
378 Initialize(extension);
379 }
380
386 {
387 if (m_ActiveExtensions.Contains(ext.GetType()))
388 {
389 return;
390 }
391
392 m_ActiveExtensions.Add(ext.GetType());
393 ext.InnerAddExtensions(this);
394 }
395}
Describes a specific position inside a source file.
Implements the Scope for the Script Engine.
Definition BadScope.cs:16
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
Public Extension API for the BS2 Runtime.
void InnerAddExtensions(BadInteropExtensionProvider provider)
Adds the Extensions to the given Provider.
void RegisterObject(Type t, string propName, Func< BadObject, BadObject > obj)
Registers the specified extension for the specified type.
readonly List< Type > m_ActiveExtensions
List of all active extensions.
BadObject GetObject(Type t, string propName, BadObject instance, BadScope? caller, BadSourcePosition? pos)
Returns the specified extension.
void RegisterObject(Type t, string propName, BadObject obj)
Registers the specified extension for the specified type.
BadTable GetExtensions(BadObject obj)
Returns all Extension Names for the specified object.
void RegisterGlobal(string propName, Func< BadObject, BadObject > func)
Registers the specified extension for all objects.
BadInteropExtensionProvider()
Creates a new BadInteropExtensionProvider.
bool HasObject< T >(string propName)
Returns True if the specified type has the specified extension.
readonly Dictionary< Type, Dictionary< string, Func< BadObject, BadObject > > > m_StaticExtensionCache
Cache for already built extension tables.
BadObjectReference GetObjectReference(Type t, string propName, BadObject instance, BadScope? caller)
Returns a reference to the specified extension.
void RegisterObject< T >(string propName, Func< T, BadObject > obj)
Registers the specified extension for the specified type.
BadObject[] GetExtensionNames(BadObject obj)
Returns all Extension Names for the specified object.
void AddExtension(BadInteropExtension extension)
Adds the specified extension to the list of registered extensions.
Dictionary< string, Func< BadObject, BadObject > > GetTypeExtensions(Type type)
Returns all type extensions for the specified type.
bool HasGlobalExtensions(string propName)
Returns true if a global extension with the specified name is available.
void AddExtensions(params BadInteropExtension[] extensions)
Adds the specified extensions to the list of registered extensions.
BadObject GetObject< T >(string propName, BadObject instance, BadScope? caller=null, BadSourcePosition? pos=null)
Returns the specified extension.
void RegisterGlobal(string propName, BadObject obj)
Registers the specified extension for all objects.
readonly Dictionary< Type, Dictionary< string, Func< BadObject, BadObject > > > m_ObjectExtensions
Object Extensions that are available for objects of the specified type.
void AddExtension< T >()
Adds an Extension Class to the List of registered extensions.
BadInteropExtensionProvider(BadInteropExtension[] extensions)
Creates a new BadInteropExtensionProvider.
bool HasObject(Type t, string propName)
Returns True if the specified type has the specified extension.
BadObject[] GetExtensionNames()
Returns all Global Extension names.
bool HasTypeExtensions(Type t)
Returns true if any extensions are available for the specified object(excluding global extensions)
readonly Dictionary< string, Func< BadObject, BadObject > > m_GlobalExtensions
Global extensions that are available for all objects in the runtime.
void Initialize(BadInteropExtension ext)
Initializes the extension.
The Base Class for all BadScript Objects.
Definition BadObject.cs:14
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.
Implements a Table Structure for the BadScript Language.
Definition BadTable.cs:14
T Value
The Value of the Native Type.
Definition BadNative.cs:51
static T Instance
Returns the Instance of the Settings Provider.
Defines properties for Native Types.
Definition IBadNative.cs:7
Contains Shared Data Structures and Functionality.
Contains the Error Objects for the BadScript2 Language.
Contains the Interop Abstractions and Implementations for the BadScript2 Language.
Contains the Native Runtime Objects.
Definition BadBoolean.cs:6
Contains the Runtime Objects.
Definition BadArray.cs:10
Contains Runtime Settings Objects.