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); }
public void SetMetaTable(LuaRef meta) { PushToStack(); meta.PushToStack(); lua_setmetatable(L, -2); lua_pop(L, 1); }
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(); }
public static string GetMemberName(LuaRef parent, string name) { string full_name = parent.RawGet(___type, "<unknown>"); full_name += '.'; full_name += name; return(full_name); }
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); }
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); }
public void SetSetter(string name, LuaRef setter) { if (name == "Item") { SetMemberFunction(LunaNative.___set_indexed, setter); } else { meta.RawGet(LunaNative.___setters).RawSet(name, setter); } }
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); } }
public LuaRef GetMetaTable() { LuaRef meta = LuaRef.None; PushToStack(); if (lua_getmetatable(L, -1) != 0) { meta = PopFromStack(L); } lua_pop(L, 1); return(meta); }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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); }
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 }
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); }
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); }
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); } } }
public SharpModule(SharpModule parent, string name, LuaRef meta) : base(parent) { this.meta = meta; this.parent = parent; Name = name; }
//GlobalModule public SharpModule(Luna luna) : base(null, LuaRef.Globals(luna.State)) { this.luna = luna; Name = "_G"; }
public void SetMemberFunction(IntPtr name, LuaRef proc) { meta.RawSet(name, proc); }
public SharpClass(SharpClass parent, LuaRef meta) { this.meta = meta; this.meta.CheckTable(); this.parent = parent; }