예제 #1
0
        public bool ProtectedCall(int args, int errfunc)
        {
            if (!state.IsMainThread())
            {
                Logger.LogError("Can't call lua function in bg thread");
                return(false);
            }

            LuaNativeMethods.lua_getref(VariablePointer, valueref);

            if (!LuaNativeMethods.lua_isfunction(VariablePointer, -1))
            {
                LuaNativeMethods.lua_pop(VariablePointer, 1);
                throw new Exception("Call invalid function.");
            }

            LuaNativeMethods.lua_insert(VariablePointer, -args - 1);
            if (LuaNativeMethods.lua_pcall(VariablePointer, args, -1, errfunc) != 0)
            {
                LuaNativeMethods.lua_pop(VariablePointer, 1);
                return(false);
            }

            return(true);
        }
예제 #2
0
        public static int GetOpFunction(IntPtr ptr, string f, string tip)
        {
            int err = PushTry(ptr);

            CheckLuaObject(ptr, 1);

            while (!LuaNativeMethods.lua_isnil(ptr, -1))
            {
                LuaNativeMethods.lua_getfield(ptr, -1, f);
                if (!LuaNativeMethods.lua_isnil(ptr, -1))
                {
                    LuaNativeMethods.lua_remove(ptr, -2);
                    break;
                }

                LuaNativeMethods.lua_pop(ptr, 1);     // pop nil
                LuaNativeMethods.lua_getfield(ptr, -1, "__parent");
                LuaNativeMethods.lua_remove(ptr, -2); // pop base
            }

            if (LuaNativeMethods.lua_isnil(ptr, -1))
            {
                LuaNativeMethods.lua_pop(ptr, 1);
                throw new Exception(string.Format("No {0} operator", tip));
            }

            return(err);
        }
예제 #3
0
        public static ObjectCache Get(IntPtr ptr)
        {
            if (oldPtr == ptr)
            {
                return(Oldoc);
            }

            ObjectCache oc;

            if (multiState.TryGetValue(ptr, out oc))
            {
                oldPtr = ptr;
                Oldoc  = oc;
                return(oc);
            }

            LuaNativeMethods.lua_getglobal(ptr, "__main_state");
            if (LuaNativeMethods.lua_isnil(ptr, -1))
            {
                LuaNativeMethods.lua_pop(ptr, 1);
                return(null);
            }

            IntPtr nl = LuaNativeMethods.lua_touserdata(ptr, -1);

            LuaNativeMethods.lua_pop(ptr, 1);

            if (nl != ptr)
            {
                return(Get(nl));
            }

            return(null);
        }
예제 #4
0
        public bool DoBuffer(byte[] bytes, string fn, out object ret)
        {
            // ensure no utf-8 bom, LuaJIT can read BOM, but Lua cannot!
            bytes = CleanUTF8Bom(bytes);
            ret   = null;
            int errfunc = LuaObject.PushTry(statePointer);

            if (LuaNativeMethods.luaL_loadbuffer(statePointer, bytes, bytes.Length, fn) == 0)
            {
                if (LuaNativeMethods.lua_pcall(statePointer, 0, LuaNativeMethods.LUAMultRet, errfunc) != 0)
                {
                    LuaNativeMethods.lua_pop(statePointer, 2);
                    return(false);
                }

                LuaNativeMethods.lua_remove(statePointer, errfunc); // pop error function
                ret = TopObjects(errfunc - 1);
                return(true);
            }

            string err = LuaNativeMethods.lua_tostring(statePointer, -1);

            LuaNativeMethods.lua_pop(statePointer, 2);
            throw new Exception("File " + fn + ": " + err);
        }
