Beispiel #1
0
        /*
         * Implementation of get_constructor_bysig. Returns nil
         * if no matching constructor is found.
         */
        private int getConstructorSignature(KopiLua.LuaState luaState)
        {
            IReflect klass = null;
            int      udata = LuaDll.luanet_checkudata(luaState, 1, "luaNet_class");

            if (udata != -1)
            {
                klass = (IReflect)objects[udata];
            }
            if (klass == null)
            {
                throwError(luaState, "get_constructor_bysig: first arg is invalid type reference");
            }
            Type[] signature = new Type[LuaDll.lua_gettop(luaState) - 1];
            for (int i = 0; i < signature.Length; i++)
            {
                signature[i] = FindType(LuaDll.lua_tostring(luaState, i + 2));
            }
            try
            {
                ConstructorInfo constructor = klass.UnderlyingSystemType.GetConstructor(signature);
                pushFunction(luaState, new KopiLua.LuaNativeFunction((new LuaMethodWrapper(this, null, klass, constructor)).call));
            }
            catch (Exception e)
            {
                throwError(luaState, e);
                LuaDll.lua_pushnil(luaState);
            }
            return(1);
        }
Beispiel #2
0
        public void lua_registerTest()
        {
            bool wasCalled = false;

            LuaDll.lua_CFunction testFunctionDelegate = delegate(lua_State state)
            {
                wasCalled = true;
                LuaDll.lua_pushstring(state, "Success!");
                return(1);
            };

            // Create a new state
            var L = LuaDll.luaL_newstate();

            // Register the given function by name
            LuaDll.lua_register(L, "test_function", testFunctionDelegate);

            // Call the function by name
            var result = LuaDll.luaL_dostring(L, "return test_function()");

            Assert.AreEqual(0, result);
            Assert.IsTrue(wasCalled);

            // Check that the function returned the same string.
            var resultIndex  = LuaDll.lua_gettop(L);
            var resultString = LuaDll.lua_tostring(L, resultIndex);

            Assert.AreEqual("Success!", resultString);
        }
Beispiel #3
0
        /*
         * __index metafunction of base classes (the base field of Lua tables).
         * Adds a prefix to the method name to call the base version of the method.
         */
        private int getBaseMethod(KopiLua.LuaState luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj == null)
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaDll.lua_pushnil(luaState);
                LuaDll.lua_pushboolean(luaState, false);
                return(2);
            }
            string methodName = LuaDll.lua_tostring(luaState, 2);

            if (methodName == null)
            {
                LuaDll.lua_pushnil(luaState);
                LuaDll.lua_pushboolean(luaState, false);
                return(2);
            }
            getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance);
            LuaDll.lua_settop(luaState, -2);
            if (LuaDll.lua_type(luaState, -1) == LuaTypes.LUA_TNIL)
            {
                LuaDll.lua_settop(luaState, -2);
                return(getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance));
            }
            LuaDll.lua_pushboolean(luaState, false);
            return(2);
        }
Beispiel #4
0
        public Lua()
        {
            luaState = LuaDll.luaL_newstate();                  // steffenj: Lua 5.1.1 API change (lua_open is gone)
            //LuaDLL.luaopen_base(luaState);	// steffenj: luaopen_* no longer used
            LuaDll.luaL_openlibs(luaState);                     // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here)
            LuaDll.lua_pushstring(luaState, "LUAINTERFACE LOADED");
            LuaDll.lua_pushboolean(luaState, true);
            LuaDll.lua_settable(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX);
            LuaDll.lua_newtable(luaState);
            LuaDll.lua_setglobal(luaState, "luanet");
            LuaDll.lua_pushvalue(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX);
            LuaDll.lua_getglobal(luaState, "luanet");
            LuaDll.lua_pushstring(luaState, "getmetatable");
            LuaDll.lua_getglobal(luaState, "getmetatable");
            LuaDll.lua_settable(luaState, -3);
            LuaDll.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX);
            translator = new ObjectTranslator(this, luaState);
            LuaDll.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX);
            LuaDll.luaL_dostring(luaState, Lua.init_luanet);                    // steffenj: lua_dostring renamed to luaL_dostring

            // We need to keep this in a managed reference so the delegate doesn't get garbage collected
            panicCallback = new KopiLua.LuaNativeFunction(PanicCallback);
            LuaDll.lua_atpanic(luaState, panicCallback);

            // LuaDLL.lua_atlock(luaState, lockCallback = new KopiLua.LuaNativeFunction(LockCallback));
            // LuaDLL.lua_atunlock(luaState, unlockCallback = new KopiLua.LuaNativeFunction(UnlockCallback));
        }
