Client LuaCsForBarotrauma
LuaUserData.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using MoonSharp.Interpreter;
6 using MoonSharp.Interpreter.Interop;
7 
8 namespace Barotrauma
9 {
10  partial class LuaUserData
11  {
12  public static Type GetType(string typeName) => LuaCsSetup.GetType(typeName);
13 
14  public static IUserDataDescriptor RegisterType(string typeName)
15  {
16  Type type = GetType(typeName);
17 
18  if (type == null)
19  {
20  throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
21  }
22 
23  return UserData.RegisterType(type);
24  }
25 
26  public static bool IsRegistered(string typeName)
27  {
28  Type type = GetType(typeName);
29 
30  if (type == null)
31  {
32  return false;
33  }
34 
35  return UserData.GetDescriptorForType(type, true) != null;
36  }
37 
38  public static void UnregisterType(string typeName, bool deleteHistory = false)
39  {
40  Type type = GetType(typeName);
41 
42  if (type == null)
43  {
44  throw new ScriptRuntimeException($"tried to unregister a type that doesn't exist: {typeName}.");
45  }
46 
47  UserData.UnregisterType(type, deleteHistory);
48  }
49  public static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
50  {
51  Type type = GetType(typeName);
52  Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
53  Type genericType = type.MakeGenericType(typeArguements);
54  return UserData.RegisterType(genericType);
55  }
56 
57  public static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
58  {
59  Type type = GetType(typeName);
60  Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
61  Type genericType = type.MakeGenericType(typeArguements);
62  UserData.UnregisterType(genericType);
63  }
64 
65  public static bool IsTargetType(object obj, string typeName)
66  {
67  if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
68  Type targetType = GetType(typeName);
69  if (targetType == null) { throw new ScriptRuntimeException("target type not found"); }
70 
71  Type type = obj is Type ? (Type)obj : obj.GetType();
72  return targetType.IsAssignableFrom(type);
73  }
74 
75  public static string TypeOf(object obj)
76  {
77  if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
78 
79  return obj.GetType().FullName;
80  }
81 
82  public static object CreateStatic(string typeName)
83  {
84  Type type = GetType(typeName);
85 
86  if (type == null)
87  {
88  throw new ScriptRuntimeException($"tried to create a static userdata of a type that doesn't exist: {typeName}.");
89  }
90 
91  MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
92  MethodInfo generic = method.MakeGenericMethod(type);
93  return generic.Invoke(null, null);
94  }
95 
96  public static object CreateEnumTable(string typeName)
97  {
98  Type type = GetType(typeName);
99 
100  if (type == null)
101  {
102  throw new ScriptRuntimeException($"tried to create an enum table with a type that doesn't exist:: {typeName}.");
103  }
104 
105  Dictionary<string, object> result = new Dictionary<string, object>();
106 
107  foreach (var value in Enum.GetValues(type))
108  {
109  string name = Enum.GetName(type, value);
110 
111  result[name] = value;
112  }
113 
114  return result;
115  }
116 
117  private static FieldInfo FindFieldRecursively(Type type, string fieldName)
118  {
119  var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
120 
121  if (field == null && type.BaseType != null)
122  {
123  return FindFieldRecursively(type.BaseType, fieldName);
124  }
125 
126  return field;
127  }
128 
129  public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
130  {
131  if (IUUD == null)
132  {
133  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {fieldName} accessible.");
134  }
135 
136  var descriptor = (StandardUserDataDescriptor)IUUD;
137  FieldInfo field = FindFieldRecursively(IUUD.Type, fieldName);
138 
139  if (field == null)
140  {
141  throw new ScriptRuntimeException($"tried to make field '{fieldName}' accessible, but the field doesn't exist.");
142  }
143 
144  descriptor.RemoveMember(fieldName);
145  descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
146  }
147 
148  private static MethodInfo FindMethodRecursively(Type type, string methodName, Type[] types = null)
149  {
150  MethodInfo method;
151 
152  if (types == null)
153  {
154  method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
155  }
156  else
157  {
158  method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, types);
159  }
160 
161  if (method == null && type.BaseType != null)
162  {
163  return FindMethodRecursively(type.BaseType, methodName, types);
164  }
165 
166  return method;
167  }
168 
169  public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null)
170  {
171  if (IUUD == null)
172  {
173  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {methodName} accessible.");
174  }
175 
176  Type[] parameterTypes = null;
177 
178 
179  if (parameters != null)
180  {
181  parameterTypes = new Type[parameters.Length];
182 
183  for (int i = 0; i < parameters.Length; i++)
184  {
185  Type type = LuaUserData.GetType(parameters[i]);
186  if (type == null)
187  {
188  throw new ScriptRuntimeException($"invalid parameter type '{parameters[i]}'");
189  }
190  parameterTypes[i] = type;
191  }
192  }
193 
194  var descriptor = (StandardUserDataDescriptor)IUUD;
195 
196  MethodBase method;
197 
198  try
199  {
200  method = FindMethodRecursively(IUUD.Type, methodName, parameterTypes);
201  }
202  catch (AmbiguousMatchException ex)
203  {
204  throw new ScriptRuntimeException("ambiguous method signature.");
205  }
206 
207  if (method == null)
208  {
209  throw new ScriptRuntimeException($"tried to make method '{methodName}' accessible, but the method doesn't exist.");
210  }
211 
212  descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
213  }
214 
215  private static PropertyInfo FindPropertyRecursively(Type type, string propertyName)
216  {
217  var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
218 
219  if (property == null && type.BaseType != null)
220  {
221  return FindPropertyRecursively(type.BaseType, propertyName);
222  }
223 
224  return property;
225  }
226 
227  public static void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
228  {
229  if (IUUD == null)
230  {
231  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {propertyName} accessible.");
232  }
233 
234  var descriptor = (StandardUserDataDescriptor)IUUD;
235  PropertyInfo property = FindPropertyRecursively(IUUD.Type, propertyName);
236 
237  if (property == null)
238  {
239  throw new ScriptRuntimeException($"tried to make property '{propertyName}' accessible, but the property doesn't exist.");
240  }
241 
242  descriptor.RemoveMember(propertyName);
243  descriptor.AddMember(propertyName, new PropertyMemberDescriptor(property, InteropAccessMode.Default, property.GetGetMethod(true), property.GetSetMethod(true)));
244  }
245 
246  public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
247  {
248  if (IUUD == null)
249  {
250  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add method {methodName}.");
251  }
252 
253  var descriptor = (StandardUserDataDescriptor)IUUD;
254 
255  descriptor.RemoveMember(methodName);
256  descriptor.AddMember(methodName, new ObjectCallbackMemberDescriptor(methodName, (object arg1, ScriptExecutionContext arg2, CallbackArguments arg3) =>
257  {
258  if (GameMain.LuaCs != null)
259  return GameMain.LuaCs.CallLuaFunction(function, arg3.GetArray());
260  return null;
261  }));
262  }
263 
264  public static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
265  {
266  if (IUUD == null)
267  {
268  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add field {fieldName}.");
269  }
270 
271  var descriptor = (StandardUserDataDescriptor)IUUD;
272  descriptor.RemoveMember(fieldName);
273  descriptor.AddMember(fieldName, new DynValueMemberDescriptor(fieldName, value));
274  }
275 
276  public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
277  {
278  if (IUUD == null)
279  {
280  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to remove the member {memberName}.");
281  }
282 
283  var descriptor = (StandardUserDataDescriptor)IUUD;
284  descriptor.RemoveMember(memberName);
285  }
286 
287  public static bool HasMember(object obj, string memberName)
288  {
289  if (obj == null) { throw new ScriptRuntimeException("object is nil"); }
290 
291  Type type;
292  if (obj is Type)
293  {
294  type = (Type)obj;
295  }
296  else if(obj is IUserDataDescriptor descriptor)
297  {
298  type = descriptor.Type;
299 
300  if (((StandardUserDataDescriptor)descriptor).HasMember(memberName))
301  {
302  return true;
303  }
304  }
305  else
306  {
307  type = obj.GetType();
308  }
309 
310  if (type.GetMember(memberName).Length == 0)
311  {
312  return false;
313  }
314 
315  return true;
316  }
317 
318 
325  public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
326  {
327  return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
328  }
329 
344  public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
345  {
346  IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
347  descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
348  return CreateUserDataFromDescriptor(scriptObject, descriptor);
349  }
350  }
351 }
static LuaCsSetup LuaCs
Definition: GameMain.cs:26
static Type GetType(string typeName, bool throwOnError=false, bool ignoreCase=false)
DynValue CallLuaFunction(object function, params object[] args)
static void UnregisterType(string typeName, bool deleteHistory=false)
Definition: LuaUserData.cs:38
static bool IsRegistered(string typeName)
Definition: LuaUserData.cs:26
static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
Definition: LuaUserData.cs:264
static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
Definition: LuaUserData.cs:57
static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
Definition: LuaUserData.cs:246
static Type GetType(string typeName)
static object CreateEnumTable(string typeName)
Definition: LuaUserData.cs:96
static object CreateStatic(string typeName)
Definition: LuaUserData.cs:82
static bool IsTargetType(object obj, string typeName)
Definition: LuaUserData.cs:65
static void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
Definition: LuaUserData.cs:227
static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
See CreateUserDataFromType.
Definition: LuaUserData.cs:325
static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
Definition: LuaUserData.cs:129
static IUserDataDescriptor RegisterType(string typeName)
Definition: LuaUserData.cs:14
static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
Converts a Lua value to a CLR object of a desired type and wraps it in a userdata....
Definition: LuaUserData.cs:344
static bool HasMember(object obj, string memberName)
Definition: LuaUserData.cs:287
static string TypeOf(object obj)
Definition: LuaUserData.cs:75
static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters=null)
Definition: LuaUserData.cs:169
static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
Definition: LuaUserData.cs:276
static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
Definition: LuaUserData.cs:49