예제 #5
0
        public static bool CheckArray <T>(IntPtr ptr, int p, out T[] ta)
        {
            if (LuaNativeMethods.lua_type(ptr, p) == LuaTypes.TYPE_TABLE)
            {
                int n = LuaNativeMethods.lua_rawlen(ptr, p);
                ta = new T[n];
                for (int k = 0; k < n; k++)
                {
                    LuaNativeMethods.lua_rawgeti(ptr, p, k + 1);
                    object o     = CheckVar(ptr, -1);
                    Type   fromT = o.GetType();
                    Type   toT   = typeof(T);

                    if (toT.IsAssignableFrom(fromT))
                    {
                        ta[k] = (T)o;
                    }
                    else
                    {
                        ta[k] = (T)Convert.ChangeType(o, typeof(T));
                    }

                    LuaNativeMethods.lua_pop(ptr, 1);
                }

                return(true);
            }
            else
            {
                Array array = CheckObj(ptr, p) as Array;
                ta = array as T[];
                return(ta != null);
            }
        }
예제 #6
0
        public static int MakeArray(IntPtr ptr)
        {
            try
            {
                Type t;
                CheckType(ptr, 1, out t);
                LuaNativeMethods.luaL_checktype(ptr, 2, LuaTypes.TYPE_TABLE);
                int   n     = LuaNativeMethods.lua_rawlen(ptr, 2);
                Array array = Array.CreateInstance(t, n);
                for (int k = 0; k < n; k++)
                {
                    LuaNativeMethods.lua_rawgeti(ptr, 2, k + 1);
                    object obj = LuaObject.CheckVar(ptr, -1);
                    array.SetValue(LuaObject.ChangeType(obj, t), k);
                    LuaNativeMethods.lua_pop(ptr, 1);
                }

                LuaObject.PushValue(ptr, true);
                LuaObject.PushValue(ptr, array);
                return(2);
            }
            catch (Exception e)
            {
                return(Error(ptr, e));
            }
        }
예제 #7
0
            public bool MoveNext()
            {
                if (tableIndex < 0)
                {
                    return(false);
                }

                if (iterPhase == 0)
                {
                    LuaNativeMethods.lua_pushnil(table.VariablePointer);
                    iterPhase = 1;
                }
                else
                {
                    LuaNativeMethods.lua_pop(table.VariablePointer, 1);
                }

                // var ty = LuaDLL.lua_type(t.L, -1);
                bool ret = LuaNativeMethods.lua_next(table.VariablePointer, tableIndex) > 0;

                if (!ret)
                {
                    iterPhase = 2;
                }

                return(ret);
            }
예제 #8
0
        public static LuaState Get(IntPtr ptr)
        {
            if (ptr == oldptr)
            {
                return(oldstate);
            }

            LuaState ls;

            if (statemap.TryGetValue(ptr, out ls))
            {
                oldptr   = ptr;
                oldstate = ls;
                return(ls);
            }

            LuaNativeMethods.lua_getglobal(ptr, "__main_state");
            if (LuaNativeMethods.lua_isnil(ptr, -1))
            {
                LuaNativeMethods.lua_pop(ptr, 1);
                return(null);
            }

            IntPtr nl = LuaNativeMethods.lua_touserdata(ptr, -1);

            LuaNativeMethods.lua_pop(ptr, 1);
            if (nl != ptr)
            {
                return(Get(nl));
            }

            return(null);
        }
예제 #9
0
        public static bool CheckType(IntPtr ptr, int p, out LuaDelegate f)
        {
            LuaState state = LuaState.Get(ptr);

            p = LuaNativeMethods.lua_absindex(ptr, p);
            LuaNativeMethods.luaL_checktype(ptr, p, LuaTypes.TYPE_FUNCTION);

            LuaNativeMethods.lua_getglobal(ptr, DelgateTable);
            LuaNativeMethods.lua_pushvalue(ptr, p);
            LuaNativeMethods.lua_gettable(ptr, -2); // find function in __LuaDelegate table

            if (LuaNativeMethods.lua_isnil(ptr, -1))
            {                                     // not found
                LuaNativeMethods.lua_pop(ptr, 1); // pop nil
                f = NewDelegate(ptr, p);
            }
            else
            {
                int fref = LuaNativeMethods.lua_tointeger(ptr, -1);
                LuaNativeMethods.lua_pop(ptr, 1); // pop ref value;
                f = state.DelegateMap[fref];
                if (f == null)
                {
                    f = NewDelegate(ptr, p);
                }
            }

            LuaNativeMethods.lua_pop(ptr, 1); // pop DelgateTable
            return(true);
        }
