Esempio n. 1
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));
        }
Esempio n. 2
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);
            }
        }
        static bool tryPrimitiveArrayGet(Type type, RealStatePtr L, object obj, int index)
        {
            bool ok = true;

            if (type == typeof(int[]))
            {
                int[] array = obj as int[];
                LuaAPI.xlua_pushinteger(L, array[index]);
            }
            else if (type == typeof(float[]))
            {
                float[] array = obj as float[];
                LuaAPI.lua_pushnumber(L, array[index]);
            }
            else if (type == typeof(double[]))
            {
                double[] array = obj as double[];
                LuaAPI.lua_pushnumber(L, array[index]);
            }
            else if (type == typeof(bool[]))
            {
                bool[] array = obj as bool[];
                LuaAPI.lua_pushboolean(L, array[index]);
            }
            else if (type == typeof(long[]))
            {
                long[] array = obj as long[];
                LuaAPI.lua_pushint64(L, array[index]);
            }
            else if (type == typeof(ulong[]))
            {
                ulong[] array = obj as ulong[];
                LuaAPI.lua_pushuint64(L, array[index]);
            }
            else if (type == typeof(sbyte[]))
            {
                sbyte[] array = obj as sbyte[];
                LuaAPI.xlua_pushinteger(L, array[index]);
            }
            else if (type == typeof(short[]))
            {
                short[] array = obj as short[];
                LuaAPI.xlua_pushinteger(L, array[index]);
            }
            else if (type == typeof(ushort[]))
            {
                ushort[] array = obj as ushort[];
                LuaAPI.xlua_pushinteger(L, array[index]);
            }
            else if (type == typeof(char[]))
            {
                char[] array = obj as char[];
                LuaAPI.xlua_pushinteger(L, array[index]);
            }
            else if (type == typeof(uint[]))
            {
                uint[] array = obj as uint[];
                LuaAPI.xlua_pushuint(L, array[index]);
            }
            else if (type == typeof(IntPtr[]))
            {
                IntPtr[] array = obj as IntPtr[];
                LuaAPI.lua_pushlightuserdata(L, array[index]);
            }
            else if (type == typeof(decimal[]))
            {
                decimal[]        array      = obj as decimal[];
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                translator.PushDecimal(L, array[index]);
            }
            else if (type == typeof(string[]))
            {
                string[] array = obj as string[];
                LuaAPI.lua_pushstring(L, array[index]);
            }
            else
            {
                ok = false;
            }
            return(ok);
        }