コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: LuaModule.cs プロジェクト: lzxkulou/LuaScriptCore
        /// <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);
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
ファイル: LuaModule.cs プロジェクト: lzxkulou/LuaScriptCore
        /// <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 });
            }
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
                }
            }
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
 /// <summary>
 /// 初始化
 /// </summary>
 /// <param name="context">上下文对象.</param>
 public LuaObjectEncoder(LuaContext context)
 {
     _buffer  = new List <byte> ();
     _context = context;
 }
コード例 #10
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);
            }
        }
コード例 #11
0
 /// <summary>
 /// 初始化
 /// </summary>
 /// <param name="context">上下文对象.</param>
 public LuaExportsTypeManager(LuaContext context)
 {
     _weakContext = new WeakReference(context);
 }
コード例 #12
0
ファイル: UNIEnv.cs プロジェクト: zhongbq88/LuaScriptCore
        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);
                }
            }
        }