예제 #10
0
        public object TopObjects(int from)
        {
            int top  = LuaNativeMethods.lua_gettop(statePointer);
            int args = top - from;

            if (args == 0)
            {
                return(null);
            }
            else if (args == 1)
            {
                object o = LuaObject.CheckVar(statePointer, top);
                LuaNativeMethods.lua_pop(statePointer, 1);
                return(o);
            }
            else
            {
                object[] o = new object[args];
                for (int n = 1; n <= args; n++)
                {
                    o[n - 1] = LuaObject.CheckVar(statePointer, from + n);
                }

                LuaNativeMethods.lua_settop(statePointer, from);
                return(o);
            }
        }
예제 #11
0
 public static void RemoveDelgate(IntPtr ptr, int r)
 {
     LuaNativeMethods.lua_getglobal(ptr, DelgateTable);
     LuaNativeMethods.lua_getref(ptr, r);    // push key
     LuaNativeMethods.lua_pushnil(ptr);      // push nil value
     LuaNativeMethods.lua_settable(ptr, -3); // remove function from __LuaDelegate table
     LuaNativeMethods.lua_pop(ptr, 1);       // pop __LuaDelegate
 }
예제 #12
0
        public object GetObject(string key)
        {
            LuaNativeMethods.lua_pushglobaltable(statePointer);
            object o = GetObject(key.Split(new char[] { '.' }));

            LuaNativeMethods.lua_pop(statePointer, 1);
            return(o);
        }
예제 #13
0
 public static void CheckLuaObject(IntPtr ptr, int p)
 {
     LuaNativeMethods.lua_getmetatable(ptr, p);
     if (LuaNativeMethods.lua_isnil(ptr, -1))
     {
         LuaNativeMethods.lua_pop(ptr, 1);
         throw new Exception("expect luaobject as first argument");
     }
 }
예제 #14
0
        public static void Register(IntPtr ptr, LuaCSFunction func, string ns)
        {
            CheckMethodValid(func);

            NewTypeTable(ptr, ns);
            PushValue(ptr, func);
            LuaNativeMethods.lua_setfield(ptr, -2, func.Method.Name);
            LuaNativeMethods.lua_pop(ptr, 1);
        }
예제 #15
0
            public void Dispose()
            {
                if (iterPhase == 1)
                {
                    LuaNativeMethods.lua_pop(table.VariablePointer, 2);
                }

                LuaNativeMethods.lua_remove(table.VariablePointer, tableIndex);
            }
예제 #16
0
        public static bool CheckType(IntPtr ptr, int p, out Type t)
        {
            string   tname = null;
            LuaTypes lt    = LuaNativeMethods.lua_type(ptr, p);

            switch (lt)
            {
            case LuaTypes.TYPE_USERDATA:
                object o = CheckObj(ptr, p);
                if (o.GetType() != monoType)
                {
                    throw new Exception(string.Format("{0} expect Type, got {1}", p, o.GetType().Name));
                }

                t = (Type)o;
                return(true);

            case LuaTypes.TYPE_TABLE:
                LuaNativeMethods.lua_pushstring(ptr, "__type");
                LuaNativeMethods.lua_rawget(ptr, p);
                if (!LuaNativeMethods.lua_isnil(ptr, -1))
                {
                    t = (Type)CheckObj(ptr, -1);
                    LuaNativeMethods.lua_pop(ptr, 1);
                    return(true);
                }
                else
                {
                    LuaNativeMethods.lua_pushstring(ptr, "__fullname");
                    LuaNativeMethods.lua_rawget(ptr, p);
                    tname = LuaNativeMethods.lua_tostring(ptr, -1);
                    LuaNativeMethods.lua_pop(ptr, 2);
                }

                break;

            case LuaTypes.TYPE_STRING:
                CheckType(ptr, p, out tname);
                break;
            }

            if (tname == null)
            {
                throw new Exception("expect string or type table");
            }

            t = LuaObject.FindType(tname);
            if (t != null && lt == LuaTypes.TYPE_TABLE)
            {
                LuaNativeMethods.lua_pushstring(ptr, "__type");
                PushLightObject(ptr, t);
                LuaNativeMethods.lua_rawset(ptr, p);
            }

            return(t != null);
        }
