private static IntPtr luaMethodRoute(int nativeContextId, string methodName, IntPtr arguments, int size) { if (_contexts.ContainsKey(nativeContextId)) { LuaContext context = _contexts [nativeContextId].Target as LuaContext; if (context != null) { return(context.luaMethodHandler(methodName, arguments, size)); } } return(IntPtr.Zero); }
/// <summary> /// 注册模块 /// </summary> /// <param name="context">Lua上下文.</param> /// <param name="moduleName">模块名称.</param> /// <param name="t">类型.</param> protected static void _register(LuaContext context, string moduleName, Type t) { //初始化模块导出信息 Dictionary <string, MethodInfo> exportMethods = new Dictionary <string, MethodInfo> (); List <string> exportMethodNames = new List <string> (); MethodInfo[] methods = t.GetMethods(); foreach (MethodInfo m in methods) { if (m.IsStatic && m.IsPublic) { //静态和公开的方法会导出到Lua exportMethodNames.Add(m.Name); exportMethods.Add(m.Name, m); } } IntPtr exportMethodNamesPtr = IntPtr.Zero; if (exportMethodNames.Count > 0) { LuaObjectEncoder encoder = new LuaObjectEncoder(); encoder.writeInt32(exportMethodNames.Count); foreach (string name in exportMethodNames) { encoder.writeString(name); } byte[] bytes = encoder.bytes; exportMethodNamesPtr = Marshal.AllocHGlobal(bytes.Length); Marshal.Copy(bytes, 0, exportMethodNamesPtr, bytes.Length); } if (_moduleMethodHandleDelegate == null) { _moduleMethodHandleDelegate = new LuaModuleMethodHandleDelegate(luaModuleMethodRoute); } IntPtr fp = Marshal.GetFunctionPointerForDelegate(_moduleMethodHandleDelegate); //注册模块 int moduleId = NativeUtils.registerModule(context.objectId, moduleName, exportMethodNamesPtr, fp); //关联注册模块的注册方法 _exportsModuleMethods.Add(moduleId, exportMethods); if (exportMethodNamesPtr != IntPtr.Zero) { Marshal.FreeHGlobal(exportMethodNamesPtr); } }
private static Int64 _createInstance(int contextId, int nativeClassId, IntPtr argumentsBuffer, int bufferSize) { Int64 refId = -1; if (_exportsClass.ContainsKey(nativeClassId)) { Type t = _exportsClass [nativeClassId]; if (t != null) { LuaContext context = LuaContext.getContext(contextId); List <LuaValue> arguments = getArgumentList(context, argumentsBuffer, bufferSize); ConstructorInfo ci = getConstructor(t, t, arguments); if (ci != null) { ArrayList argsArr = new ArrayList(); ParameterInfo[] parameters = ci.GetParameters(); if (parameters.Length > 0 && arguments != null) { int i = 0; foreach (ParameterInfo p in parameters) { if (i >= arguments.Count) { break; } object value = getNativeValueForLuaValue(p.ParameterType, arguments[i]); argsArr.Add(value); i++; } } object instance = ci.Invoke(argsArr.ToArray()); if (instance != null) { LuaObjectReference objRef = new LuaObjectReference(instance); //添加引用避免被GC进行回收 _instances.Add(objRef); refId = objRef.referenceId; } } } } return(refId); }
/// <summary> /// 注册模块 /// </summary> internal static void register(LuaContext context, Type t) { string moduleName = LuaModule.moduleName(t); if (context.isModuleRegisted(moduleName)) { return; } MethodInfo m = t.GetMethod("_register", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); if (m != null) { m.Invoke(null, new object[] { context, moduleName, t }); } }
private static IntPtr _fieldGetter(int contextId, int classId, Int64 instancePtr, string fieldName) { IntPtr retValuePtr = IntPtr.Zero; if (instancePtr != 0) { LuaContext context = LuaContext.getContext(contextId); LuaObjectReference objRef = LuaObjectReference.findObject(instancePtr); object instance = objRef.target; LuaValue value = null; if (_exportsProperties.ContainsKey(classId) && _exportsProperties [classId].ContainsKey(fieldName)) { PropertyInfo propertyInfo = _exportsProperties [classId] [fieldName]; if (instance != null && propertyInfo != null && propertyInfo.CanRead) { object retValue = propertyInfo.GetValue(instance, null); value = new LuaValue(retValue); } } else if (_exportsFields.ContainsKey(classId) && _exportsFields [classId].ContainsKey(fieldName)) { FieldInfo fieldInfo = _exportsFields [classId] [fieldName]; if (instance != null && fieldInfo != null) { object retValue = fieldInfo.GetValue(instance); value = new LuaValue(retValue); } } if (value != null) { LuaObjectEncoder encoder = new LuaObjectEncoder(context); encoder.writeObject(value); byte[] bytes = encoder.bytes; retValuePtr = Marshal.AllocHGlobal(bytes.Length); Marshal.Copy(bytes, 0, retValuePtr, bytes.Length); } } return(retValuePtr); }
private static void _fieldSetter(int contextId, int classId, Int64 instancePtr, string fieldName, IntPtr valueBuffer, int bufferSize) { if (instancePtr != 0 && _exportsFields.ContainsKey(classId) && _exportsFields[classId].ContainsKey(fieldName)) { LuaContext context = LuaContext.getContext(contextId); LuaObjectReference objRef = LuaObjectReference.findObject(instancePtr); object instance = objRef.target; PropertyInfo propertyInfo = _exportsFields[classId][fieldName]; if (instance != null && propertyInfo != null && propertyInfo.CanWrite) { LuaObjectDecoder decoder = new LuaObjectDecoder(valueBuffer, bufferSize, context); LuaValue value = decoder.readObject() as LuaValue; propertyInfo.SetValue(instance, getNativeValueForLuaValue(propertyInfo.PropertyType, value), null); } } }
/// <summary> /// 从原生编码对象中获取参数列表 /// </summary> /// <returns>参数列表.</returns> /// <param name="context">上下文</param> /// <param name="arguments">参数缓存.</param> /// <param name="size">缓存长度.</param> protected static List <LuaValue> getArgumentList(LuaContext context, IntPtr arguments, int size) { List <LuaValue> argumentsList = null; if (arguments != IntPtr.Zero) { //反序列化参数列表 LuaObjectDecoder decoder = new LuaObjectDecoder(arguments, size, context); int argSize = decoder.readInt32(); argumentsList = new List <LuaValue> (); for (int i = 0; i < argSize; i++) { LuaValue value = decoder.readObject() as LuaValue; argumentsList.Add(value); } } return(argumentsList); }
/// <summary> /// 解析方法的参数列表 /// </summary> /// <returns>参数列表</returns> /// <param name="context">上下文对象</param> /// <param name="m">方法信息</param> /// <param name="arguments">参数列表数据</param> /// <param name="size">参数列表数据长度</param> protected static ArrayList parseMethodParameters(LuaContext context, MethodInfo m, IntPtr arguments, int size) { List <LuaValue> argumentsList = null; if (arguments != IntPtr.Zero) { //反序列化参数列表 LuaObjectDecoder decoder = new LuaObjectDecoder(arguments, size, context); int argSize = decoder.readInt32(); argumentsList = new List <LuaValue> (); for (int i = 0; i < argSize; i++) { LuaValue value = decoder.readObject() as LuaValue; argumentsList.Add(value); } } ArrayList argsArr = null; ParameterInfo[] parameters = m.GetParameters(); if (parameters.Length > 0 && argumentsList != null) { int i = 0; argsArr = new ArrayList(); foreach (ParameterInfo p in parameters) { if (i >= argumentsList.Count) { break; } object value = getNativeValueForLuaValue(p.ParameterType, argumentsList[i]); argsArr.Add(value); i++; } } return(argsArr); }
/// <summary> /// 初始化 /// </summary> /// <param name="context">上下文对象.</param> public LuaObjectEncoder(LuaContext context) { _buffer = new List <byte> (); _context = context; }
/// <summary> /// 导出类型 /// </summary> /// <param name="type">类型.</param> /// <param name="context">上下文对象.</param> public void exportType(Type t, LuaContext context) { LuaExportTypeAnnotation typeAnnotation = Attribute.GetCustomAttribute(t, typeof(LuaExportTypeAnnotation), false) as LuaExportTypeAnnotation; LuaExportTypeAnnotation baseTypeAnnotation = Attribute.GetCustomAttribute(t.BaseType, typeof(LuaExportTypeAnnotation), false) as LuaExportTypeAnnotation; //获取导出的类/实例方法 Dictionary <string, MethodInfo> exportClassMethods = new Dictionary <string, MethodInfo> (); List <string> exportClassMethodNames = new List <string> (); Dictionary <string, MethodInfo> exportInstanceMethods = new Dictionary <string, MethodInfo> (); List <string> exportInstanceMethodNames = new List <string> (); MethodInfo[] methods = t.GetMethods(); foreach (MethodInfo m in methods) { if (m.IsPublic || (m.IsStatic && m.IsPublic)) { StringBuilder methodSignature = new StringBuilder(); foreach (ParameterInfo paramInfo in m.GetParameters()) { Type paramType = paramInfo.ParameterType; if (baseTypesMapping.ContainsKey(paramType)) { methodSignature.Append(baseTypesMapping [paramType]); } else { methodSignature.Append("@"); } } string methodName = string.Format("{0}_{1}", m.Name, methodSignature.ToString()); if (m.IsStatic && m.IsPublic) { if (typeAnnotation != null && typeAnnotation.excludeExportClassMethodNames != null && Array.IndexOf(typeAnnotation.excludeExportClassMethodNames, m.Name) >= 0) { //为过滤方法 continue; } //静态和公开的方法会导出到Lua exportClassMethodNames.Add(methodName); exportClassMethods.Add(methodName, m); } else if (m.IsPublic) { if (typeAnnotation != null && typeAnnotation.excludeExportInstanceMethodNames != null && Array.IndexOf(typeAnnotation.excludeExportInstanceMethodNames, m.Name) >= 0) { //为过滤方法 continue; } //实例方法 exportInstanceMethodNames.Add(methodName); exportInstanceMethods.Add(methodName, m); } } } //获取导出的字段 Dictionary <string, PropertyInfo> exportFields = new Dictionary <string, PropertyInfo> (); List <string> exportPropertyNames = new List <string> (); PropertyInfo[] propertys = t.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo p in propertys) { if (typeAnnotation != null && typeAnnotation.excludeExportPropertyNames != null && Array.IndexOf(typeAnnotation.excludeExportPropertyNames, p.Name) >= 0) { //在过滤列表中 continue; } StringBuilder actStringBuilder = new StringBuilder(); if (p.CanRead) { actStringBuilder.Append("r"); } if (p.CanWrite) { actStringBuilder.Append("w"); } exportPropertyNames.Add(string.Format("{0}_{1}", p.Name, actStringBuilder.ToString())); exportFields.Add(p.Name, p); } //创建导出的字段数据 IntPtr exportPropertyNamesPtr = IntPtr.Zero; if (exportPropertyNames.Count > 0) { LuaObjectEncoder fieldEncoder = new LuaObjectEncoder(context); fieldEncoder.writeInt32(exportPropertyNames.Count); foreach (string name in exportPropertyNames) { fieldEncoder.writeString(name); } byte[] fieldNameBytes = fieldEncoder.bytes; exportPropertyNamesPtr = Marshal.AllocHGlobal(fieldNameBytes.Length); Marshal.Copy(fieldNameBytes, 0, exportPropertyNamesPtr, fieldNameBytes.Length); } //创建导出的实例方法数据 IntPtr exportInstanceMethodNamesPtr = IntPtr.Zero; if (exportInstanceMethodNames.Count > 0) { LuaObjectEncoder instanceMethodEncoder = new LuaObjectEncoder(context); instanceMethodEncoder.writeInt32(exportInstanceMethodNames.Count); foreach (string name in exportInstanceMethodNames) { instanceMethodEncoder.writeString(name); } byte[] instMethodNameBytes = instanceMethodEncoder.bytes; exportInstanceMethodNamesPtr = Marshal.AllocHGlobal(instMethodNameBytes.Length); Marshal.Copy(instMethodNameBytes, 0, exportInstanceMethodNamesPtr, instMethodNameBytes.Length); } //创建导出类方法数据 IntPtr exportClassMethodNamesPtr = IntPtr.Zero; if (exportClassMethodNames.Count > 0) { LuaObjectEncoder classMethodEncoder = new LuaObjectEncoder(context); classMethodEncoder.writeInt32(exportClassMethodNames.Count); foreach (string name in exportClassMethodNames) { classMethodEncoder.writeString(name); } byte[] classMethodNameBytes = classMethodEncoder.bytes; exportClassMethodNamesPtr = Marshal.AllocHGlobal(classMethodNameBytes.Length); Marshal.Copy(classMethodNameBytes, 0, exportClassMethodNamesPtr, classMethodNameBytes.Length); } //创建实例方法 if (_createInstanceDelegate == null) { _createInstanceDelegate = new LuaInstanceCreateHandleDelegate(_createInstance); } //销毁实例方法 if (_destroyInstanceDelegate == null) { _destroyInstanceDelegate = new LuaInstanceDestroyHandleDelegate(_destroyInstance); } //类描述 if (_instanceDescriptionDelegate == null) { _instanceDescriptionDelegate = new LuaInstanceDescriptionHandleDelegate(_instanceDescription); } //字段获取器 if (_fieldGetterDelegate == null) { _fieldGetterDelegate = new LuaInstanceFieldGetterHandleDelegate(_fieldGetter); } //字段设置器 if (_fieldSetterDelegate == null) { _fieldSetterDelegate = new LuaInstanceFieldSetterHandleDelegate(_fieldSetter); } //实例方法处理器 if (_instanceMethodHandlerDelegate == null) { _instanceMethodHandlerDelegate = new LuaInstanceMethodHandleDelegate(_instanceMethodHandler); } //类方法处理器 if (_classMethodHandleDelegate == null) { _classMethodHandleDelegate = new LuaModuleMethodHandleDelegate(_classMethodHandler); } string typeName = t.Name; if (typeAnnotation != null && typeAnnotation.typeName != null) { typeName = typeAnnotation.typeName; } string baseTypeName = t.BaseType.Name; if (baseTypeAnnotation != null && baseTypeAnnotation.typeName != null) { baseTypeName = baseTypeAnnotation.typeName; } int typeId = NativeUtils.registerType( context.objectId, typeName, baseTypeName, exportPropertyNamesPtr, exportInstanceMethodNamesPtr, exportClassMethodNamesPtr, Marshal.GetFunctionPointerForDelegate(_createInstanceDelegate), Marshal.GetFunctionPointerForDelegate(_destroyInstanceDelegate), Marshal.GetFunctionPointerForDelegate(_instanceDescriptionDelegate), Marshal.GetFunctionPointerForDelegate(_fieldGetterDelegate), Marshal.GetFunctionPointerForDelegate(_fieldSetterDelegate), Marshal.GetFunctionPointerForDelegate(_instanceMethodHandlerDelegate), Marshal.GetFunctionPointerForDelegate(_classMethodHandleDelegate)); //关联注册模块的注册方法 _exportsClass[typeId] = t; _exportsClassIdMapping [t] = typeId; _exportsClassMethods[typeId] = exportClassMethods; _exportsInstanceMethods[typeId] = exportInstanceMethods; _exportsFields[typeId] = exportFields; if (exportPropertyNamesPtr != IntPtr.Zero) { Marshal.FreeHGlobal(exportPropertyNamesPtr); } if (exportInstanceMethodNamesPtr != IntPtr.Zero) { Marshal.FreeHGlobal(exportInstanceMethodNamesPtr); } if (exportClassMethodNamesPtr != IntPtr.Zero) { Marshal.FreeHGlobal(exportClassMethodNamesPtr); } }
/// <summary> /// 初始化 /// </summary> /// <param name="context">上下文对象.</param> public LuaExportsTypeManager(LuaContext context) { _weakContext = new WeakReference(context); }
private static void exportsNativeType(int contextId, string typeName) { if (_assemblys == null) { //初始化名称空间 _assemblys = new HashSet <Assembly> (); Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblys) { bool needAdd = true; string assemblyName = assembly.GetName().Name; foreach (Regex regex in _excludeAssemblyNames) { if (regex.IsMatch(assemblyName)) { needAdd = false; break; } } if (needAdd) { _assemblys.Add(assembly); } } } LuaContext context = LuaContext.getContext(contextId); if (context != null) { //查找类型 Type targetType = null; string fullTypeName = typeName.Replace("_", "."); foreach (Assembly assembly in _assemblys) { targetType = Type.GetType(string.Format("{0},{1}", typeName, assembly.GetName().Name)); if (targetType == null) { targetType = Type.GetType(string.Format("{0},{1}", fullTypeName, assembly.GetName().Name)); if (targetType == null) { foreach (Type type in assembly.GetTypes()) { if (type.Name == typeName) { targetType = type; break; } } } } if (targetType != null) { break; } } if (targetType != null) { //为导出类型 context.exportsNativeType(targetType); } } }