ModuleRegister.cs 5.7 KB

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