예제 #17
0
        public static int Equals(LuaVar lhs, LuaVar rhs)
        {
            // TODO: CHECK IF THIS IS ACTUALLY CORRECT?
            lhs.Push(lhs.VariablePointer);
            rhs.Push(lhs.VariablePointer);
            int ok = LuaNativeMethods.lua_equal(lhs.VariablePointer, -1, -2);

            LuaNativeMethods.lua_pop(lhs.VariablePointer, 2);
            return(ok);
        }
예제 #18
0
        public static void ProtectedCall(IntPtr ptr, LuaCSFunction f)
        {
            int err = LuaObject.PushTry(ptr);

            LuaNativeMethods.lua_pushcfunction(ptr, f);
            if (LuaNativeMethods.lua_pcall(ptr, 0, 0, err) != 0)
            {
                LuaNativeMethods.lua_pop(ptr, 1);
            }

            LuaNativeMethods.lua_remove(ptr, err);
        }
예제 #19
0
        public static int LuaUnaryOp(IntPtr ptr, string f, string tip)
        {
            int err = GetOpFunction(ptr, f, tip);

            LuaNativeMethods.lua_pushvalue(ptr, 1);
            if (LuaNativeMethods.lua_pcall(ptr, 1, 1, err) != 0)
            {
                LuaNativeMethods.lua_pop(ptr, 1);
            }

            LuaNativeMethods.lua_remove(ptr, err);
            PushValue(ptr, true);
            LuaNativeMethods.lua_insert(ptr, -2);
            return(2);
        }
예제 #20
0
        public static int Import(IntPtr ptr)
        {
            try
            {
                LuaNativeMethods.luaL_checktype(ptr, 1, LuaTypes.TYPE_STRING);
                string str = LuaNativeMethods.lua_tostring(ptr, 1);

                string[] ns = str.Split('.');

                LuaNativeMethods.lua_pushglobaltable(ptr);

                for (int n = 0; n < ns.Length; n++)
                {
                    LuaNativeMethods.lua_getfield(ptr, -1, ns[n]);
                    if (!LuaNativeMethods.lua_istable(ptr, -1))
                    {
                        return(LuaObject.Error(ptr, "expect {0} is type table", ns));
                    }

                    LuaNativeMethods.lua_remove(ptr, -2);
                }

                LuaNativeMethods.lua_pushnil(ptr);
                while (LuaNativeMethods.lua_next(ptr, -2) != 0)
                {
                    string key = LuaNativeMethods.lua_tostring(ptr, -2);
                    LuaNativeMethods.lua_getglobal(ptr, key);
                    if (!LuaNativeMethods.lua_isnil(ptr, -1))
                    {
                        LuaNativeMethods.lua_pop(ptr, 1);
                        return(LuaObject.Error(ptr, "{0} had existed, import can't overload it.", key));
                    }

                    LuaNativeMethods.lua_pop(ptr, 1);
                    LuaNativeMethods.lua_setglobal(ptr, key);
                }

                LuaNativeMethods.lua_pop(ptr, 1);

                LuaObject.PushValue(ptr, true);
                return(1);
            }
            catch (Exception e)
            {
                return(LuaObject.Error(ptr, e));
            }
        }
