Exemple #1
0
        public bool TryDelayWrapLoader(RealStatePtr L, Type type)
        {
            if (loaded_types.ContainsKey(type))
            {
                return(true);
            }
            loaded_types.Add(type, true);

            LuaAPI.luaL_newmetatable(L, type.FullName); //先建一个metatable,因为加载过程可能会需要用到
            LuaAPI.lua_pop(L, 1);

            Action <RealStatePtr> loader;
            int top = LuaAPI.lua_gettop(L);

            if (delayWrap.TryGetValue(type, out loader))
            {
                delayWrap.Remove(type);
                loader(L);
            }
            else
            {
                Utils.ReflectionWrap(L, type);
#if NOT_GEN_WARNING
#if !XLUA_GENERAL
                UnityEngine.Debug.LogWarning(string.Format("{0} not gen, using reflection instead", type));
#else
                System.Console.WriteLine(string.Format("Warning: {0} not gen, using reflection instead", type));
#endif
#endif
            }
            if (top != LuaAPI.lua_gettop(L))
            {
                throw new Exception("top change, before:" + top + ", after:" + LuaAPI.lua_gettop(L));
            }

            foreach (var nested_type in type.GetNestedTypes())
            {
                if ((!nested_type.IsAbstract && typeof(Delegate).IsAssignableFrom(nested_type)) ||
                    nested_type.IsGenericTypeDefinition)
                {
                    continue;
                }
                TryDelayWrapLoader(L, nested_type);
            }

            return(true);
        }
Exemple #2
0
        public static void ReflectionWrap(RealStatePtr L, Type type)
        {
            int top_enter = LuaAPI.lua_gettop(L);
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);

            //create obj meta table
            LuaAPI.luaL_getmetatable(L, type.FullName);
            if (LuaAPI.lua_isnil(L, -1))
            {
                LuaAPI.lua_pop(L, 1);
                LuaAPI.luaL_newmetatable(L, type.FullName);
            }
            LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
            LuaAPI.lua_pushnumber(L, 1);
            LuaAPI.lua_rawset(L, -3);
            int obj_meta = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_meta = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int obj_field = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int obj_getter = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int obj_setter = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_field = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_getter = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_setter = LuaAPI.lua_gettop(L);

            LuaCSFunction item_getter;
            LuaCSFunction item_setter;

            makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
                               out item_getter, out item_setter);

            // init obj metatable
            LuaAPI.xlua_pushasciistring(L, "__gc");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
            LuaAPI.lua_rawset(L, obj_meta);

            LuaAPI.xlua_pushasciistring(L, "__tostring");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
            LuaAPI.lua_rawset(L, obj_meta);

            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, obj_field);
            LuaAPI.lua_pushvalue(L, obj_getter);
            translator.PushFixCSFunction(L, item_getter);
            translator.PushAny(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.lua_pushnil(L);
            LuaAPI.gen_obj_indexer(L);
            //store in lua indexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, obj_meta); // set __index

            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, obj_setter);
            translator.PushFixCSFunction(L, item_setter);
            translator.Push(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.lua_pushnil(L);
            LuaAPI.gen_obj_newindexer(L);
            //store in lua newindexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, obj_meta); // set __newindex
            //finish init obj metatable

            LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
            translator.PushAny(L, type);
            LuaAPI.lua_rawset(L, cls_field);

            if (type != null && type.IsEnum)
            {
                LuaAPI.xlua_pushasciistring(L, "__CastFrom");
                translator.PushFixCSFunction(L, genEnumCastFrom(type));
                LuaAPI.lua_rawset(L, cls_field);
            }

            //set cls_field to namespace
            SetCSTable(L, type, cls_field);
            //finish set cls_field to namespace

            //init class meta
            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, cls_getter);
            LuaAPI.lua_pushvalue(L, cls_field);
            translator.Push(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_indexer(L);
            //store in lua indexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, cls_meta); // set __index

            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, cls_setter);
            translator.Push(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_newindexer(L);
            //store in lua newindexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, cls_meta); // set __newindex

            LuaCSFunction constructor = translator.methodWrapsCache.GetConstructorWrap(type);

            if (constructor == null)
            {
                constructor = (RealStatePtr LL) =>
                {
                    return(LuaAPI.luaL_error(LL, "No constructor for " + type));
                };
            }

            LuaAPI.xlua_pushasciistring(L, "__call");
            translator.PushFixCSFunction(L, constructor);
            LuaAPI.lua_rawset(L, cls_meta);

            LuaAPI.lua_pushvalue(L, cls_meta);
            LuaAPI.lua_setmetatable(L, cls_field);

            LuaAPI.lua_pop(L, 8);

            System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L));
        }
