BadScript 2
Loading...
Searching...
No Matches
BadInteropExtensionProvider.cs
Go to the documentation of this file.
5
7
9{
13 private readonly List<Type> m_ActiveExtensions = new List<Type>();
14
18 private readonly Dictionary<string, Func<BadObject, BadObject>> m_GlobalExtensions =
19 new Dictionary<string, Func<BadObject, BadObject>>();
20
24 private readonly Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>> m_ObjectExtensions =
25 new Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>>();
26
30 private readonly Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>> m_StaticExtensionCache =
31 new Dictionary<Type, Dictionary<string, Func<BadObject, BadObject>>>();
32
33 private readonly Dictionary<Type, bool> m_SupportedTypes = new Dictionary<Type, bool>();
34
39
45 {
46 AddExtensions(extensions);
47 }
48
54 {
55 return m_GlobalExtensions.Keys.Select(x => (BadObject)x).ToArray();
56 }
57
64 {
65 Type t = obj.GetType();
66
67
68 List<BadObject> objs = new List<BadObject>(GetExtensionNames());
69
70 if (HasTypeExtensions(t))
71 {
72 objs.AddRange(GetTypeExtensions(t).Keys.Select(x => (BadObject)x));
73 }
74
75 if (obj is not IBadNative native)
76 {
77 return objs.ToArray();
78 }
79
80 t = native.Type;
81
82 if (HasTypeExtensions(t))
83 {
84 objs.AddRange(GetTypeExtensions(t).Keys.Select(x => (BadObject)x));
85 }
86
87 return objs.ToArray();
88 }
89
90 private bool InnerHasTypeExtensions(Type t)
91 {
92 bool r = m_ObjectExtensions.Any(x => x.Key.IsAssignableFrom(t));
93 m_SupportedTypes.Add(t, r);
94
95 return r;
96 }
97
103 private bool HasTypeExtensions(Type t)
104 {
105 return m_SupportedTypes.TryGetValue(t, out bool r) ? r : InnerHasTypeExtensions(t);
106 }
107
113 private bool HasGlobalExtensions(string propName)
114 {
115 return m_GlobalExtensions.ContainsKey(propName);
116 }
117
123 private Dictionary<string, Func<BadObject, BadObject>> GetTypeExtensions(Type type)
124 {
125 if (m_StaticExtensionCache.TryGetValue(type, out Dictionary<string, Func<BadObject, BadObject>>? extensions))
126 {
127 return extensions;
128 }
129
130 Dictionary<string, Func<BadObject, BadObject>>
131 exts = new Dictionary<string, Func<BadObject, BadObject>>();
132
133 foreach (KeyValuePair<Type, Dictionary<string, Func<BadObject, BadObject>>> kvp in m_ObjectExtensions.Where(
134 x => x.Key.IsAssignableFrom(type)
135 ))
136 {
137 foreach (KeyValuePair<string, Func<BadObject, BadObject>> keyValuePair in kvp.Value)
138 {
139 exts[keyValuePair.Key] = keyValuePair.Value;
140 }
141 }
142
143 if (BadNativeOptimizationSettings.Instance.UseStaticExtensionCaching)
144 {
145 m_StaticExtensionCache[type] = exts;
146 }
147
148 return exts;
149 }
150
156 public void RegisterGlobal(string propName, Func<BadObject, BadObject> func)
157 {
158 m_GlobalExtensions.Add(propName, func);
159 }
160
166 public void RegisterGlobal(string propName, BadObject obj)
167 {
168 RegisterGlobal(propName, _ => obj);
169 }
170
178 public void RegisterObject<T>(string propName, Func<T, BadObject> obj)
179 {
181 typeof(T),
182 propName,
183 o =>
184 {
185 return o switch
186 {
187 T t => obj(t),
188 BadNative<T> nT => obj(nT.Value),
189 _ => throw new BadRuntimeException("Cannot cast object to type " + typeof(T)),
190 };
191 }
192 );
193 }
194
202 public void RegisterObject(Type t, string propName, BadObject obj)
203 {
204 RegisterObject(t, propName, _ => obj);
205 }
206
214 public void RegisterObject(Type t, string propName, Func<BadObject, BadObject> obj)
215 {
216 if (m_ObjectExtensions.TryGetValue(t, out Dictionary<string, Func<BadObject, BadObject>>? extension))
217 {
218 extension[propName] = obj;
219 }
220 else
221 {
222 m_ObjectExtensions[t] = new Dictionary<string, Func<BadObject, BadObject>>
223 {
224 {
225 propName, obj
226 },
227 };
228 }
229 }
230
231
238 public bool HasObject(Type t, string propName)
239 {
240 return HasGlobalExtensions(propName) || HasTypeExtensions(t) && GetTypeExtensions(t).ContainsKey(propName);
241 }
242
249 public bool HasObject<T>(string propName)
250 {
251 return HasObject(typeof(T), propName);
252 }
253
263 Type t,
264 string propName,
265 BadObject instance,
266 BadScope? caller)
267 {
269 $"{t.Name}.{propName}",
270 () => GetObject(t, propName, instance, caller)
271 );
272 }
273
282 public BadObject GetObject(Type t, string propName, BadObject instance, BadScope? caller)
283 {
284 Dictionary<string, Func<BadObject, BadObject>> ext = GetTypeExtensions(t);
285
286 if (ext.ContainsKey(propName))
287 {
288 return ext[propName](instance);
289 }
290
291 if (HasGlobalExtensions(propName))
292 {
293 return m_GlobalExtensions[propName](instance);
294 }
295
296 throw BadRuntimeException.Create(caller, $"No property named {propName} for type {t.Name}");
297 }
298
299
308 public BadObject GetObject<T>(string propName, BadObject instance, BadScope? caller = null)
309 {
310 return GetObject(typeof(T), propName, instance, caller);
311 }
312
317 public void AddExtension<T>() where T : BadInteropExtension, new()
318 {
319 T t = new T();
320 Initialize(t);
321 }
322
327 public void AddExtensions(params BadInteropExtension[] extensions)
328 {
329 foreach (BadInteropExtension extension in extensions)
330 {
331 AddExtension(extension);
332 }
333 }
334
339 public void AddExtension(BadInteropExtension extension)
340 {
341 Initialize(extension);
342 }
343
349 {
350 if (m_ActiveExtensions.Contains(ext.GetType()))
351 {
352 return;
353 }
354
355 m_ActiveExtensions.Add(ext.GetType());
356 ext.InnerAddExtensions(this);
357 }
358}
Implements the Scope for the Script Engine.
Definition BadScope.cs:238
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.
void RegisterObject(Type t, string propName, BadObject obj)
Registers the specified extension for the specified type.
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.
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.
BadObject GetObject(Type t, string propName, BadObject instance, BadScope? caller)
Returns the specified extension.
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)
BadObject GetObject< T >(string propName, BadObject instance, BadScope? caller=null)
Returns the specified extension.
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< BadObject > getter, Action< BadObject, BadPropertyInfo?>? setter=null, Action? delete=null)
Creates a new Reference Object.
T Value
The Value of the Native Type.
Definition BadNative.cs:52
static T Instance
Returns the Instance of the Settings Provider.
Defines properties for Native Types.
Definition IBadNative.cs:7
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.