예제 #21
0
        public static bool IsTypeTable(IntPtr ptr, int p)
        {
            if (LuaNativeMethods.lua_type(ptr, p) != LuaTypes.TYPE_TABLE)
            {
                return(false);
            }

            LuaNativeMethods.lua_pushstring(ptr, "__fullname");
            LuaNativeMethods.lua_rawget(ptr, p);
            if (LuaNativeMethods.lua_isnil(ptr, -1))
            {
                LuaNativeMethods.lua_pop(ptr, 1);
                return(false);
            }

            return(true);
        }
예제 #22
0
 public void SetObject(int reference, int index, object o)
 {
     if (index >= 1)
     {
         LuaNativeMethods.lua_getref(statePointer, reference);
         LuaObject.PushVar(statePointer, o);
         LuaNativeMethods.lua_rawseti(statePointer, -2, index);
         LuaNativeMethods.lua_pop(statePointer, 1);
     }
     else
     {
         LuaNativeMethods.lua_getref(statePointer, reference);
         LuaNativeMethods.lua_pushinteger(statePointer, index);
         LuaObject.PushVar(statePointer, o);
         LuaNativeMethods.lua_settable(statePointer, -3);
         LuaNativeMethods.lua_pop(statePointer, 1);
     }
 }
예제 #23
0
 public object GetObject(int reference, int index)
 {
     if (index >= 1)
     {
         LuaNativeMethods.lua_getref(statePointer, reference);
         LuaNativeMethods.lua_rawgeti(statePointer, -1, index);
         object returnValue = GetObject(statePointer, -1);
         LuaNativeMethods.lua_pop(statePointer, 2);
         return(returnValue);
     }
     else
     {
         LuaNativeMethods.lua_getref(statePointer, reference);
         LuaNativeMethods.lua_pushinteger(statePointer, index);
         LuaNativeMethods.lua_gettable(statePointer, -2);
         object returnValue = GetObject(statePointer, -1);
         LuaNativeMethods.lua_pop(statePointer, 2);
         return(returnValue);
     }
 }
예제 #24
0
        public static void CreateTypeMetatable(IntPtr ptr, LuaCSFunction con, Type self, Type parent)
        {
            CheckMethodValid(con);

            // set parent
            bool parentSet = false;

            LuaNativeMethods.lua_pushstring(ptr, "__parent");
            while (parent != null && parent != typeof(object) && parent != typeof(ValueType))
            {
                LuaNativeMethods.luaL_getmetatable(ptr, ObjectCache.GetAQName(parent));
                // if parentType is not exported to lua
                if (LuaNativeMethods.lua_isnil(ptr, -1))
                {
                    LuaNativeMethods.lua_pop(ptr, 1);
                    parent = parent.BaseType;
                }
                else
                {
                    LuaNativeMethods.lua_rawset(ptr, -3);

                    LuaNativeMethods.lua_pushstring(ptr, "__parent");
                    LuaNativeMethods.luaL_getmetatable(ptr, parent.FullName);
                    LuaNativeMethods.lua_rawset(ptr, -4);

                    parentSet = true;
                    break;
                }
            }

            if (!parentSet)
            {
                LuaNativeMethods.luaL_getmetatable(ptr, "__luabaseobject");
                LuaNativeMethods.lua_rawset(ptr, -3);
            }

            CompleteInstanceMeta(ptr, self);
            CompleteTypeMeta(ptr, con, self);

            LuaNativeMethods.lua_pop(ptr, 1); // pop type Table
        }
