예제 #1
0
        static int MetaUnaryOpFunctionInternal(lua_State L)
        {
            var objectArg = Api.luaL_testudata(L, 1, Lua.objectMetaTable);             // test first one

            if (objectArg == IntPtr.Zero)
            {
                throw new LuaException(string.Format("Binary op {0} called on unexpected values.", Api.lua_tostring(L, Api.lua_upvalueindex(1))));
            }
            var obj     = Lua.UdataToObject(objectArg);
            var type    = obj.GetType();
            var opName  = Api.lua_tostring(L, Api.lua_upvalueindex(1));
            var members = Lua.GetMembers(type, opName, hasPrivatePrivillage: false);

            if (members.Length == 0)
            {
                throw new LuaException(string.Format("{0} not found in type {1}", opName, type.ToString()));
            }

            // upvalue 1 --> invocationFlags
            // upvalue 2 --> userdata (host of metatable).
            // upvalue 3 --> members
            Api.lua_pushinteger(L, (long)Lua.InvocationFlags.Static);
            Lua.PushObjectInternal(L, type);
            Lua.PushObjectInternal(L, members);
            Api.lua_pushcclosure(L, Lua.InvokeMethod, 3);
            Api.lua_pushvalue(L, 1);
            Lua.CallInternal(L, 1, 1);
            return(1);
        }
예제 #2
0
        static int LuaDelegateInternal(IntPtr L)
        {
            var func          = (Delegate)Lua.ObjectAtInternal(L, Api.lua_upvalueindex(1));
            var numArgs       = Api.lua_gettop(L);
            var refToDelegate = Lua.MakeRefToInternal(L, func);

            try
            {
                Api.lua_pushinteger(L, 0);                 // upvalue 1 --> invocationFlags
                Lua.PushRefInternal(L, refToDelegate);     // upvalue 2 --> userdata, first parameter of __index
                var members = Lua.GetMembers(func.GetType(), "Invoke", hasPrivatePrivillage: false);
                Lua.PushObjectInternal(L, members);        // upvalue 3 --> members
                Api.lua_pushcclosure(L, Lua.InvokeMethod, 3);
                Lua.PushRefInternal(L, refToDelegate);
                for (int i = 1; i <= numArgs; ++i)
                {
                    Api.lua_pushvalue(L, i);
                }
                Lua.CallInternal(L, numArgs + 1, 1);
                Lua.UnrefInternal(L, refToDelegate);
            }
            catch (Exception e)
            {
                Lua.UnrefInternal(L, refToDelegate);
                throw e;
            }
            return(1);
        }
예제 #3
0
        static int MetaBinaryOpFunctionInternal(lua_State L)
        {
            var op         = (Lua.BinaryOp)Api.lua_tointeger(L, Api.lua_upvalueindex(2));
            var objectArg  = Api.luaL_testudata(L, 1, Lua.objectMetaTable);
            var objectArg2 = Api.luaL_testudata(L, 2, Lua.objectMetaTable);

            if (objectArg == IntPtr.Zero && objectArg2 == IntPtr.Zero)
            {
                throw new LuaException(string.Format("Binary op {0} called on unexpected values.", Api.lua_tostring(L, Api.lua_upvalueindex(1))));
            }
            object obj1 = null, obj2 = null;

            if (objectArg != IntPtr.Zero)
            {
                obj1 = Lua.UdataToObject(objectArg);
            }
            if (objectArg2 != IntPtr.Zero)
            {
                obj2 = Lua.UdataToObject(objectArg2);
            }
            if (op == Lua.BinaryOp.op_Equality)
            {
                if ((obj1 == obj2) ||
                    (obj1 != null && obj1.Equals(obj2)) ||
                    (obj2 != null && obj2.Equals(obj1)))
                {
                    Api.lua_pushboolean(L, true);
                }
                else
                {
                    Api.lua_pushboolean(L, false);
                }
                return(1);
            }
            var obj = obj1;

            if (obj == null)
            {
                obj = obj2;
            }

            var type    = obj.GetType();
            var opName  = Api.lua_tostring(L, Api.lua_upvalueindex(1));
            var members = Lua.GetMembers(type, opName, hasPrivatePrivillage: false);

            if (members.Length == 0)
            {
                throw new LuaException(string.Format("{0} not found in type {1}", opName, type.ToString()));
            }

            long invocationFlags = (long)Lua.InvocationFlags.Static;

            Api.lua_pushinteger(L, invocationFlags);    // upvalue 1 --> invocationFlags
            Lua.PushObjectInternal(L, type);            // upvalue 2 --> userdata (host of metatable).
            Lua.PushObjectInternal(L, members);         // upvalue 3 --> members
            Api.lua_pushcclosure(L, Lua.InvokeMethod, 3);
            Api.lua_pushvalue(L, 1);
            Api.lua_pushvalue(L, 2);
            Lua.CallInternal(L, 2, 1);
            return(1);
        }