예제 #1
0
        public void Start()
        {
            if (ReadBytes == null)
            {
                ReadBytes = System.IO.File.ReadAllBytes;
            }

            L         = Lua.newstate();
            mainState = L;

            luaL_openlibs(L);
            lua_atpanic(L, PanicCallback);

            Register("print", DoPrint);
            Register("dofile", DoFile);
            Register("loadfile", LoadFile);

            errorFuncRef = get_error_func_ref(L);

            AddAssembly(Assembly.GetExecutingAssembly());

            _global = LuaRef.Globals(L);
            _global.Set("luna", LuaRef.CreateTable(L));

            Register("luna.typeof", GetClassType);
            Register("luna.findType", FindClassType);

#if LUNA_SCRIPT
            DoString(coroutineSource);
            DoString(classSource);
            DoString(listSource);
#endif

            _binder = new SharpModule(this);

            AddSearcher(LuaLoader);

            LunaNative.Init(L);
            SharpObject.Init(L);

            RegisterWraps(this.GetType());

            foreach (var moduleInfo in this._config)
            {
                this.RegisterModel(moduleInfo);
            }

            PostInit?.Invoke();

            var it = _classWrapers.GetEnumerator();
            while (it.MoveNext())
            {
                if (!SharpModule.IsRegistered(it.Current.Key))
                {
                    RegisterClass(it.Current.Key);
                }
            }

            //_classWrapers.Clear();
        }
예제 #2
0
        internal static object GetObject(lua_State L, int index)
        {
            LuaType type = lua_type(L, index);

            switch (type)
            {
            case LuaType.Number:
            {
                if (lua_isinteger(L, index))
                {
                    return(lua_tointeger(L, index));
                }

                return(lua_tonumber(L, index));
            }

            case LuaType.String:
                return(lua_tostring(L, index));

            case LuaType.Boolean:
                return((bool)(lua_toboolean(L, index) != 0));

            case LuaType.Table:
            {
                Get(L, index, out LuaRef luaref);
                return(luaref);
            }

            case LuaType.Function:
            {
                Get(L, index, out LuaRef luaref);
                return(luaref);
            }

            case LuaType.LightUserData:
                return(ToLightObject <object>(L, index));

            case LuaType.UserData:
                return(SharpObject.Get <object>(L, index));

            default:
                return(null);
            }
        }
예제 #3
0
        public static LuaRef CreateClass(LuaRef module, string name, Type classType, Type superClass, LuaNativeFunction dctor)
        {
            LuaRef classref = module.RawGet <LuaRef, string>(name);

            if (classref)
            {
                return(classref);
            }

            var meta = LunaNative.create_class(module.State, module, name, classType, dctor);

            if (superClass != null)
            {
                LuaRef registry     = new LuaRef(module.State, LUA_REGISTRYINDEX);
                int    superClassID = SharpObject.TypeID(superClass);
                LuaRef super        = registry.RawGet <LuaRef>(superClassID);
                meta.RawSet(LunaNative.___super, super);
            }

            return(meta);
        }
예제 #4
0
        public static LuaRef create_class(lua_State L, LuaRef parentModule, string name, Type classType, LuaNativeFunction dctor)
        {
            int moduleRef = parentModule.Ref;
            int classId   = SharpObject.TypeID(classType);

#if C_API
            int metaRef = luna_create_class(L, moduleRef, name, classId, dctor.ToFunctionPointer());
            var meta    = new LuaRef(metaRef, L);
#else
            string fullName = GetFullName(parentModule, name);

            LuaRef meta = LuaRef.CreateTable(L);
            meta.SetMetaTable(meta);

            meta.RawSet("__index", (LuaNativeFunction)class_index);
            meta.RawSet("__newindex", (LuaNativeFunction)class_newindex);
            meta.RawSet(___getters, LuaRef.CreateTable(L));
            meta.RawSet(___setters, LuaRef.CreateTable(L));
            meta.RawSet(___type, fullName);

            if (dctor != null)
            {
                meta.RawSet("__gc", dctor);
            }

            if (classId != 0)
            {
                LuaRef registry = LuaRef.Registry(L);
                registry.RawSet(classId, meta);
            }

            parentModule.RawSet(name, meta);
#endif
            meta.RawSet("type", classType);
            return(meta);
        }