예제 #25
0
        public static int PrintError(IntPtr ptr)
        {
            int n = LuaNativeMethods.lua_gettop(ptr);

            s.Length = 0;

            LuaNativeMethods.lua_getglobal(ptr, "tostring");

            for (int i = 1; i <= n; i++)
            {
                if (i > 1)
                {
                    s.Append("    ");
                }

                LuaNativeMethods.lua_pushvalue(ptr, -1);
                LuaNativeMethods.lua_pushvalue(ptr, i);

                LuaNativeMethods.lua_call(ptr, 1, 1);
                s.Append(LuaNativeMethods.lua_tostring(ptr, -1));
                LuaNativeMethods.lua_pop(ptr, 1);
            }

            LuaNativeMethods.lua_settop(ptr, n);

            LuaNativeMethods.lua_getglobal(ptr, "debug");
            LuaNativeMethods.lua_getfield(ptr, -1, "traceback");
            LuaNativeMethods.lua_call(ptr, 0, 1);
            s.Append("\n");
            s.Append(LuaNativeMethods.lua_tostring(ptr, -1));
            LuaNativeMethods.lua_pop(ptr, 1);
            Logger.LogError(s.ToString(), true);

            if (ErrorEvent != null)
            {
                ErrorEvent(s.ToString());
            }

            return(0);
        }
예제 #26
0
        public static void NewTypeTable(IntPtr ptr, string name)
        {
            string[] subt = name.Split('.');

            LuaNativeMethods.lua_pushglobaltable(ptr);

            foreach (string t in subt)
            {
                LuaNativeMethods.lua_pushstring(ptr, t);
                LuaNativeMethods.lua_rawget(ptr, -2);
                if (LuaNativeMethods.lua_isnil(ptr, -1))
                {
                    LuaNativeMethods.lua_pop(ptr, 1);
                    LuaNativeMethods.lua_createtable(ptr, 0, 0);
                    LuaNativeMethods.lua_pushstring(ptr, t);
                    LuaNativeMethods.lua_pushvalue(ptr, -2);
                    LuaNativeMethods.lua_rawset(ptr, -4);
                }

                LuaNativeMethods.lua_remove(ptr, -2);
            }
        }
예제 #27
0
        public static int ExtractFunction(IntPtr ptr, int p)
        {
            int      op = 0;
            LuaTypes t  = LuaNativeMethods.lua_type(ptr, p);

            switch (t)
            {
            case LuaTypes.TYPE_NIL:
            case LuaTypes.TYPE_USERDATA:
                op = 0;
                break;

            case LuaTypes.TYPE_TABLE:

                LuaNativeMethods.lua_rawgeti(ptr, p, 1);
                LuaNativeMethods.lua_pushstring(ptr, "+=");
                if (LuaNativeMethods.lua_rawequal(ptr, -1, -2) == 1)
                {
                    op = 1;
                }
                else
                {
                    op = 2;
                }

                LuaNativeMethods.lua_pop(ptr, 2);
                LuaNativeMethods.lua_rawgeti(ptr, p, 2);
                break;

            case LuaTypes.TYPE_FUNCTION:
                LuaNativeMethods.lua_pushvalue(ptr, p);
                break;

            default:
                throw new Exception("expect valid Delegate");
            }

            return(op);
        }
예제 #28
0
        public static int ErrorReport(IntPtr ptr)
        {
            LuaNativeMethods.lua_getglobal(ptr, "debug");
            LuaNativeMethods.lua_getfield(ptr, -1, "traceback");
            LuaNativeMethods.lua_pushvalue(ptr, 1);
            LuaNativeMethods.lua_pushnumber(ptr, 2);
            LuaNativeMethods.lua_call(ptr, 2, 1);
            LuaNativeMethods.lua_remove(ptr, -2);
            string error = LuaNativeMethods.lua_tostring(ptr, -1);

            LuaNativeMethods.lua_pop(ptr, 1);

            Logger.LogError(error, true);
            if (ErrorEvent != null)
            {
                ErrorEvent(error);
            }

            LuaNativeMethods.lua_getglobal(ptr, "dumpstack");
            LuaNativeMethods.lua_call(ptr, 0, 0);

            return(0);
        }
예제 #29
0
 public void SetObject(string key, object v)
 {
     LuaNativeMethods.lua_pushglobaltable(statePointer);
     SetObject(key.Split(new char[] { '.' }), v);
     LuaNativeMethods.lua_pop(statePointer, 1);
 }