Exemplo n.º 1
0
        /// <summary>
        /// 注册模块
        /// </summary>
        /// <param name="context">Lua上下文对象.</param>
        /// <param name="moduleName">模块名称.</param>
        /// <param name="t">类型.</param>
        protected static new void _register(LuaContext context, string moduleName, Type t)
        {
            Type baseType = t.BaseType;

            string superClassName = null;

            if (baseType != typeof(LuaModule))
            {
                superClassName = LuaModule.moduleName(baseType);
                if (!context.isModuleRegisted(superClassName))
                {
                    //尚未注册父类,进行父类注册
                    LuaModule.register(context, baseType);
                }
            }

            //获取导出的类/实例方法
            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.IsStatic && m.IsPublic)
                {
                    //静态和公开的方法会导出到Lua
                    exportClassMethodNames.Add(m.Name);
                    exportClassMethods.Add(m.Name, m);
                }
                else if (m.IsPublic)
                {
                    //实例方法
                    exportInstanceMethodNames.Add(m.Name);
                    exportInstanceMethods.Add(m.Name, m);
                }
            }

            //获取导出的字段
            Dictionary <string, PropertyInfo> exportFields = new Dictionary <string, PropertyInfo> ();
            List <string> exportSetterNames = new List <string> ();
            List <string> exportGetterNames = new List <string> ();

            PropertyInfo[] propertys = t.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (PropertyInfo p in propertys)
            {
                if (p.CanRead)
                {
                    exportGetterNames.Add(p.Name);
                }
                if (p.CanWrite)
                {
                    exportSetterNames.Add(p.Name);
                }
                exportFields.Add(p.Name, p);
            }

            //创建导出的字段数据
            IntPtr exportSetterNamesPtr = IntPtr.Zero;

            if (exportSetterNames.Count > 0)
            {
                LuaObjectEncoder fieldEncoder = new LuaObjectEncoder();
                fieldEncoder.writeInt32(exportSetterNames.Count);
                foreach (string name in exportSetterNames)
                {
                    fieldEncoder.writeString(name);
                }

                byte[] fieldNameBytes = fieldEncoder.bytes;
                exportSetterNamesPtr = Marshal.AllocHGlobal(fieldNameBytes.Length);
                Marshal.Copy(fieldNameBytes, 0, exportSetterNamesPtr, fieldNameBytes.Length);
            }

            IntPtr exportGetterNamesPtr = IntPtr.Zero;

            if (exportGetterNames.Count > 0)
            {
                LuaObjectEncoder fieldEncoder = new LuaObjectEncoder();
                fieldEncoder.writeInt32(exportGetterNames.Count);
                foreach (string name in exportGetterNames)
                {
                    fieldEncoder.writeString(name);
                }

                byte[] fieldNameBytes = fieldEncoder.bytes;
                exportGetterNamesPtr = Marshal.AllocHGlobal(fieldNameBytes.Length);
                Marshal.Copy(fieldNameBytes, 0, exportGetterNamesPtr, fieldNameBytes.Length);
            }


            //创建导出的实例方法数据
            IntPtr exportInstanceMethodNamesPtr = IntPtr.Zero;

            if (exportInstanceMethodNames.Count > 0)
            {
                LuaObjectEncoder instanceMethodEncoder = new LuaObjectEncoder();
                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();
                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);
            }

            int nativeId = NativeUtils.registerClass(
                context.objectId,
                moduleName,
                superClassName,
                exportSetterNamesPtr,
                exportGetterNamesPtr,
                exportInstanceMethodNamesPtr,
                exportClassMethodNamesPtr,
                Marshal.GetFunctionPointerForDelegate(_createInstanceDelegate),
                Marshal.GetFunctionPointerForDelegate(_destroyInstanceDelegate),
                Marshal.GetFunctionPointerForDelegate(_instanceDescriptionDelegate),
                Marshal.GetFunctionPointerForDelegate(_fieldGetterDelegate),
                Marshal.GetFunctionPointerForDelegate(_fieldSetterDelegate),
                Marshal.GetFunctionPointerForDelegate(_instanceMethodHandlerDelegate),
                Marshal.GetFunctionPointerForDelegate(_classMethodHandleDelegate));

            //关联注册模块的注册方法
            _exportsClass[nativeId]           = t;
            _exportsClassMethods[nativeId]    = exportClassMethods;
            _exportsInstanceMethods[nativeId] = exportInstanceMethods;
            _exportsFields[nativeId]          = exportFields;

            if (exportSetterNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportSetterNamesPtr);
            }
            if (exportGetterNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportGetterNamesPtr);
            }
            if (exportInstanceMethodNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportInstanceMethodNamesPtr);
            }
            if (exportClassMethodNamesPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(exportClassMethodNamesPtr);
            }
        }
Exemplo n.º 2
0
        /// <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);
            }
        }