Esempio n. 1
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(LuaCore.lua_State luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj.IsNull())
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaLib.lua_pushnil(luaState);
                LuaLib.lua_pushboolean(luaState, false);
                return(2);
            }

            string methodName = LuaLib.lua_tostring(luaState, 2).ToString();

            if (methodName.IsNull())
            {
                LuaLib.lua_pushnil(luaState);
                LuaLib.lua_pushboolean(luaState, false);
                return(2);
            }

            getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance | BindingFlags.IgnoreCase);
            LuaLib.lua_settop(luaState, -2);

            if (LuaLib.lua_type(luaState, -1) == LuaTypes.Nil)
            {
                LuaLib.lua_settop(luaState, -2);
                return(getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase));
            }

            LuaLib.lua_pushboolean(luaState, false);
            return(2);
        }
Esempio n. 2
0
        /*
         * CAUTION: LuaInterface.Lua instances can't share the same lua state!
         */
        public Lua(LuaCore.lua_State lState)
        {
            LuaLib.lua_pushstring(lState, "LUAINTERFACE LOADED");
            LuaLib.lua_gettable(lState, (int)LuaIndexes.Registry);

            if (LuaLib.lua_toboolean(lState, -1))
            {
                LuaLib.lua_settop(lState, -2);
                throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state");
            }
            else
            {
                LuaLib.lua_settop(lState, -2);
                LuaLib.lua_pushstring(lState, "LUAINTERFACE LOADED");
                LuaLib.lua_pushboolean(lState, true);
                LuaLib.lua_settable(lState, (int)LuaIndexes.Registry);
                luaState = lState;
                LuaLib.lua_pushvalue(lState, (int)LuaIndexes.Globals);
                LuaLib.lua_getglobal(lState, "luanet");
                LuaLib.lua_pushstring(lState, "getmetatable");
                LuaLib.lua_getglobal(lState, "getmetatable");
                LuaLib.lua_settable(lState, -3);
                LuaLib.lua_replace(lState, (int)LuaIndexes.Globals);
                translator = new ObjectTranslator(this, luaState);
                LuaLib.lua_replace(lState, (int)LuaIndexes.Globals);
                LuaLib.luaL_dostring(lState, Lua.init_luanet);                  // steffenj: lua_dostring renamed to luaL_dostring
            }

            _StatePassed = true;
        }
Esempio n. 3
0
        public Lua()
        {
            luaState = LuaLib.luaL_newstate();                  // steffenj: Lua 5.1.1 API change (lua_open is gone)
            //LuaLib.luaopen_base(luaState);	// steffenj: luaopen_* no longer used
            LuaLib.luaL_openlibs(luaState);                     // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here)
            LuaLib.lua_pushstring(luaState, "LUAINTERFACE LOADED");
            LuaLib.lua_pushboolean(luaState, true);
            LuaLib.lua_settable(luaState, (int)LuaIndexes.Registry);
            LuaLib.lua_newtable(luaState);
            LuaLib.lua_setglobal(luaState, "luanet");
            LuaLib.lua_pushvalue(luaState, (int)LuaIndexes.Globals);
            LuaLib.lua_getglobal(luaState, "luanet");
            LuaLib.lua_pushstring(luaState, "getmetatable");
            LuaLib.lua_getglobal(luaState, "getmetatable");
            LuaLib.lua_settable(luaState, -3);
            LuaLib.lua_replace(luaState, (int)LuaIndexes.Globals);
            translator = new ObjectTranslator(this, luaState);
            LuaLib.lua_replace(luaState, (int)LuaIndexes.Globals);
            LuaLib.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 LuaCore.lua_CFunction(PanicCallback);
            LuaLib.lua_atpanic(luaState, panicCallback);

            //LuaLib.lua_atlock(luaState, lockCallback = new LuaCore.lua_CFunction(LockCallback));
            //LuaLib.lua_atunlock(luaState, unlockCallback = new LuaCore.lua_CFunction(UnlockCallback));
        }
