Ejemplo n.º 1
0
        private SharpClass CreateClass(Type classType, Type superType, SharpClass module)
        {
            string name = GetTableName(classType);

            LuaNativeFunction dctor = null;

            if (classType.IsValueType)
            {
                if (!classType.IsUnManaged()) //未注册Wrap,用反射版api, UnmanagedType同Object
                {
                    dctor = gcFn;
                }
            }
            else
            {
                dctor = gcFn;
            }

            LuaRef meta      = CreateClass(module.Meta, name, classType, superType, dctor);
            var    bindClass = new SharpClass(module, meta);

            bindClass.Name = name;
            bindClass.SetClassType(classType);
            registeredClass.Add(classType, bindClass);
            return(bindClass);
        }
Ejemplo n.º 2
0
 public void SetMetaTable(LuaRef meta)
 {
     PushToStack();
     meta.PushToStack();
     lua_setmetatable(L, -2);
     lua_pop(L, 1);
 }
Ejemplo n.º 3
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();
        }
Ejemplo n.º 4
0
        public static string GetMemberName(LuaRef parent, string name)
        {
            string full_name = parent.RawGet(___type, "<unknown>");

            full_name += '.';
            full_name += name;
            return(full_name);
        }
Ejemplo n.º 5
0
        public void SetReadOnly(string name)
        {
            LuaRef meta_class = meta;
            string full_name  = LunaNative.GetMemberName(meta_class, name);
            LuaRef err        = LuaRef.CreateFunctionWith(State, LunaNative.ErrorReadOnly, full_name);

            meta_class.RawGet(LunaNative.___setters).RawSet(name, err);
        }
Ejemplo n.º 6
0
        public LuaRef RawGet <K>(K key)
        {
            PushToStack();
            Lua.PushT <K>(L, key);
            lua_rawget(L, -2);
            LuaRef v = Lua.Get <LuaRef>(L, -1);

            lua_pop(L, 2);
            return(v);
        }
Ejemplo n.º 7
0
 public void SetSetter(string name, LuaRef setter)
 {
     if (name == "Item")
     {
         SetMemberFunction(LunaNative.___set_indexed, setter);
     }
     else
     {
         meta.RawGet(LunaNative.___setters).RawSet(name, setter);
     }
 }
Ejemplo n.º 8
0
 public static void Get(lua_State L, int index, out LuaRef v)
 {
     if (lua_isnone(L, index))
     {
         v = LuaRef.None;
     }
     else
     {
         v = new LuaRef(L, index);
     }
 }
Ejemplo n.º 9
0
        public LuaRef GetMetaTable()
        {
            LuaRef meta = LuaRef.None;

            PushToStack();
            if (lua_getmetatable(L, -1) != 0)
            {
                meta = PopFromStack(L);
            }
            lua_pop(L, 1);
            return(meta);
        }
Ejemplo n.º 10
0
        public SharpClass RegMethod(string name, MethodBase[] methodInfo, bool isAsync = false)
        {
            MethodReflection method = new MethodReflection(methodInfo);

#if !IL2CPP
            for (int i = 0; i < methodInfo.Length; i++)
            {
                var mi = methodInfo[i] as MethodInfo;
                if (mi != null)
                {
                    if (DelegateCache.GetMethodDelegate(classType, mi, "CallDel", out CallDel fn, out Delegate del))
                    {
                        method.luaFunc[i] = fn;
                        method.del[i]     = del;
                    }
                }
            }
#endif
            //Luna.Log("反射方式实现");
            LuaRef luaFun = LuaRef.CreateFunction(State, MethodReflection.Call, method);
            if (IsTagMethod(name, out var tag))
            {
                meta.RawSet(tag, luaFun);
            }
            else
            {
                meta.RawSet(name, luaFun);
            }

            if (classType.IsArray)
            {
                if (name == "Get")
                {
                    SetMemberFunction(LunaNative.___get_indexed, luaFun);
                }

                if (name == "Set")
                {
                    SetMemberFunction(LunaNative.___set_indexed, luaFun);
                }
            }

            if (isAsync)
            {
                LuaRef r = new LuaRef(State, "coroutine.__async");
                luaFun = r.Call <LuaRef>(luaFun);

                meta.RawSet("_async_" + name, luaFun);
            }

            return(this);
        }
Ejemplo n.º 11
0
        public LuaRef RegMethod(MethodInfo methodInfo, bool isProp)
        {
#if LUNA_SCRIPT
            string callFnName = (methodInfo.IsStatic && !isProp) ? "StaticCall" : "Call";
#else
            string callFnName = "Call";
#endif
            if (DelegateCache.GetMethodDelegate(classType, methodInfo, callFnName, out LuaNativeFunction luaFunc, out Delegate del))
            {
                return(LuaRef.CreateFunction(State, luaFunc, del));
            }

            return(null);
        }