예제 #5
0
        public static T Opt <T>(lua_State L, int index, T def)
        {
            switch (def)
            {
            case bool bval:
                return(Converter.To <T>(luaL_optinteger(L, index, bval ? 1 : 0)));

            case sbyte ival:
                return(Converter.To <T>((sbyte)luaL_optinteger(L, index, ival)));

            case byte ival:
                return(Converter.To <T>((byte)luaL_optinteger(L, index, ival)));

            case short ival:
                return(Converter.To <T>((short)luaL_optinteger(L, index, ival)));

            case ushort ival:
                return(Converter.To <T>((ushort)luaL_optinteger(L, index, ival)));

            case char ival:
                return(Converter.To <T>((char)luaL_optinteger(L, index, ival)));

            case int ival:
                return(Converter.To <T>((int)luaL_optinteger(L, index, ival)));

            case uint ival:
                return(Converter.To <T>((uint)luaL_optinteger(L, index, ival)));

            case long ival:
                return(Converter.To <T>(luaL_optinteger(L, index, ival)));

            case ulong ival:
                return(Converter.To <T>((ulong)luaL_optinteger(L, index, (long)ival)));

            case IntPtr ival:
                return(Converter.To <T>((IntPtr)luaL_optinteger(L, index, (long)ival)));

            case UIntPtr ival:
                return(Converter.To <T>((UIntPtr)luaL_optinteger(L, index, (long)ival)));

            case float fval:
                return(Converter.To <T>((float)luaL_optnumber(L, index, fval)));

            case double fval:
                return(Converter.To <T>(luaL_optnumber(L, index, fval)));

            case string strval:
                return((T)(object)luaL_optstring(L, index, strval));

            case LuaNativeFunction fn:
                return(lua_isnoneornil(L, index) ? def : (T)(object)lua_tocfunction(L, index).ToLuaFunction());

            case LuaByteBuffer v:
            {
                if (lua_isnoneornil(L, index))
                {
                    return(def);
                }
                Get(L, index, out LuaByteBuffer buffer);
                return((T)(object)buffer);
            }

            case byte[] v:
            {
                if (lua_isnoneornil(L, index))
                {
                    return(def);
                }
                Get(L, index, out byte[] buffer);
                return((T)(object)buffer);
            }

            case LuaRef luaRef:
                return(lua_isnone(L, index) ? def : Converter.To <T>(new LuaRef(L, index)));

            default:
            {
                if (typeof(T).IsEnum)
                {
                    return(Converter.To <T>((int)luaL_optinteger(L, index, (long)(object)def)));
                }

                if (lua_isnoneornil(L, index))
                {
                    return(def);
                }

                if (typeof(T).IsUnManaged())
                {
                    return(SharpObject.GetUnmanaged <T>(L, index));
                }

                return(SharpObject.Get <T>(L, index));
            }
            }
        }