Esempio n. 4
0
 /*
  * Pushes the object into the Lua stack according to its type.
  */
 internal void push(LuaCore.lua_State luaState, object o)
 {
     if (o.IsNull())
     {
         LuaLib.lua_pushnil(luaState);
     }
     else if (o is sbyte || o is byte || o is short || o is ushort ||
              o is int || o is uint || o is long || o is float ||
              o is ulong || o is decimal || o is double)
     {
         double d = Convert.ToDouble(o);
         LuaLib.lua_pushnumber(luaState, d);
     }
     else if (o is char)
     {
         double d = (char)o;
         LuaLib.lua_pushnumber(luaState, d);
     }
     else if (o is string)
     {
         string str = (string)o;
         LuaLib.lua_pushstring(luaState, str);
     }
     else if (o is bool)
     {
         bool b = (bool)o;
         LuaLib.lua_pushboolean(luaState, b);
     }
     else if (IsILua(o))
     {
         (((ILuaGeneratedType)o).__luaInterface_getLuaTable()).push(luaState);
     }
     else if (o is LuaTable)
     {
         ((LuaTable)o).push(luaState);
     }
     else if (o is LuaCore.lua_CFunction)
     {
         pushFunction(luaState, (LuaCore.lua_CFunction)o);
     }
     else if (o is LuaFunction)
     {
         ((LuaFunction)o).push(luaState);
     }
     else
     {
         pushObject(luaState, o, "luaNet_metatable");
     }
 }
Esempio n. 5
0
        /*
         * Called by the __index metafunction of CLR objects in case the
         * method is not cached or it is a field/property/event.
         * Receives the object and the member name as arguments and returns
         * either the value of the member or a delegate to call it.
         * If the member does not exist returns nil.
         */
        private int getMethod(LuaCore.lua_State luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj.IsNull())
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaLib.lua_pushnil(luaState);
                return(1);
            }

            object index = translator.getObject(luaState, 2);
            //var indexType = index.GetType();
            string methodName = index as string;                        // will be null if not a string arg
            var    objType    = obj.GetType();

            // Handle the most common case, looking up the method by name.

            // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
            // ie: xmlelement['item'] <- item is a property of xmlelement
            try
            {
                if (!methodName.IsNull() && isMemberPresent(objType, methodName))
                {
                    return(getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase));
                }
            }
            catch
            {
            }

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                int intIndex = (int)((double)index);

                if (objType.UnderlyingSystemType == typeof(float[]))
                {
                    float[] arr = ((float[])obj);
                    translator.push(luaState, arr[intIndex]);
                }
                else if (objType.UnderlyingSystemType == typeof(double[]))
                {
                    double[] arr = ((double[])obj);
                    translator.push(luaState, arr[intIndex]);
                }
                else if (objType.UnderlyingSystemType == typeof(int[]))
                {
                    int[] arr = ((int[])obj);
                    translator.push(luaState, arr[intIndex]);
                }
                else
                {
                    object[] arr = (object[])obj;
                    translator.push(luaState, arr[intIndex]);
                }
            }
            else
            {
                // Try to use get_Item to index into this .net object
                //MethodInfo getter = objType.GetMethod("get_Item");
                var methods = objType.GetMethods();

                foreach (var mInfo in methods)
                {
                    if (mInfo.Name == "get_Item")
                    {
                        //check if the signature matches the input
                        if (mInfo.GetParameters().Length == 1)
                        {
                            var getter      = mInfo;
                            var actualParms = (!getter.IsNull()) ? getter.GetParameters() : null;

                            if (actualParms.IsNull() || actualParms.Length != 1)
                            {
                                translator.throwError(luaState, "method not found (or no indexer): " + index);
                                LuaLib.lua_pushnil(luaState);
                            }
                            else
                            {
                                // Get the index in a form acceptable to the getter
                                index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);
                                object[] args = new object[1];

                                // Just call the indexer - if out of bounds an exception will happen
                                args[0] = index;

                                try
                                {
                                    object result = getter.Invoke(obj, args);
                                    translator.push(luaState, result);
                                }
                                catch (TargetInvocationException e)
                                {
                                    // Provide a more readable description for the common case of key not found
                                    if (e.InnerException is KeyNotFoundException)
                                    {
                                        translator.throwError(luaState, "key '" + index + "' not found ");
                                    }
                                    else
                                    {
                                        translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
                                    }

                                    LuaLib.lua_pushnil(luaState);
                                }
                            }
                        }
                    }
                }
            }

            LuaLib.lua_pushboolean(luaState, false);
            return(2);
        }