UserDataDescriptor.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using System.Threading;
  7. using MoonSharp.Interpreter.Execution;
  8. namespace MoonSharp.Interpreter.Interop
  9. {
  10. internal class UserDataDescriptor
  11. {
  12. internal string Name { get; private set; }
  13. internal Type Type { get; private set; }
  14. internal InteropAccessMode AccessMode { get; private set; }
  15. internal string FriendlyName { get; private set; }
  16. private Dictionary<string, UserDataMethodDescriptor> m_Methods = new Dictionary<string, UserDataMethodDescriptor>();
  17. private Dictionary<string, UserDataPropertyDescriptor> m_Properties = new Dictionary<string, UserDataPropertyDescriptor>();
  18. internal UserDataDescriptor(Type type, InteropAccessMode accessMode, string friendlyName)
  19. {
  20. Type = type;
  21. Name = type.FullName;
  22. AccessMode = accessMode;
  23. FriendlyName = friendlyName;
  24. if (AccessMode != InteropAccessMode.HideMembers)
  25. {
  26. foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static))
  27. {
  28. if (CheckVisibility(mi.GetCustomAttributes(true), mi.IsPublic))
  29. {
  30. if (mi.IsSpecialName)
  31. continue;
  32. var md = new UserDataMethodDescriptor(mi, this.AccessMode);
  33. if (m_Methods.ContainsKey(md.Name))
  34. throw new ArgumentException(string.Format("{0}.{1} has overloads", Name, md.Name));
  35. m_Methods.Add(md.Name, md);
  36. }
  37. }
  38. foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
  39. {
  40. if (CheckVisibility(pi.GetCustomAttributes(true), pi.GetGetMethod().IsPublic || pi.GetSetMethod().IsPublic))
  41. {
  42. var pd = new UserDataPropertyDescriptor(pi, this.AccessMode);
  43. m_Properties.Add(pd.Name, pd);
  44. }
  45. }
  46. }
  47. }
  48. private bool CheckVisibility(object[] attributes, bool isPublic)
  49. {
  50. MoonSharpVisibleAttribute va = attributes.OfType<MoonSharpVisibleAttribute>().SingleOrDefault();
  51. if (va != null)
  52. return va.Visible;
  53. else
  54. return isPublic;
  55. }
  56. internal DynValue Index(Script script, object obj, string idxname)
  57. {
  58. UserDataMethodDescriptor mdesc;
  59. if (m_Methods.TryGetValue(idxname, out mdesc))
  60. return DynValue.NewCallback(mdesc.GetCallback(script, obj));
  61. UserDataPropertyDescriptor pdesc;
  62. if (m_Properties.TryGetValue(idxname, out pdesc))
  63. {
  64. object o = pdesc.GetValue(obj);
  65. return ConversionHelper.ClrObjectToComplexMoonSharpValue(script, o);
  66. }
  67. throw ScriptRuntimeException.UserDataMissingField(this.Name, idxname);
  68. }
  69. internal void SetIndex(Script script, object obj, string idxname, DynValue value)
  70. {
  71. UserDataPropertyDescriptor pdesc;
  72. if (m_Properties.TryGetValue(idxname, out pdesc))
  73. {
  74. object o = ConversionHelper.MoonSharpValueToObjectOfType(value, pdesc.PropertyInfo.PropertyType, null);
  75. pdesc.SetValue(obj, o, value.Type);
  76. }
  77. else
  78. {
  79. throw ScriptRuntimeException.UserDataMissingField(this.Name, idxname);
  80. }
  81. }
  82. internal void Optimize()
  83. {
  84. foreach (var m in this.m_Methods.Values)
  85. m.Optimize();
  86. foreach (var m in this.m_Properties.Values)
  87. {
  88. m.OptimizeGetter();
  89. m.OptimizeSetter();
  90. }
  91. }
  92. }
  93. }