Ejemplo n.º 12
0
        public SharpModule(SharpModule parent, string name) : base(parent)
        {
            LuaRef parentMeta = parent.meta;
            LuaRef luaref     = parentMeta.RawGet(name) as LuaRef;

            if (luaref)
            {
                meta = luaref;
                return;
            }

            this.parent = parent;
            meta        = LunaNative.create_module(parentMeta.State, parentMeta, name);
            Name        = name;
        }
Ejemplo n.º 13
0
        public static SharpModule Get(SharpModule global, string name)
        {
            if (registeredModule == null)
            {
                registeredModule = new Dictionary <string, SharpModule>();
            }

            if (registeredModule.TryGetValue(name, out var module))
            {
                return(module);
            }

            LuaRef meta = new LuaRef(global.State, name);

            module = new SharpModule(global, name, meta);
            registeredModule.Add(name, module);
            return(module);
        }
Ejemplo n.º 14
0
        public SharpClass RegConstant(FieldInfo field)
        {
            var v = field.GetValue(null);

//             if(field.FieldType.IsEnum)
//             {
//                 LuaRef r = LuaRef.FromValue(State, (int)v);
//                 SetGetter(field.Name, r);
//             }
//             else
            {
                LuaRef r = LuaRef.FromValue(State, v);
                meta.RawSet(field.Name, r);
                //SetGetter(field.Name, r);
            }

            SetReadOnly(field.Name);
            return(this);
        }
Ejemplo n.º 15
0
        public SharpClass RegField(FieldInfo fieldInfo)
        {
            if (classInfo.TryGetValue(fieldInfo.Name, out var methodConfig))
            {
                if (methodConfig.getter != null)
                {
                    var getter = LuaRef.CreateFunction(State, methodConfig.getter);
                    SetGetter(fieldInfo.Name, getter);
                }

                if (methodConfig.setter != null)
                {
                    var setter = LuaRef.CreateFunction(State, methodConfig.setter);
                    SetSetter(fieldInfo.Name, setter);
                }
                else
                {
                    SetReadOnly(fieldInfo.Name);
                }

                return(this);
            }

            //Luna.LogWarning("注册反射版的field : " + fieldInfo.Name);
            if (fieldInfo.IsStatic)
            {
                var getter = LuaRef.CreateFunction(State, Field.StaticGetter, fieldInfo);
                SetGetter(fieldInfo.Name, getter);
                var setter = LuaRef.CreateFunction(State, Field.StaticSetter, fieldInfo);
                SetSetter(fieldInfo.Name, setter);
            }
            else
            {
                var getter = LuaRef.CreateFunction(State, Field.Getter, fieldInfo);
                SetGetter(fieldInfo.Name, getter);
                var setter = LuaRef.CreateFunction(State, Field.Setter, fieldInfo);
                SetSetter(fieldInfo.Name, setter);
            }

            return(this);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 17
0
        public static string GetFullName(LuaRef parent, string name)
        {
            string full_name = parent.RawGet(___type, "");

            if (!string.IsNullOrEmpty(full_name))
            {
                int pos = full_name.IndexOf('<');
                if (pos != -1)
                {
                    full_name.Remove(0, pos + 1);
                }
                pos = full_name.LastIndexOf('>');
                if (pos != -1)
                {
                    full_name.Remove(pos);
                }
                full_name += '.';
            }
            full_name += name;
            return(full_name);
        }
Ejemplo n.º 18
0
        public static LuaRef create_module(lua_State L, LuaRef parentModule, string name)
        {
            int moduleRef = parentModule.Ref;

#if C_API
            int metaRef;
            metaRef = luna_create_module(L, moduleRef, name);
            return(new LuaRef(metaRef, L));
#else
            string fullName = GetFullName(parentModule, name);

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

            meta.RawSet("__index", (LuaNativeFunction)module_index);
            meta.RawSet("__newindex", (LuaNativeFunction)module_newindex);
            meta.RawSet(___getters, LuaRef.CreateTable(L));
            meta.RawSet(___setters, LuaRef.CreateTable(L));
            meta.RawSet(___type, fullName);
            parentModule.RawSet(name, meta);
            return(meta);
#endif
        }
Ejemplo n.º 19
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);
        }