예제 #6
0
        public static T Get <T>(lua_State L, int index)
        {
            Type t = typeof(T);

            if (t.IsPrimitive)
            {
                if (t == typeof(bool))
                {
                    return(Converter.To <T>((bool)(lua_toboolean(L, index) != 0)));
                }
                else if (t == typeof(char))
                {
                    return(Converter.To <T>((char)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(sbyte))
                {
                    return(Converter.To <T>((sbyte)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(byte))
                {
                    return(Converter.To <T>((byte)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(short))
                {
                    return(Converter.To <T>((short)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(ushort))
                {
                    return(Converter.To <T>((ushort)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(int))
                {
                    return(Converter.To <T>((int)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(uint))
                {
                    return(Converter.To <T>((uint)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(long))
                {
                    return(Converter.To <T>((long)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(ulong))
                {
                    return(Converter.To <T>((ulong)luaL_checkinteger(L, index)));
                }
                else if (t == typeof(float))
                {
                    return(Converter.To <T>((float)luaL_checknumber(L, index)));
                }
                else if (t == typeof(double))
                {
                    return(Converter.To <T>(luaL_checknumber(L, index)));
                }
                else
                {
                    throw new Exception("Error type");
                }
            }
            else if (t == typeof(IntPtr))
            {
                return(Converter.To <T>((IntPtr)luaL_checkinteger(L, index)));
            }
            else if (t == typeof(UIntPtr))
            {
                return(Converter.To <T>((UIntPtr)luaL_checkinteger(L, index)));
            }
            else if (t == typeof(string))
            {
                return((T)(object)lua_checkstring(L, index));
            }
            else if (t == typeof(LuaNativeFunction))
            {
                return((T)(object)lua_tocfunction(L, index).ToLuaFunction());
            }
            else if (t == typeof(LuaByteBuffer))
            {
                Get(L, index, out LuaByteBuffer buffer);
                return((T)(object)buffer);
            }
            else if (t == typeof(byte[]))
            {
                Get(L, index, out byte[] buffer);
                return((T)(object)buffer);
            }
            else if (t == typeof(LuaRef))
            {
                if (lua_isnone(L, index))
                {
                    return((T)(object)null);// Convert.To<T>(LuaRef.None);
                }
                else
                {
                    return(Converter.To <T>(new LuaRef(L, index)));
                }
            }
            else
            {
                if (t == typeof(object))
                {
                    return((T)GetObject(L, index));
                }
                else if (t.IsEnum)
                {
                    if (lua_type(L, index) == LuaType.Number)
                    {
                        return(Converter.To <T>((int)luaL_checkinteger(L, index)));
                    }
                }
                else if (t.IsValueType)
                {
                    if (t.IsUnManaged())
                    {
                        return(SharpObject.GetUnmanaged <T>(L, index));
                    }
                }

                return(SharpObject.Get <T>(L, index));
            }
        }
예제 #7
0
 public static void Get <T>(lua_State L, int index, out T v) => v = SharpObject.Get <T>(L, index);
예제 #8
0
 public static void Get(lua_State L, int index, out object v) => v = SharpObject.Get <object>(L, index);
예제 #9
0
        internal static object GetObject(lua_State L, int index, Type objtype)
        {
            if (objtype == typeof(float))
            {
                return((float)lua_tonumber(L, index));
            }
            if (objtype == typeof(double))
            {
                return(lua_tonumber(L, index));
            }
            else if (objtype == typeof(int))
            {
                return((int)lua_tonumber(L, index));
            }
            else if (objtype == typeof(uint))
            {
                return((uint)lua_tonumber(L, index));
            }
            else if (objtype == typeof(short))
            {
                return((short)lua_tonumber(L, index));
            }
            else if (objtype == typeof(ushort))
            {
                return((ushort)lua_tonumber(L, index));
            }
            else if (objtype == typeof(sbyte))
            {
                return((sbyte)lua_tonumber(L, index));
            }
            else if (objtype == typeof(byte))
            {
                return((byte)lua_tonumber(L, index));
            }
            else if (objtype == typeof(string))
            {
                return(lua_tostring(L, index));
            }
            else if (objtype == typeof(bool))
            {
                return((bool)(lua_toboolean(L, index) != 0));
            }
            else if (objtype == typeof(IntPtr))
            {
                return((IntPtr)lua_tonumber(L, index));
            }
            else if (objtype == typeof(UIntPtr))
            {
                return((uint)lua_tonumber(L, index));
            }
            else if (objtype == typeof(LuaNativeFunction))
            {
                return(lua_tocfunction(L, index).ToLuaFunction());
            }
            else if (objtype == typeof(byte[]))
            {
                Get(L, index, out byte[] v);
                return(v);
            }
            else if (objtype == typeof(LuaByteBuffer))
            {
                Get(L, index, out LuaByteBuffer v);
                return(v);
            }
            else if (objtype == typeof(LuaRef))
            {
                LuaType type = lua_type(L, index);
                var     obj  = Converter.Convert(objtype, type, L, index);
                if (obj != null)
                {
                    return(obj);
                }
                Get(L, index, out LuaRef luaref);
                return(luaref);
            }
            else if (objtype == typeof(object))
            {
                return(GetObject(L, index));
            }
            else
            {
                if (objtype.IsEnum)
                {
                    return((int)lua_tonumber(L, index));
                }
                if (objtype.IsValueType)
                {
                    if (objtype.IsUnManaged())
                    {
                        return(SharpObject.GetUnmanaged(L, index, objtype));
                    }
                }

                return(SharpObject.Get(L, index, objtype));
            }
        }
예제 #10
0
        public static void PushT <T>(lua_State L, T v)
        {
            switch (v)
            {
            case bool bval:
                lua_pushboolean(L, bval ? 1 : 0);
                break;

            case long lval:
                lua_pushinteger(L, lval);
                break;

            case ulong lval:
                lua_pushinteger(L, (long)lval);
                break;

            case IntPtr lval:
                lua_pushinteger(L, (long)lval);
                break;

            case UIntPtr lval:
                lua_pushinteger(L, (long)lval);
                break;

            case sbyte ival:
                lua_pushnumber(L, ival);
                break;

            case byte ival:
                lua_pushnumber(L, ival);
                break;

            case short ival:
                lua_pushnumber(L, ival);
                break;

            case ushort ival:
                lua_pushnumber(L, ival);
                break;

            case int ival:
                lua_pushnumber(L, ival);
                break;

            case uint ival:
                lua_pushnumber(L, ival);
                break;

            case float fval:
                lua_pushnumber(L, fval);
                break;

            case double dval:
                lua_pushnumber(L, dval);
                break;

            case string strval:
                lua_pushstring(L, strval);
                break;

            case LuaNativeFunction fn:
                lua_pushcfunction(L, fn);
                break;

            case LuaRef luaRef:
                if (luaRef.IsValid)
                {
                    luaRef.PushToStack();
                }
                else
                {
                    lua_pushnil(L);
                }
                break;

            case byte[] bytes:
                Push(L, bytes);
                break;

            case LuaByteBuffer bytes:
                Push(L, bytes);
                break;

            default:
                if (v == null)
                {
                    lua_pushnil(L);
                    break;
                }
                Type t = v.GetType();
                if (t.IsEnum)
                {
                    //SharpObject.PushToStack(L, v);
                    lua_pushinteger(L, (int)(object)v);
                    return;
                }
                else if (t.IsValueType)
                {
                    SharpObject.PushValueType(L, v);
                }
                else
                {
                    SharpObject.PushObject(L, v);
                }
                break;
            }
        }
예제 #11
0
 public static void Push <T>(lua_State L, ref T v) where T : struct => SharpObject.PushValueType(L, ref v);
예제 #12
0
 public static void Push <T>(lua_State L, T v) => SharpObject.PushObject(L, v);
예제 #13
0
        public static void Push(lua_State L, object obj)
        {
            Type t = obj.GetType();

            if (t.IsPrimitive)
            {
                if (t == typeof(bool))
                {
                    lua_pushboolean(L, ((bool)obj) ? 1 : 0);
                }
                else if (t == typeof(long))
                {
                    lua_pushinteger(L, (long)obj);
                }
                else if (t == typeof(ulong))
                {
                    lua_pushinteger(L, (long)(ulong)obj);
                }
                else if (t == typeof(sbyte))
                {
                    lua_pushinteger(L, (long)(sbyte)obj);
                }
                else if (t == typeof(byte))
                {
                    lua_pushnumber(L, (double)(byte)obj);
                }
                else if (t == typeof(short))
                {
                    lua_pushnumber(L, (double)(short)obj);
                }
                else if (t == typeof(ushort))
                {
                    lua_pushnumber(L, (double)(ushort)obj);
                }
                else if (t == typeof(char))
                {
                    lua_pushnumber(L, (double)(char)obj);
                }
                else if (t == typeof(int))
                {
                    lua_pushnumber(L, (double)(int)obj);
                }
                else if (t == typeof(uint))
                {
                    lua_pushnumber(L, (double)(uint)obj);
                }
                else if (t == typeof(float))
                {
                    lua_pushnumber(L, (double)(float)obj);
                }
                else if (t == typeof(double))
                {
                    lua_pushnumber(L, (double)obj);
                }
                else
                {
                    throw new Exception("未知类型");
                }
            }
            else if (t == typeof(IntPtr))
            {
                lua_pushinteger(L, (long)(IntPtr)obj);
            }
            else if (t == typeof(UIntPtr))
            {
                lua_pushinteger(L, (long)(UIntPtr)obj);
            }
            else if (t == typeof(string))
            {
                lua_pushstring(L, (string)obj);
            }
            else if (t == typeof(LuaNativeFunction))
            {
                lua_pushcfunction(L, (LuaNativeFunction)obj);
            }
            else if (t == typeof(byte[]))
            {
                Push(L, (byte[])obj);
            }
            else if (t == typeof(LuaByteBuffer))
            {
                Push(L, (LuaByteBuffer)obj);
            }
            else if (t == typeof(LuaRef))
            {
                var luaRef = (LuaRef)obj;
                if (luaRef.IsValid)
                {
                    luaRef.PushToStack();
                }
                else
                {
                    lua_pushnil(L);
                }
            }
            else
            {
                if (t.IsEnum)
                {
                    lua_pushinteger(L, (int)(object)obj);
                    //SharpObject.PushToStack(L, obj);
                }
                else if (t.IsValueType)
                {
                    SharpObject.PushValueType(L, obj);
                }
                else
                {
                    SharpObject.PushObject(L, obj);
                }
            }
        }
예제 #14
0
 static int DestructorStruct(lua_State L)
 {
     SharpObject.FreeStruct(L, 1);
     return(0);
 }