ModuleRegister.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using MoonSharp.Interpreter.CoreLib;
  7. using MoonSharp.Interpreter.Execution;
  8. namespace MoonSharp.Interpreter
  9. {
  10. public static class ModuleRegister
  11. {
  12. public static Table RegisterCoreModules(this Table table, CoreModules modules)
  13. {
  14. if (modules.Has(CoreModules.GlobalConsts)) RegisterConstants(table);
  15. if (modules.Has(CoreModules.TableIterators)) RegisterModuleType<TableIterators>(table);
  16. if (modules.Has(CoreModules.Basic)) RegisterModuleType<BasicMethods>(table);
  17. if (modules.Has(CoreModules.Metatables)) RegisterModuleType<MetaTableMethods>(table);
  18. if (modules.Has(CoreModules.String)) RegisterModuleType<StringModule>(table);
  19. if (modules.Has(CoreModules.LoadMethods)) RegisterModuleType<LoadMethods>(table);
  20. if (modules.Has(CoreModules.Table)) RegisterModuleType<TableModule>(table);
  21. if (modules.Has(CoreModules.Table)) RegisterModuleType<TableModule_Globals>(table);
  22. if (modules.Has(CoreModules.ErrorHandling)) RegisterModuleType<ErrorHandling>(table);
  23. return table;
  24. }
  25. public static Table RegisterConstants(this Table table)
  26. {
  27. table["_G"] = DynValue.NewTable(table);
  28. table["_VERSION"] = DynValue.NewString(string.Format("Moon# {0}",
  29. Assembly.GetExecutingAssembly().GetName().Version.Major,
  30. Assembly.GetExecutingAssembly().GetName().Version.Minor));
  31. table["_MOONSHARP"] = DynValue.NewString(Assembly.GetExecutingAssembly().GetName().Version.ToString());
  32. return table;
  33. }
  34. public static Table RegisterModuleType(this Table gtable, Type t)
  35. {
  36. Table table = CreateModuleNamespace(gtable, t);
  37. foreach (MethodInfo mi in t.GetMethods(BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic).Where(_mi => _mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).Length > 0))
  38. {
  39. MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
  40. ParameterInfo[] pi = mi.GetParameters();
  41. if (pi.Length != 2 || pi[0].ParameterType != typeof(ScriptExecutionContext)
  42. || pi[1].ParameterType != typeof(CallbackArguments) || mi.ReturnType != typeof(DynValue))
  43. {
  44. throw new ArgumentException(string.Format("Method {0} does not have the right signature.", mi.Name));
  45. }
  46. Func<ScriptExecutionContext, CallbackArguments, DynValue> func = (Func<ScriptExecutionContext, CallbackArguments, DynValue>)Delegate.CreateDelegate(typeof(Func<ScriptExecutionContext, CallbackArguments, DynValue>), mi);
  47. string name = (!string.IsNullOrEmpty(attr.Name)) ? attr.Name : mi.Name;
  48. table[name] = DynValue.NewCallback(func);
  49. }
  50. foreach (FieldInfo fi in t.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic).Where(_mi => _mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).Length > 0))
  51. {
  52. MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)fi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
  53. string name = (!string.IsNullOrEmpty(attr.Name)) ? attr.Name : fi.Name;
  54. RegisterScriptField(fi, null, table, t, name);
  55. }
  56. return gtable;
  57. }
  58. private static void RegisterScriptField(FieldInfo fi, object o, Table table, Type t, string name)
  59. {
  60. if (fi.FieldType != typeof(string))
  61. {
  62. throw new ArgumentException(string.Format("Field {0} does not have the right type - it must be string.", name));
  63. }
  64. string val = fi.GetValue(o) as string;
  65. DynValue fn = table.OwnerScript.LoadFunction(val, null, name);
  66. table[name] = fn;
  67. }
  68. private static Table CreateModuleNamespace(Table gtable, Type t)
  69. {
  70. MoonSharpModuleAttribute attr = (MoonSharpModuleAttribute)t.GetCustomAttributes(typeof(MoonSharpModuleAttribute), false).First();
  71. if (string.IsNullOrEmpty(attr.Namespace))
  72. {
  73. return gtable;
  74. }
  75. else
  76. {
  77. Table table = new Table(gtable.OwnerScript);
  78. gtable[attr.Namespace] = DynValue.NewTable(table);
  79. DynValue package = gtable.RawGet("package");
  80. if (package == null || package.Type != DataType.Table)
  81. {
  82. gtable["package"] = package = DynValue.NewTable(gtable.OwnerScript);
  83. }
  84. DynValue loaded = package.Table.RawGet("loaded");
  85. if (loaded == null || loaded.Type != DataType.Table)
  86. {
  87. package.Table["loaded"] = loaded = DynValue.NewTable(gtable.OwnerScript);
  88. }
  89. loaded.Table[attr.Namespace] = DynValue.NewTable(table);
  90. return table;
  91. }
  92. }
  93. public static Table RegisterModuleType<T>(this Table table)
  94. {
  95. return RegisterModuleType(table, typeof(T));
  96. }
  97. public static Table RegisterModuleObject(this Table gtable, object o)
  98. {
  99. Type t = o.GetType();
  100. Table table = CreateModuleNamespace(gtable, t);
  101. foreach (MethodInfo mi in t.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic).Where(_mi => _mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).Length > 0))
  102. {
  103. MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
  104. ParameterInfo[] pi = mi.GetParameters();
  105. if (pi.Length != 2 || pi[0].ParameterType != typeof(ScriptExecutionContext)
  106. || pi[1].ParameterType != typeof(CallbackArguments) || mi.ReturnType != typeof(DynValue))
  107. {
  108. throw new ArgumentException(string.Format("Method {0} does not have the right signature.", mi.Name));
  109. }
  110. Func<ScriptExecutionContext, CallbackArguments, DynValue> func = (Func<ScriptExecutionContext, CallbackArguments, DynValue>)
  111. Delegate.CreateDelegate(typeof(Func<ScriptExecutionContext, CallbackArguments, DynValue>), o, mi);
  112. string name = (!string.IsNullOrEmpty(attr.Name)) ? attr.Name : mi.Name;
  113. table[name] = DynValue.NewCallback(func);
  114. }
  115. foreach (FieldInfo fi in t.GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic).Where(_mi => _mi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).Length > 0))
  116. {
  117. MoonSharpMethodAttribute attr = (MoonSharpMethodAttribute)fi.GetCustomAttributes(typeof(MoonSharpMethodAttribute), false).First();
  118. string name = (!string.IsNullOrEmpty(attr.Name)) ? attr.Name : fi.Name;
  119. RegisterScriptField(fi, o, table, t, name);
  120. }
  121. return gtable;
  122. }
  123. }
  124. }