Ejemplo n.º 20
0
        public SharpClass RegProperty(PropertyInfo propertyInfo, bool isIndexer = false)
        {
            if (classInfo.TryGetValue(propertyInfo.Name, out var methodConfig))
            {
                if (methodConfig.getter != null)
                {
                    var getter = LuaRef.CreateFunction(State, methodConfig.getter);
                    SetGetter(propertyInfo.Name, getter);
                }

                if (methodConfig.setter != null)
                {
                    var setter = LuaRef.CreateFunction(State, methodConfig.setter);
                    SetSetter(propertyInfo.Name, setter);
                }
                else
                {
                    SetReadOnly(propertyInfo.Name);
                }

                return(this);
            }

            if (propertyInfo.CanRead)
            {
                MethodInfo methodInfo = propertyInfo.GetGetMethod(false);
                if (methodInfo != null)
                {
#if true//IL2CPP
                    var fn     = methodInfo.IsStatic ? (LuaNativeFunction)Property.StaticGetter : Property.Getter;
                    var getter = LuaRef.CreateFunction(State, fn, propertyInfo);
                    SetGetter(propertyInfo.Name, getter);
#else
                    var luaFun = RegMethod(methodInfo, true);
                    if (luaFun)
                    {
                        SetGetter(propertyInfo.Name, luaFun);
                    }
#endif
                }
            }

            if (propertyInfo.CanWrite)
            {
                MethodInfo methodInfo = propertyInfo.GetSetMethod(false);
                if (methodInfo != null)
                {
#if true//IL2CPP
                    var fn     = methodInfo.IsStatic ? (LuaNativeFunction)Property.StaticSetter : Property.Setter;
                    var setter = LuaRef.CreateFunction(State, fn, propertyInfo);
                    SetSetter(propertyInfo.Name, setter);
#else
                    var luaFun = RegMethod(methodInfo, true);
                    if (luaFun)
                    {
                        SetSetter(propertyInfo.Name, luaFun);
                    }
#endif
                }
            }
            else
            {
                SetReadOnly(propertyInfo.Name);
            }

            return(this);
        }
Ejemplo n.º 21
0
        public void OnRegClass()
        {
            var fields = classType.GetFields();

            foreach (var field in fields)
            {
                if (!field.IsPublic)
                {
                    continue;
                }

                if (field.IsLiteral)
                {
                    RegConstant(field);
                }
                else
                {
                    RegField(field);
                }
            }

            if (classInfo.TryGetValue("ctor", out var methodConfig))
            {
                meta.RawSet("__call", LuaRef.CreateFunction(State, methodConfig.func));
            }
            else
            {
                var ctors = classType.GetConstructors();
                List <MethodBase> memberInfo = new List <MethodBase>();
                foreach (var constructorInfo in ctors)
                {
                    if (!constructorInfo.IsPublic)
                    {
                        continue;
                    }

                    if (!constructorInfo.ShouldExport())
                    {
                        continue;
                    }

                    var paramInfos = constructorInfo.GetParameters();
                    foreach (var info in paramInfos)
                    {
                        if (!info.ParameterType.ShouldExport())
                        {
                            continue;
                        }
                    }

                    memberInfo.Add(constructorInfo);
                }

                if (memberInfo.Count > 0)
                {
                    RegMethod("__call", memberInfo.ToArray());
                }
            }

            var props = classType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);

            foreach (var p in props)
            {
                if (!p.ShouldExport())
                {
                    continue;
                }

                RegProperty(p);
            }

            var methods = classType.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            HashSet <string> registered = new HashSet <string>();

            foreach (var m in methods)
            {
                if (registered.Contains(m.Name))
                {
                    continue;
                }

                bool isAsync = m.GetCustomAttribute <LuaAsyncAttribute>() != null;

                if (classInfo.TryGetValue(m.Name, out methodConfig))
                {
                    if (methodConfig.func != null)
                    {
                        var fn = LuaRef.CreateFunction(State, methodConfig.func);
                        if (IsTagMethod(m.Name, out var tag))
                        {
                            meta.RawSet(tag, fn);
                        }
                        else
                        {
                            meta.RawSet(m.Name, fn);
                        }

                        if (isAsync)
                        {
                            LuaRef r = new LuaRef(State, "coroutine.__async");
                            fn = r.Call <LuaRef>(fn);

                            meta.RawSet("_async_" + m.Name, fn);
                        }

                        if (classType.IsArray)
                        {
                            if (m.Name == "Get")
                            {
                                SetMemberFunction(LunaNative.___get_indexed, fn);
                            }

                            if (m.Name == "Set")
                            {
                                SetMemberFunction(LunaNative.___set_indexed, fn);
                            }
                        }
                    }

                    registered.Add(m.Name);
                    continue;
                }

                if (!m.ShouldExport())
                {
                    continue;
                }

                var memberInfo = classType.GetMember(m.Name).Cast <MethodBase>().ToArray();
                registered.Add(m.Name);
                if (memberInfo.Length > 0)
                {
                    RegMethod(m.Name, memberInfo, isAsync);
                }
            }
        }
Ejemplo n.º 22
0
 public SharpModule(SharpModule parent, string name, LuaRef meta) : base(parent)
 {
     this.meta   = meta;
     this.parent = parent;
     Name        = name;
 }
Ejemplo n.º 23
0
 //GlobalModule
 public SharpModule(Luna luna) : base(null, LuaRef.Globals(luna.State))
 {
     this.luna = luna;
     Name      = "_G";
 }
Ejemplo n.º 24
0
 public void SetMemberFunction(IntPtr name, LuaRef proc)
 {
     meta.RawSet(name, proc);
 }
Ejemplo n.º 25
0
 public SharpClass(SharpClass parent, LuaRef meta)
 {
     this.meta = meta;
     this.meta.CheckTable();
     this.parent = parent;
 }