Exemple #3
0
        //meta: -4, method:-3, getter: -2, setter: -1
        public static void BeginObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, int meta_count, int method_count, int getter_count,
                                               int setter_count, int type_id = -1)
        {
            if (type == null)
            {
                if (type_id == -1)
                {
                    throw new Exception("Fatal: must provide a type of type_id");
                }
                LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id);
            }
            else
            {
                LuaAPI.luaL_getmetatable(L, type.FullName);
                if (LuaAPI.lua_isnil(L, -1))
                {
                    LuaAPI.lua_pop(L, 1);
                    LuaAPI.luaL_newmetatable(L, type.FullName);
                }
            }
            LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
            LuaAPI.lua_pushnumber(L, 1);
            LuaAPI.lua_rawset(L, -3);

            if ((type == null || !translator.HasCustomOp(type)) && type != typeof(decimal))
            {
                LuaAPI.xlua_pushasciistring(L, "__gc");
                LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
                LuaAPI.lua_rawset(L, -3);
            }

            LuaAPI.xlua_pushasciistring(L, "__tostring");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
            LuaAPI.lua_rawset(L, -3);

            if (method_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, method_count);
            }

            if (getter_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, getter_count);
            }

            if (setter_count == 0)
            {
                LuaAPI.lua_pushnil(L);
            }
            else
            {
                LuaAPI.lua_createtable(L, 0, setter_count);
            }
        }