Beispiel #5
0
        /*
         * Gets the values from the provided index to
         * the top of the stack and returns them in an array, casting
         * them to the provided types.
         */
        internal object[] popValues(KopiLua.LuaState luaState, int oldTop, Type[] popTypes)
        {
            int newTop = LuaDll.lua_gettop(luaState);

            if (oldTop == newTop)
            {
                return(null);
            }
            else
            {
                int       iTypes;
                ArrayList returnValues = new ArrayList();
                if (popTypes[0] == typeof(void))
                {
                    iTypes = 1;
                }
                else
                {
                    iTypes = 0;
                }
                for (int i = oldTop + 1; i <= newTop; i++)
                {
                    returnValues.Add(getAsType(luaState, i, popTypes[iTypes]));
                    iTypes++;
                }
                LuaDll.lua_settop(luaState, oldTop);
                return(returnValues.ToArray());
            }
        }
Beispiel #6
0
        /*
         * __index metafunction of type references, works on static members.
         */
        private int getClassMethod(KopiLua.LuaState luaState)
        {
            IReflect klass;
            object   obj = translator.getRawNetObject(luaState, 1);

            if (obj == null || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to index an invalid type reference");
                LuaDll.lua_pushnil(luaState);
                return(1);
            }
            else
            {
                klass = (IReflect)obj;
            }
            if (LuaDll.lua_isnumber(luaState, 2))
            {
                int size = (int)LuaDll.lua_tonumber(luaState, 2);
                translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size));
                return(1);
            }
            else
            {
                string methodName = LuaDll.lua_tostring(luaState, 2);
                if (methodName == null)
                {
                    LuaDll.lua_pushnil(luaState);
                    return(1);
                }
                else
                {
                    return(getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static));
                }
            }
        }
Beispiel #7
0
        /*
         * Calls the object as a function with the provided arguments and
         * casting returned values to the types in returnTypes before returning
         * them in an array
         */
        internal object[] callFunction(object function, object[] args, Type[] returnTypes)
        {
            int nArgs  = 0;
            int oldTop = LuaDll.lua_gettop(luaState);

            if (!LuaDll.lua_checkstack(luaState, args.Length + 6))
            {
                throw new LuaException("Lua stack overflow");
            }
            translator.push(luaState, function);
            if (args != null)
            {
                nArgs = args.Length;
                for (int i = 0; i < args.Length; i++)
                {
                    translator.push(luaState, args[i]);
                }
            }
            int error = LuaDll.lua_pcall(luaState, nArgs, -1, 0);

            if (error != 0)
            {
                ThrowExceptionFromError(oldTop);
            }

            if (returnTypes != null)
            {
                return(translator.popValues(luaState, oldTop, returnTypes));
            }
            else
            {
                return(translator.popValues(luaState, oldTop));
            }
        }
Beispiel #8
0
 /*
  * CAUTION: LuaInterface.Lua instances can't share the same lua state!
  */
 public Lua(KopiLua.LuaState lState)
 {
     LuaDll.lua_pushstring(lState, "LUAINTERFACE LOADED");
     LuaDll.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX);
     if (LuaDll.lua_toboolean(lState, -1))
     {
         LuaDll.lua_settop(lState, -2);
         throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state");
     }
     else
     {
         LuaDll.lua_settop(lState, -2);
         LuaDll.lua_pushstring(lState, "LUAINTERFACE LOADED");
         LuaDll.lua_pushboolean(lState, true);
         LuaDll.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX);
         this.luaState = lState;
         LuaDll.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
         LuaDll.lua_getglobal(lState, "luanet");
         LuaDll.lua_pushstring(lState, "getmetatable");
         LuaDll.lua_getglobal(lState, "getmetatable");
         LuaDll.lua_settable(lState, -3);
         LuaDll.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
         translator = new ObjectTranslator(this, this.luaState);
         LuaDll.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
         LuaDll.luaL_dostring(lState, Lua.init_luanet);                          // steffenj: lua_dostring renamed to luaL_dostring
     }
 }