Exemple #4
0
        public static void ReflectionWrap(RealStatePtr L, Type type)
        {
            int top_enter = LuaAPI.lua_gettop(L);
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);

            //create obj meta table
            LuaAPI.luaL_getmetatable(L, type.FullName);
            if (LuaAPI.lua_isnil(L, -1))
            {
                LuaAPI.lua_pop(L, 1);
                LuaAPI.luaL_newmetatable(L, type.FullName);
            }
            LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
            LuaAPI.lua_pushnumber(L, 1);
            LuaAPI.lua_rawset(L, -3);
            int obj_meta = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_meta = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int obj_field = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int obj_getter = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int obj_setter = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_field = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_getter = LuaAPI.lua_gettop(L);

            LuaAPI.lua_newtable(L);
            int cls_setter = LuaAPI.lua_gettop(L);

            BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;

            FieldInfo[] fields = type.GetFields(flag);

            for (int i = 0; i < fields.Length; ++i)
            {
                FieldInfo field = fields[i];
                if (field.IsStatic && (field.IsInitOnly || field.IsLiteral))
                {
                    LuaAPI.xlua_pushasciistring(L, field.Name);
                    translator.PushAny(L, field.GetValue(null));
                    LuaAPI.lua_rawset(L, cls_field);
                }
                else
                {
                    LuaAPI.xlua_pushasciistring(L, field.Name);
                    translator.PushFixCSFunction(L, genFieldGetter(type, field));
                    LuaAPI.lua_rawset(L, field.IsStatic ? cls_getter : obj_getter);

                    LuaAPI.xlua_pushasciistring(L, field.Name);
                    translator.PushFixCSFunction(L, genFieldSetter(type, field));
                    LuaAPI.lua_rawset(L, field.IsStatic ? cls_setter : obj_setter);
                }
            }

            EventInfo[] events = type.GetEvents(flag);
            for (int i = 0; i < events.Length; ++i)
            {
                EventInfo eventInfo = events[i];
                LuaAPI.xlua_pushasciistring(L, eventInfo.Name);
                translator.PushFixCSFunction(L, translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name));
                bool is_static = (eventInfo.GetAddMethod() != null) ? eventInfo.GetAddMethod().IsStatic : eventInfo.GetRemoveMethod().IsStatic;
                LuaAPI.lua_rawset(L, is_static ? cls_field : obj_field);
            }

            Dictionary <string, PropertyInfo> prop_map = new Dictionary <string, PropertyInfo>();
            List <PropertyInfo> items = new List <PropertyInfo>();

            PropertyInfo[] props = type.GetProperties(flag);
            for (int i = 0; i < props.Length; ++i)
            {
                PropertyInfo prop = props[i];
                if (prop.Name == "Item")
                {
                    items.Add(prop);
                }
                else
                {
                    prop_map.Add(prop.Name, prop);
                }
            }

            var           item_array  = items.ToArray();
            LuaCSFunction item_getter = item_array.Length > 0 ? genItemGetter(type, item_array) : null;
            LuaCSFunction item_setter = item_array.Length > 0 ? genItemSetter(type, item_array) : null;;

            MethodInfo[] methods = type.GetMethods(flag);
            Dictionary <MethodKey, List <MemberInfo> > pending_methods = new Dictionary <MethodKey, List <MemberInfo> >();

            for (int i = 0; i < methods.Length; ++i)
            {
                MethodInfo method      = methods[i];
                string     method_name = method.Name;

                MethodKey method_key = new MethodKey {
                    Name = method_name, IsStatic = method.IsStatic
                };
                List <MemberInfo> overloads;
                if (pending_methods.TryGetValue(method_key, out overloads))
                {
                    overloads.Add(method);
                    continue;
                }

                PropertyInfo prop = null;
                if (method_name.StartsWith("add_") || method_name.StartsWith("remove_") ||
                    method_name == "get_Item" || method_name == "set_Item")
                {
                    continue;
                }

                if (method_name.StartsWith("op_")) // 操作符
                {
                    if (support_op.ContainsKey(method_name))
                    {
                        if (overloads == null)
                        {
                            overloads = new List <MemberInfo>();
                            pending_methods.Add(method_key, overloads);
                        }
                        overloads.Add(method);
                    }
                    continue;
                }
                else if (method_name.StartsWith("get_") && prop_map.TryGetValue(method.Name.Substring(4), out prop)) // getter of property
                {
                    LuaAPI.xlua_pushasciistring(L, prop.Name);
                    translator.PushFixCSFunction(L, genPropGetter(type, prop, method.IsStatic));
                    LuaAPI.lua_rawset(L, method.IsStatic ? cls_getter : obj_getter);
                }
                else if (method_name.StartsWith("set_") && prop_map.TryGetValue(method.Name.Substring(4), out prop)) // setter of property
                {
                    LuaAPI.xlua_pushasciistring(L, prop.Name);
                    translator.PushFixCSFunction(L, genPropSetter(type, prop, method.IsStatic));
                    LuaAPI.lua_rawset(L, method.IsStatic ? cls_setter : obj_setter);
                }
                else if (method_name == ".ctor" && method.IsConstructor)
                {
                    continue;
                }
                else
                {
                    if (overloads == null)
                    {
                        overloads = new List <MemberInfo>();
                        pending_methods.Add(method_key, overloads);
                    }
                    overloads.Add(method);
                }
            }

            foreach (var kv in pending_methods)
            {
                if (kv.Key.Name.StartsWith("op_")) // 操作符
                {
                    LuaAPI.xlua_pushasciistring(L, support_op[kv.Key.Name]);
                    translator.PushFixCSFunction(L,
                                                 new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
                    LuaAPI.lua_rawset(L, obj_meta);
                }
                else
                {
                    LuaAPI.xlua_pushasciistring(L, kv.Key.Name);
                    translator.PushFixCSFunction(L,
                                                 new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
                    LuaAPI.lua_rawset(L, kv.Key.IsStatic ? cls_field : obj_field);
                }
            }

            IEnumerable <MethodInfo> extend_methods = GetExtensionMethodsOf(type);

            if (extend_methods != null)
            {
                foreach (var kv in (from extend_method in extend_methods select(MemberInfo) extend_method into member group member by member.Name))
                {
                    LuaAPI.xlua_pushasciistring(L, kv.Key);
                    translator.PushFixCSFunction(L, new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key, kv).Call));
                    LuaAPI.lua_rawset(L, obj_field);
                }
            }

            // init obj metatable
            LuaAPI.xlua_pushasciistring(L, "__gc");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
            LuaAPI.lua_rawset(L, obj_meta);

            LuaAPI.xlua_pushasciistring(L, "__tostring");
            LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
            LuaAPI.lua_rawset(L, obj_meta);

            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, obj_field);
            LuaAPI.lua_pushvalue(L, obj_getter);
            translator.PushFixCSFunction(L, item_getter);
            translator.PushAny(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.lua_pushnil(L);
            LuaAPI.gen_obj_indexer(L);
            //store in lua indexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, obj_meta); // set __index

            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, obj_setter);
            translator.PushFixCSFunction(L, item_setter);
            translator.Push(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.lua_pushnil(L);
            LuaAPI.gen_obj_newindexer(L);
            //store in lua newindexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, obj_meta); // set __newindex
            //finish init obj metatable

            LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
            translator.PushAny(L, type);
            LuaAPI.lua_rawset(L, cls_field);

            if (type != null && type.IsEnum)
            {
                LuaAPI.xlua_pushasciistring(L, "__CastFrom");
                translator.PushFixCSFunction(L, genEnumCastFrom(type));
                LuaAPI.lua_rawset(L, cls_field);
            }

            //set cls_field to namespace
            SetCSTable(L, type, cls_field);
            //finish set cls_field to namespace

            //init class meta
            LuaAPI.xlua_pushasciistring(L, "__index");
            LuaAPI.lua_pushvalue(L, cls_getter);
            LuaAPI.lua_pushvalue(L, cls_field);
            translator.Push(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_indexer(L);
            //store in lua indexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, cls_meta); // set __index

            LuaAPI.xlua_pushasciistring(L, "__newindex");
            LuaAPI.lua_pushvalue(L, cls_setter);
            translator.Push(L, type.BaseType);
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            LuaAPI.gen_cls_newindexer(L);
            //store in lua newindexs function tables
            LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName);
            LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
            translator.Push(L, type);
            LuaAPI.lua_pushvalue(L, -3);
            LuaAPI.lua_rawset(L, -3);
            LuaAPI.lua_pop(L, 1);
            LuaAPI.lua_rawset(L, cls_meta); // set __newindex

            LuaCSFunction constructor = translator.methodWrapsCache.GetConstructorWrap(type);

            if (constructor == null)
            {
                constructor = (RealStatePtr LL) =>
                {
                    return(LuaAPI.luaL_error(LL, "No constructor for " + type));
                };
            }

            LuaAPI.xlua_pushasciistring(L, "__call");
            translator.PushFixCSFunction(L, constructor);
            LuaAPI.lua_rawset(L, cls_meta);

            LuaAPI.lua_pushvalue(L, cls_meta);
            LuaAPI.lua_setmetatable(L, cls_field);

            LuaAPI.lua_pop(L, 8);

            System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L));
        }