Beispiel #9
0
 /*
  * Registers the indexing function of CLR objects
  * passed to Lua
  */
 private void createIndexingMetaFunction(KopiLua.LuaState luaState)
 {
     LuaDll.lua_pushstring(luaState, "luaNet_indexfunction");
     LuaDll.luaL_dostring(luaState, MetaFunctions.luaIndexFunction);             // steffenj: lua_dostring renamed to luaL_dostring
     //LuaDLL.lua_pushstdcallcfunction(luaState,indexFunction);
     LuaDll.lua_rawset(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX);
 }
Beispiel #10
0
        /*
         * Sets a field of the table or userdata corresponding the the provided reference
         * to the provided value
         */
        internal void setObject(int reference, string field, object val)
        {
            int oldTop = LuaDll.lua_gettop(luaState);

            LuaDll.lua_getref(luaState, reference);
            setObject(field.Split(new char[] { '.' }), val);
            LuaDll.lua_settop(luaState, oldTop);
        }
Beispiel #11
0
        private object getAsUlong(KopiLua.LuaState luaState, int stackPos)
        {
            ulong retVal = (ulong)LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #12
0
        private object getAsByte(KopiLua.LuaState luaState, int stackPos)
        {
            byte retVal = (byte)LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #13
0
        private object getAsString(KopiLua.LuaState luaState, int stackPos)
        {
            string retVal = LuaDll.lua_tostring(luaState, stackPos);

            if (retVal == "" && !LuaDll.lua_isstring(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #14
0
        private object getAsFloat(KopiLua.LuaState luaState, int stackPos)
        {
            float retVal = (float)LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #15
0
        /*
         * Gets a field of the table or userdata corresponding to the provided reference
         */
        internal object getObject(int reference, string field)
        {
            int oldTop = LuaDll.lua_gettop(luaState);

            LuaDll.lua_getref(luaState, reference);
            object returnValue = getObject(field.Split(new char[] { '.' }));

            LuaDll.lua_settop(luaState, oldTop);
            return(returnValue);
        }
Beispiel #16
0
        private object getAsChar(KopiLua.LuaState luaState, int stackPos)
        {
            char retVal = (char)LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #17
0
        /*
         * Sets a numeric field of the table or userdata corresponding the the provided reference
         * to the provided value
         */
        internal void setObject(int reference, object field, object val)
        {
            int oldTop = LuaDll.lua_gettop(luaState);

            LuaDll.lua_getref(luaState, reference);
            translator.push(luaState, field);
            translator.push(luaState, val);
            LuaDll.lua_settable(luaState, -3);
            LuaDll.lua_settop(luaState, oldTop);
        }
Beispiel #18
0
        private object getAsDecimal(KopiLua.LuaState luaState, int stackPos)
        {
            decimal retVal = (decimal)LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #19
0
        private object getAsDouble(KopiLua.LuaState luaState, int stackPos)
        {
            double retVal = LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #20
0
        private object getAsUshort(KopiLua.Lua.lua_State luaState, int stackPos)
        {
            ushort retVal = (ushort)LuaDll.lua_tonumber(luaState, stackPos);

            if (retVal == 0 && !LuaDll.lua_isnumber(luaState, stackPos))
            {
                return(null);
            }
            return(retVal);
        }
Beispiel #21
0
        /*
         * Gets the CLR object in the index positon of the Lua stack. Returns
         * delegates as is.
         */
        internal object getRawNetObject(KopiLua.LuaState luaState, int index)
        {
            int udata = LuaDll.luanet_rawnetobj(luaState, index);

            if (udata != -1)
            {
                return(objects[udata]);
            }
            return(null);
        }
Beispiel #22
0
 /*
  * Navigates a table to set the value of one of its fields
  */
 internal void setObject(string[] remainingPath, object val)
 {
     for (int i = 0; i < remainingPath.Length - 1; i++)
     {
         LuaDll.lua_pushstring(luaState, remainingPath[i]);
         LuaDll.lua_gettable(luaState, -2);
     }
     LuaDll.lua_pushstring(luaState, remainingPath[remainingPath.Length - 1]);
     translator.push(luaState, val);
     LuaDll.lua_settable(luaState, -3);
 }
Beispiel #23
0
        /*
         * Compares the two values referenced by ref1 and ref2 for equality
         */
        internal bool compareRef(int ref1, int ref2)
        {
            int top = LuaDll.lua_gettop(luaState);

            LuaDll.lua_getref(luaState, ref1);
            LuaDll.lua_getref(luaState, ref2);
            int equal = LuaDll.lua_equal(luaState, -1, -2);

            LuaDll.lua_settop(luaState, top);
            return(equal != 0);
        }
Beispiel #24
0
 /*
  * Sets up the list of objects in the Lua side
  */
 private void createLuaObjectList(KopiLua.LuaState luaState)
 {
     LuaDll.lua_pushstring(luaState, "luaNet_objects");
     LuaDll.lua_newtable(luaState);
     LuaDll.lua_newtable(luaState);
     LuaDll.lua_pushstring(luaState, "__mode");
     LuaDll.lua_pushstring(luaState, "v");
     LuaDll.lua_settable(luaState, -3);
     LuaDll.lua_setmetatable(luaState, -2);
     LuaDll.lua_settable(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX);
 }
Beispiel #25
0
 /*
  * Pushes the function into the Lua stack
  */
 internal void push(KopiLua.LuaState luaState)
 {
     if (reference != 0)
     {
         LuaDll.lua_getref(luaState, reference);
     }
     else
     {
         interpreter.pushCSFunction(function);
     }
 }
Beispiel #26
0
 /*
  * Creates the metatable for delegates
  */
 private void createFunctionMetatable(KopiLua.LuaState luaState)
 {
     LuaDll.luaL_newmetatable(luaState, "luaNet_function");
     LuaDll.lua_pushstring(luaState, "__gc");
     LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction);
     LuaDll.lua_settable(luaState, -3);
     LuaDll.lua_pushstring(luaState, "__call");
     LuaDll.lua_pushstdcallcfunction(luaState, metaFunctions.execDelegateFunction);
     LuaDll.lua_settable(luaState, -3);
     LuaDll.lua_settop(luaState, -2);
 }
Beispiel #27
0
        /*
         * Gets a field of the table corresponding to the provided reference
         * using rawget (do not use metatables)
         */
        internal object rawGetObject(int reference, string field)
        {
            int oldTop = LuaDll.lua_gettop(luaState);

            LuaDll.lua_getref(luaState, reference);
            LuaDll.lua_pushstring(luaState, field);
            LuaDll.lua_rawget(luaState, -2);
            object obj = translator.getObject(luaState, -1);

            LuaDll.lua_settop(luaState, oldTop);
            return(obj);
        }
Beispiel #28
0
        /*
         * Gets a numeric field of the table or userdata corresponding the the provided reference
         */
        internal object getObject(int reference, object field)
        {
            int oldTop = LuaDll.lua_gettop(luaState);

            LuaDll.lua_getref(luaState, reference);
            translator.push(luaState, field);
            LuaDll.lua_gettable(luaState, -2);
            object returnValue = translator.getObject(luaState, -1);

            LuaDll.lua_settop(luaState, oldTop);
            return(returnValue);
        }
Beispiel #29
0
        /*
         * Gets the CLR object in the index positon of the Lua stack. Returns
         * delegates as Lua functions.
         */
        internal object getNetObject(KopiLua.LuaState luaState, int index)
        {
            int idx = LuaDll.luanet_tonetobject(luaState, index);

            if (idx != -1)
            {
                return(objects[idx]);
            }
            else
            {
                return(null);
            }
        }
Beispiel #30
0
        /*
         * __tostring metafunction of CLR objects.
         */
        private int toString(KopiLua.LuaState luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj != null)
            {
                translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode());
            }
            else
            {
                LuaDll.lua_pushnil(luaState);
            }
            return(1);
        }