public static int ImportType(RealStatePtr L) { try { ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); string className = LuaAPI.lua_tostring(L, 1); Type type = translator.FindType(className); if (type != null) { if (translator.GetTypeId(L, type) >= 0) { LuaAPI.lua_pushboolean(L, true); } else { return(LuaAPI.luaL_error(L, "can not load type " + type)); } } else { LuaAPI.lua_pushnil(L); } return(1); } catch (System.Exception e) { return(LuaAPI.luaL_error(L, "c# exception in xlua.import_type:" + e)); } }
public void ReleaseLuaBase(RealStatePtr L, int reference, bool is_delegate) { if (is_delegate) { LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, reference); if (LuaAPI.lua_isnil(L, -1)) { LuaAPI.lua_pop(L, 1); } else { LuaAPI.lua_pushvalue(L, -1); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); if (LuaAPI.lua_type(L, -1) == LuaTypes.LUA_TNUMBER && LuaAPI.xlua_tointeger(L, -1) == reference) // { //UnityEngine.Debug.LogWarning("release delegate ref = " + luaReference); LuaAPI.lua_pop(L, 1); // pop LUA_REGISTRYINDEX[func] LuaAPI.lua_pushnil(L); LuaAPI.lua_rawset(L, LuaIndexes.LUA_REGISTRYINDEX); // LUA_REGISTRYINDEX[func] = nil } else //another Delegate ref the function before the GC tick { LuaAPI.lua_pop(L, 2); // pop LUA_REGISTRYINDEX[func] & func } } LuaAPI.lua_unref(L, reference); delegate_bridges.Remove(reference); } else { LuaAPI.lua_unref(L, reference); } }
public static void LoadCSTable(RealStatePtr L, Type type) { int oldTop = LuaAPI.lua_gettop(L); if (0 != LuaAPI.xlua_getglobal(L, "CS")) { throw new Exception("call xlua_getglobal fail!"); } List <string> path = getPathOfType(type); for (int i = 0; i < path.Count; ++i) { LuaAPI.xlua_pushasciistring(L, path[i]); if (0 != LuaAPI.xlua_pgettable(L, -2)) { LuaAPI.lua_settop(L, oldTop); LuaAPI.lua_pushnil(L); return; } if (!LuaAPI.lua_istable(L, -1) && i < path.Count - 1) { LuaAPI.lua_settop(L, oldTop); LuaAPI.lua_pushnil(L); return; } LuaAPI.lua_remove(L, -2); } }
public void ForEach <TKey, TValue>(Action <TKey, TValue> action) { #if THREAD_SAFE || HOTFIX_ENABLE lock (luaEnv.luaEnvLock) { #endif var L = luaEnv.L; var translator = luaEnv.translator; int oldTop = LuaAPI.lua_gettop(L); try { LuaAPI.lua_getref(L, luaReference); LuaAPI.lua_pushnil(L); while (LuaAPI.lua_next(L, -2) != 0) { if (translator.Assignable <TKey>(L, -2)) { TKey key; TValue val; translator.Get(L, -2, out key); translator.Get(L, -1, out val); action(key, val); } LuaAPI.lua_pop(L, 1); } } finally { LuaAPI.lua_settop(L, oldTop); } #if THREAD_SAFE || HOTFIX_ENABLE } #endif }
public void WriteCookieAll(string ext_path) { List <string> table_list = new List <string>(); LuaAPI.xlua_getglobal(m_lua_state, DefineConstantsCookieHandler.COOKIE_VAR); int nIndex = LuaAPI.lua_gettop(m_lua_state); LuaAPI.lua_pushnil(m_lua_state); // nil入栈作为初始key while (0 != LuaAPI.lua_next(m_lua_state, nIndex)) { LuaAPI.lua_pushvalue(m_lua_state, -2); if (LuaAPI.lua_isstring(m_lua_state, -1)) { table_list.Add(LuaAPI.lua_tostring(m_lua_state, -1)); } LuaAPI.lua_pop(m_lua_state, 2); } LuaAPI.lua_pop(m_lua_state, 1); List <string> .Enumerator itr = table_list.GetEnumerator(); while (itr.MoveNext()) { Debug.LogWarning("WriteCookieAll :" + itr.ToString()); WriteCookie(itr.ToString(), itr.ToString(), ext_path); } }
internal static bool CheckCircleAndSetMeta(IntPtr L, ref int cycle_time) { int now_top = LuaAPI.lua_gettop(L); // 堆栈操作保护 int nIndex = LuaAPI.lua_gettop(L); // 取table索引值 if (!LuaAPI.lua_istable(L, nIndex)) { LuaAPI.lua_settop(L, now_top); Debug.Log("CheckCircleAndSetMeta Need Table!"); return(false); } LuaAPI.lua_pushnil(L); // nil入栈作为初始key while (0 != LuaAPI.lua_next(L, nIndex)) { // 现在栈顶(-1)是value,-2位置是对应的key // 这里可以判断key是什么并且对value进行各种处理 // key值只能是数字或者字符串 if (LuaAPI.lua_isnumber(L, -2) && LuaAPI.lua_isstring(L, -2)) { LuaAPI.lua_settop(L, now_top); Debug.Log("Need Number or String Here!"); return(false); } if (LuaAPI.lua_isnumber(L, -1) && LuaAPI.lua_isstring(L, -1) && !LuaAPI.lua_istable(L, -1) && !LuaAPI.lua_isboolean(L, -1)) { LuaAPI.lua_settop(L, now_top); Debug.Log("Table Contains Unsupported Value! Expected [Number, String, Table]."); return(false); } if (LuaAPI.lua_istable(L, -1)) { cycle_time += 1; if (cycle_time > 50) { Debug.Log("Table Has Cycle!"); LuaAPI.lua_settop(L, now_top); return(false); } if (!CheckCircleAndSetMeta(L, ref cycle_time) || !SetMetaTable(L, nIndex)) { LuaAPI.lua_settop(L, now_top); return(false); } } LuaAPI.lua_pop(L, 1); } LuaAPI.lua_settop(L, now_top); return(true); }
public void Push(RealStatePtr L, LuaBase o) { if (o == null) { LuaAPI.lua_pushnil(L); } else { o.push(L); } }
static void PackRow(RealStatePtr L, SqliteDataReader data_reader, string table_name, bool has_column_info, List <xc.DBManager.ColumnInfo> column_info, int field_count) { for (int i = 0; i < field_count; ++i) { string field_name = ""; Type field_type = null; if (has_column_info) { field_name = column_info[i].name; field_type = column_info[i].type; } else { field_name = data_reader.GetName(i); field_type = data_reader.GetFieldType(i); if (column_info != null) { var info = new xc.DBManager.ColumnInfo(); info.name = field_name; info.type = field_type; column_info.Add(info); } } LuaAPI.lua_pushstring(L, field_name); if (field_type.Equals(typeof(string))) { var str = data_reader.GetString(i); // 如果指定列有中文,则通过翻译表的文本进行替换 var hasChineseChars = xc.DBCharIndex.Instance.HasChineseChars(table_name, field_name); if (hasChineseChars) { str = xc.DBTranslate.Instance.GetTranslateText(table_name, str); } LuaAPI.lua_pushstring(L, str); } else if (field_type.IsValueType) { LuaAPI.lua_pushnumber(L, Convert.ToDouble(data_reader.GetValue(i))); } else { LuaAPI.lua_pushnil(L); } LuaAPI.lua_rawset(L, -3); } }
internal void PushFixCSFunction(RealStatePtr L, LuaCSFunction func) { if (func == null) { LuaAPI.lua_pushnil(L); } else { LuaAPI.xlua_pushinteger(L, fix_cs_functions.Count); fix_cs_functions.Add(func); LuaAPI.lua_pushstdcallcfunction(L, metaFunctions.FixCSFunctionWraper, 1); } }
public void PushAny(RealStatePtr L, object o) { if (o == null) { LuaAPI.lua_pushnil(L); return; } Type type = o.GetType(); if (type.IsPrimitive) { pushPrimitive(L, o); } else if (o is string) { LuaAPI.lua_pushstring(L, o as string); } else if (o is byte[]) { LuaAPI.lua_pushstring(L, o as byte[]); } else if (o is decimal) { PushDecimal(L, (decimal)o); } else if (o is LuaBase) { ((LuaBase)o).push(L); } else if (o is LuaCSFunction) { Push(L, o as LuaCSFunction); } else if (o is ValueType) { PushCSObject push; if (custom_push_funcs.TryGetValue(o.GetType(), out push)) { push(L, o); } else { Push(L, o); } } else { Push(L, o); } }
public static int GetGenericMethod(RealStatePtr L) { try { ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); Type type = getType(L, translator, 1); if (type == null) { return(LuaAPI.luaL_error(L, "xlua.get_generic_method, can not find c# type")); } string methodName = LuaAPI.lua_tostring(L, 2); if (string.IsNullOrEmpty(methodName)) { return(LuaAPI.luaL_error(L, "xlua.get_generic_method, #2 param need a string")); } System.Collections.Generic.List <MethodInfo> matchMethods = new System.Collections.Generic.List <MethodInfo>(); var allMethods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); for (int i = 0; i < allMethods.Length; i++) { var method = allMethods[i]; if (method.Name == methodName && method.IsGenericMethodDefinition) { matchMethods.Add(method); } } int methodIdx = 0; if (matchMethods.Count == 0) { LuaAPI.lua_pushnil(L); } else { if (LuaAPI.lua_isinteger(L, 3)) { methodIdx = LuaAPI.xlua_tointeger(L, 3); } translator.PushAny(L, matchMethods[methodIdx]); LuaAPI.lua_pushstdcallcfunction(L, GenericMethodWraper, 1); } } catch (Exception e) { return(LuaAPI.luaL_error(L, "c# exception in xlua.get_generic_method: " + e)); } return(1); }
public IEnumerable GetKeys() { var L = luaEnv.L; var translator = luaEnv.translator; int oldTop = LuaAPI.lua_gettop(L); LuaAPI.lua_getref(L, luaReference); LuaAPI.lua_pushnil(L); while (LuaAPI.lua_next(L, -2) != 0) { yield return(translator.GetObject(L, -2)); LuaAPI.lua_pop(L, 1); } LuaAPI.lua_settop(L, oldTop); }
public static int ImportGenericType(RealStatePtr L) { try { int top = LuaAPI.lua_gettop(L); if (top < 2) { return(LuaAPI.luaL_error(L, "import generic type need at lease 2 arguments")); } ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); string className = LuaAPI.lua_tostring(L, 1); if (className.EndsWith("<>")) { className = className.Substring(0, className.Length - 2); } Type genericDef = translator.FindType(className + "`" + (top - 1)); if (genericDef == null || !genericDef.IsGenericTypeDefinition()) { LuaAPI.lua_pushnil(L); } else { Type[] typeArguments = new Type[top - 1]; for (int i = 2; i <= top; i++) { typeArguments[i - 2] = getType(L, translator, i); if (typeArguments[i - 2] == null) { return(LuaAPI.luaL_error(L, "param need a type")); } } Type genericInc = genericDef.MakeGenericType(typeArguments); translator.GetTypeId(L, genericInc); translator.PushAny(L, genericInc); } return(1); } catch (System.Exception e) { return(LuaAPI.luaL_error(L, "c# exception in xlua.import_type:" + e)); } }
public void TryForEach <TKey>(Type type_of_value, Action <TKey, object, bool> action) { #if THREAD_SAFE || HOTFIX_ENABLE lock (luaEnv.luaEnvLock) { #endif var L = luaEnv.L; var translator = luaEnv.translator; int oldTop = LuaAPI.lua_gettop(L); try { LuaAPI.lua_getref(L, luaReference); LuaAPI.lua_pushnil(L); while (LuaAPI.lua_next(L, -2) != 0) { if (translator.Assignable <TKey>(L, -2)) { bool isAssignable = translator.Assignable(L, -1, type_of_value); if (isAssignable) { TKey key; object val; translator.Get(L, -2, out key); translator.Get(L, -1, out val); action(key, val, isAssignable); } else { action(default(TKey), null, isAssignable); } } LuaAPI.lua_pop(L, 1); } } finally { LuaAPI.lua_settop(L, oldTop); } #if THREAD_SAFE || HOTFIX_ENABLE } #endif }
public IEnumerable <T> GetKeys <T>() { var L = luaEnv.L; var translator = luaEnv.translator; int oldTop = LuaAPI.lua_gettop(L); LuaAPI.lua_getref(L, luaReference); LuaAPI.lua_pushnil(L); while (LuaAPI.lua_next(L, -2) != 0) { if (translator.Assignable <T>(L, -2)) { T v; translator.Get(L, -2, out v); yield return(v); } LuaAPI.lua_pop(L, 1); } LuaAPI.lua_settop(L, oldTop); }
public void PushObject(RealStatePtr L, object o, int type_id) { if (o == null) { LuaAPI.lua_pushnil(L); return; } int index = -1; if (reverseMap.TryGetValue(o, out index)) { if (LuaAPI.xlua_tryget_cachedud(L, index, cacheRef) == 1) { return; } } index = addObject(o, false, false); LuaAPI.xlua_pushcsobj(L, index, type_id, true, cacheRef); }
public void Push(RealStatePtr L, object o) { if (o == null) { LuaAPI.lua_pushnil(L); return; } int index = -1; Type type = o.GetType(); bool is_enum = type.IsEnum; bool is_valuetype = type.IsValueType; bool needcache = !is_valuetype || is_enum; if (needcache && (is_enum ? enumMap.TryGetValue(o, out index) : reverseMap.TryGetValue(o, out index))) { if (LuaAPI.xlua_tryget_cachedud(L, index, cacheRef) == 1) { return; } //这里实在太经典了,weaktable先删除,然后GC会延迟调用,当index会循环利用的时候,不注释这行将会导致重复释放 //collectObject(index); } bool is_first; int type_id = getTypeId(L, type, out is_first); //如果一个type的定义含本身静态readonly实例时,getTypeId会push一个实例,这时候应该用这个实例 if (is_first && needcache && (is_enum ? enumMap.TryGetValue(o, out index) : reverseMap.TryGetValue(o, out index))) { if (LuaAPI.xlua_tryget_cachedud(L, index, cacheRef) == 1) { return; } } index = addObject(o, is_valuetype, is_enum); LuaAPI.xlua_pushcsobj(L, index, type_id, needcache, cacheRef); }
public static void BeginClassRegister(Type type, RealStatePtr L, LuaCSFunction creator, int class_field_count, int static_getter_count, int static_setter_count) { LuaAPI.lua_createtable(L, 0, class_field_count); int cls_table = LuaAPI.lua_gettop(L); SetCSTable(L, type, cls_table); LuaAPI.lua_createtable(L, 0, 3); int meta_table = LuaAPI.lua_gettop(L); if (creator != null) { LuaAPI.xlua_pushasciistring(L, "__call"); LuaAPI.lua_pushstdcallcfunction(L, creator); LuaAPI.lua_rawset(L, -3); } if (static_getter_count == 0) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_createtable(L, 0, static_getter_count); } if (static_setter_count == 0) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_createtable(L, 0, static_setter_count); } LuaAPI.lua_pushvalue(L, meta_table); LuaAPI.lua_setmetatable(L, cls_table); }
public static int ImportType(RealStatePtr L) { ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); string className = LuaAPI.lua_tostring(L, 1); Type type = translator.FindType(className); if (type != null) { if (translator.TryDelayWrapLoader(L, type)) { LuaAPI.lua_pushboolean(L, true); } else { return(LuaAPI.luaL_error(L, "can not load type " + type)); } } else { LuaAPI.lua_pushnil(L); } return(1); }
public static void EndObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, LuaCSFunction csIndexer, LuaCSFunction csNewIndexer, Type base_type, LuaCSFunction arrayIndexer, LuaCSFunction arrayNewIndexer) { int top = LuaAPI.lua_gettop(L); int meta_idx = abs_idx(top, OBJ_META_IDX); int method_idx = abs_idx(top, METHOD_IDX); int getter_idx = abs_idx(top, GETTER_IDX); int setter_idx = abs_idx(top, SETTER_IDX); //begin index gen LuaAPI.xlua_pushasciistring(L, "__index"); LuaAPI.lua_pushvalue(L, method_idx); LuaAPI.lua_pushvalue(L, getter_idx); if (csIndexer == null) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_pushstdcallcfunction(L, csIndexer); } translator.Push(L, type == null ? base_type : type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); if (arrayIndexer == null) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_pushstdcallcfunction(L, arrayIndexer); } LuaAPI.gen_obj_indexer(L); if (type != null) { LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); } LuaAPI.lua_rawset(L, meta_idx); //end index gen //begin newindex gen LuaAPI.xlua_pushasciistring(L, "__newindex"); LuaAPI.lua_pushvalue(L, setter_idx); if (csNewIndexer == null) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_pushstdcallcfunction(L, csNewIndexer); } translator.Push(L, type == null ? base_type : type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); if (arrayNewIndexer == null) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_pushstdcallcfunction(L, arrayNewIndexer); } LuaAPI.gen_obj_newindexer(L); if (type != null) { LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); } LuaAPI.lua_rawset(L, meta_idx); //end new index gen LuaAPI.lua_pop(L, 4); }
protected bool SerializeTableType(ref ByteBuffer write_file, string parent_str) { int now_top = LuaAPI.lua_gettop(m_lua_state); // 堆栈操作保护 string field_str_buff = new string(new char[1024]); string write_buff = new string(new char[1024]); int nIndex = LuaAPI.lua_gettop(m_lua_state); // 取table索引值 if (!LuaAPI.lua_istable(m_lua_state, nIndex)) { LuaAPI.lua_settop(m_lua_state, now_top); Debug.Log("Need Table Here!"); return(false); } string my_name_str; LuaAPI.lua_pushnil(m_lua_state); // nil入栈作为初始key while (0 != LuaAPI.lua_next(m_lua_state, nIndex)) { // 现在栈顶(-1)是value,-2位置是对应的key // 这里可以判断key是什么并且对value进行各种处理 // 写key值 LuaAPI.lua_pushvalue(m_lua_state, -2); if (SerializeBasicType(ref field_str_buff) != 0) { write_buff = string.Format("{0}[{1}]", parent_str, field_str_buff); my_name_str = write_buff; } else { LuaAPI.lua_settop(m_lua_state, now_top); return(false); } LuaAPI.lua_pop(m_lua_state, 1); if (LuaAPI.lua_isnumber(m_lua_state, -1) || LuaAPI.lua_isstring(m_lua_state, -1) || LuaAPI.lua_isboolean(m_lua_state, -1)) { if (SerializeBasicType(ref field_str_buff) != 0) { write_buff = string.Format("{0} = {1}\n", my_name_str, field_str_buff); write_file.WriteText(write_buff); } else { LuaAPI.lua_settop(m_lua_state, now_top); return(false); } } else if (LuaAPI.lua_istable(m_lua_state, -1)) { write_buff = string.Format("{0} = {1} or {{}}\n", my_name_str, my_name_str); write_file.WriteText(write_buff); if (!SerializeTableType(ref write_file, my_name_str)) { LuaAPI.lua_settop(m_lua_state, now_top); return(false); } } else { Debug.Log("This Type Cannot Write to Cookies!Need[Table, Number, String]!"); } LuaAPI.lua_pop(m_lua_state, 1); // 弹出value,让key留在栈顶 } LuaAPI.lua_settop(m_lua_state, now_top); return(true); }
private ObjectCast genCaster(Type type) { ObjectCast fixTypeGetter = (RealStatePtr L, int idx, object target) => { if (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA) { object obj = translator.SafeGetCSObj(L, idx); return((obj != null && type.IsAssignableFrom(obj.GetType())) ? obj : null); } return(null); }; if (typeof(Delegate).IsAssignableFrom(type)) { return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } if (!LuaAPI.lua_isfunction(L, idx)) { return null; } return translator.CreateDelegateBridge(L, type, idx); }); } else if (type.IsInterface) { return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } if (!LuaAPI.lua_istable(L, idx)) { return null; } return translator.CreateInterfaceBridge(L, type, idx); }); } else if (type.IsEnum) { return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } LuaTypes lua_type = LuaAPI.lua_type(L, idx); if (lua_type == LuaTypes.LUA_TSTRING) { return Enum.Parse(type, LuaAPI.lua_tostring(L, idx)); } else if (lua_type == LuaTypes.LUA_TNUMBER) { return Enum.ToObject(type, LuaAPI.xlua_tointeger(L, idx)); } throw new InvalidCastException("invalid value for enum " + type); }); } else if (type.IsArray) { return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } if (!LuaAPI.lua_istable(L, idx)) { return null; } uint len = LuaAPI.xlua_objlen(L, idx); int n = LuaAPI.lua_gettop(L); idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index Type et = type.GetElementType(); ObjectCast elementCaster = GetCaster(et); Array ary = target == null?Array.CreateInstance(et, len) : target as Array; if (!LuaAPI.lua_checkstack(L, 1)) { throw new Exception("stack overflow while cast to Array"); } for (int i = 0; i < len; ++i) { LuaAPI.lua_pushnumber(L, i + 1); LuaAPI.lua_rawget(L, idx); if (et.IsPrimitive) { if (!StaticLuaCallbacks.TryPrimitiveArraySet(type, L, ary, i, n + 1)) { ary.SetValue(elementCaster(L, n + 1, null), i); } } else { if (StaticLuaCallbacks.GenTryArraySetPtr == null || !StaticLuaCallbacks.GenTryArraySetPtr(type, L, translator, ary, i, n + 1)) { ary.SetValue(elementCaster(L, n + 1, null), i); } } LuaAPI.lua_pop(L, 1); } return ary; }); } else if (typeof(IList).IsAssignableFrom(type) && type.IsGenericType) { ObjectCast elementCaster = GetCaster(type.GetGenericArguments()[0]); return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } if (!LuaAPI.lua_istable(L, idx)) { return null; } obj = target == null?Activator.CreateInstance(type) : target; int n = LuaAPI.lua_gettop(L); idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index IList list = obj as IList; uint len = LuaAPI.xlua_objlen(L, n); if (!LuaAPI.lua_checkstack(L, 1)) { throw new Exception("stack overflow while cast to IList"); } for (int i = 0; i < len; ++i) { LuaAPI.lua_pushnumber(L, i + 1); LuaAPI.lua_rawget(L, idx); if (i < list.Count && target != null) { var item = elementCaster(L, n + 1, list[i]); if (item != null) { list[i] = item; } } else { var item = elementCaster(L, n + 1, null); if (item != null) { list.Add(item); } } LuaAPI.lua_pop(L, 1); } return obj; }); } else if (typeof(IDictionary).IsAssignableFrom(type) && type.IsGenericType) { ObjectCast keyCaster = GetCaster(type.GetGenericArguments()[0]); ObjectCast valueCaster = GetCaster(type.GetGenericArguments()[1]); return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } if (!LuaAPI.lua_istable(L, idx)) { return null; } IDictionary dic = (target == null ? Activator.CreateInstance(type) : target) as IDictionary; int n = LuaAPI.lua_gettop(L); idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index LuaAPI.lua_pushnil(L); if (!LuaAPI.lua_checkstack(L, 1)) { throw new Exception("stack overflow while cast to IDictionary"); } while (LuaAPI.lua_next(L, idx) != 0) { object k = keyCaster(L, n + 1, null); // -2:key if (k != null) { object v = valueCaster(L, n + 2, !dic.Contains(k) ? null : dic[k]); if (v != null) { dic[k] = v; // -1:value } } LuaAPI.lua_pop(L, 1); // removes value, keeps key for next iteration } return dic; }); } else if ((type.IsClass && type.GetConstructor(System.Type.EmptyTypes) != null) || (type.IsValueType && !type.IsEnum)) //class has default construtor { return((RealStatePtr L, int idx, object target) => { object obj = fixTypeGetter(L, idx, target); if (obj != null) { return obj; } if (!LuaAPI.lua_istable(L, idx)) { return null; } obj = target == null?Activator.CreateInstance(type) : target; int n = LuaAPI.lua_gettop(L); idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index if (!LuaAPI.lua_checkstack(L, 1)) { throw new Exception("stack overflow while cast to " + type); } /*foreach (PropertyInfo prop in type.GetProperties()) * { * LuaAPI.xlua_pushasciistring(L, prop.Name); * LuaAPI.lua_rawget(L, idx); * if (!LuaAPI.lua_isnil(L, -1)) * { * try * { * prop.SetValue(obj, GetCaster(prop.PropertyType)(L, n + 1, * target == null || prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string) ? null : prop.GetValue(obj, null)), null); * } * catch (Exception e) * { * throw new Exception("exception in tran " + prop.Name + ", msg=" + e.Message); * } * } * LuaAPI.lua_pop(L, 1); * }*/ foreach (FieldInfo field in type.GetFields()) { LuaAPI.xlua_pushasciistring(L, field.Name); LuaAPI.lua_rawget(L, idx); if (!LuaAPI.lua_isnil(L, -1)) { try { field.SetValue(obj, GetCaster(field.FieldType)(L, n + 1, target == null || field.FieldType.IsPrimitive || field.FieldType == typeof(string) ? null : field.GetValue(obj))); } catch (Exception e) { throw new Exception("exception in tran " + field.Name + ", msg=" + e.Message); } } LuaAPI.lua_pop(L, 1); } return obj; }); } else { return(fixTypeGetter); } }
public static void ReflectionWrap(RealStatePtr L, Type type) { int top_enter = LuaAPI.lua_gettop(L); ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); //create obj meta table LuaAPI.luaL_getmetatable(L, type.FullName); if (LuaAPI.lua_isnil(L, -1)) { LuaAPI.lua_pop(L, 1); LuaAPI.luaL_newmetatable(L, type.FullName); } LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag()); LuaAPI.lua_pushnumber(L, 1); LuaAPI.lua_rawset(L, -3); int obj_meta = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_meta = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int obj_field = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int obj_getter = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int obj_setter = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_field = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_getter = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_setter = LuaAPI.lua_gettop(L); LuaCSFunction item_getter; LuaCSFunction item_setter; makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta, out item_getter, out item_setter); // init obj metatable LuaAPI.xlua_pushasciistring(L, "__gc"); LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta); LuaAPI.lua_rawset(L, obj_meta); LuaAPI.xlua_pushasciistring(L, "__tostring"); LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta); LuaAPI.lua_rawset(L, obj_meta); LuaAPI.xlua_pushasciistring(L, "__index"); LuaAPI.lua_pushvalue(L, obj_field); LuaAPI.lua_pushvalue(L, obj_getter); translator.PushFixCSFunction(L, item_getter); translator.PushAny(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.lua_pushnil(L); LuaAPI.gen_obj_indexer(L); //store in lua indexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, obj_meta); // set __index LuaAPI.xlua_pushasciistring(L, "__newindex"); LuaAPI.lua_pushvalue(L, obj_setter); translator.PushFixCSFunction(L, item_setter); translator.Push(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.lua_pushnil(L); LuaAPI.gen_obj_newindexer(L); //store in lua newindexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, obj_meta); // set __newindex //finish init obj metatable LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType"); translator.PushAny(L, type); LuaAPI.lua_rawset(L, cls_field); if (type != null && type.IsEnum) { LuaAPI.xlua_pushasciistring(L, "__CastFrom"); translator.PushFixCSFunction(L, genEnumCastFrom(type)); LuaAPI.lua_rawset(L, cls_field); } //set cls_field to namespace SetCSTable(L, type, cls_field); //finish set cls_field to namespace //init class meta LuaAPI.xlua_pushasciistring(L, "__index"); LuaAPI.lua_pushvalue(L, cls_getter); LuaAPI.lua_pushvalue(L, cls_field); translator.Push(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.gen_cls_indexer(L); //store in lua indexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, cls_meta); // set __index LuaAPI.xlua_pushasciistring(L, "__newindex"); LuaAPI.lua_pushvalue(L, cls_setter); translator.Push(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.gen_cls_newindexer(L); //store in lua newindexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, cls_meta); // set __newindex LuaCSFunction constructor = translator.methodWrapsCache.GetConstructorWrap(type); if (constructor == null) { constructor = (RealStatePtr LL) => { return(LuaAPI.luaL_error(LL, "No constructor for " + type)); }; } LuaAPI.xlua_pushasciistring(L, "__call"); translator.PushFixCSFunction(L, constructor); LuaAPI.lua_rawset(L, cls_meta); LuaAPI.lua_pushvalue(L, cls_meta); LuaAPI.lua_setmetatable(L, cls_field); LuaAPI.lua_pop(L, 8); System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L)); }
//meta: -4, method:-3, getter: -2, setter: -1 public static void BeginObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, int meta_count, int method_count, int getter_count, int setter_count, int type_id = -1) { if (type == null) { if (type_id == -1) { throw new Exception("Fatal: must provide a type of type_id"); } LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id); } else { LuaAPI.luaL_getmetatable(L, type.FullName); if (LuaAPI.lua_isnil(L, -1)) { LuaAPI.lua_pop(L, 1); LuaAPI.luaL_newmetatable(L, type.FullName); } } LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag()); LuaAPI.lua_pushnumber(L, 1); LuaAPI.lua_rawset(L, -3); if ((type == null || !translator.HasCustomOp(type)) && type != typeof(decimal)) { LuaAPI.xlua_pushasciistring(L, "__gc"); LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta); LuaAPI.lua_rawset(L, -3); } LuaAPI.xlua_pushasciistring(L, "__tostring"); LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta); LuaAPI.lua_rawset(L, -3); if (method_count == 0) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_createtable(L, 0, method_count); } if (getter_count == 0) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_createtable(L, 0, getter_count); } if (setter_count == 0) { LuaAPI.lua_pushnil(L); } else { LuaAPI.lua_createtable(L, 0, setter_count); } }
public Delegate CreateDelegateBridge(RealStatePtr L, Type delegateType, int idx) { LuaAPI.lua_pushvalue(L, idx); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); if (!LuaAPI.lua_isnil(L, -1)) { int referenced = LuaAPI.xlua_tointeger(L, -1); LuaAPI.lua_pop(L, 1); if (delegate_bridges[referenced].IsAlive) { DelegateBridgeBase exist_bridge = delegate_bridges[referenced].Target as DelegateBridgeBase; Delegate exist_delegate; if (exist_bridge.TryGetDelegate(delegateType, out exist_delegate)) { return(exist_delegate); } else { exist_delegate = exist_bridge.GetDelegateByType(delegateType); exist_bridge.AddDelegate(delegateType, exist_delegate); return(exist_delegate); } } } else { LuaAPI.lua_pop(L, 1); } LuaAPI.lua_pushvalue(L, idx); int reference = LuaAPI.luaL_ref(L); LuaAPI.lua_pushvalue(L, idx); LuaAPI.lua_pushnumber(L, reference); LuaAPI.lua_rawset(L, LuaIndexes.LUA_REGISTRYINDEX); DelegateBridgeBase bridge; try { #if UNITY_EDITOR if (!DelegateBridge.Gen_Flag) { bridge = Activator.CreateInstance(delegate_birdge_type, new object[] { reference, luaEnv }) as DelegateBridgeBase; } else #endif { bridge = new DelegateBridge(reference, luaEnv); } } catch (Exception e) { LuaAPI.lua_pushvalue(L, idx); LuaAPI.lua_pushnil(L); LuaAPI.lua_rawset(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.lua_pushnil(L); LuaAPI.xlua_rawseti(L, LuaIndexes.LUA_REGISTRYINDEX, reference); throw e; } try { var ret = bridge.GetDelegateByType(delegateType); bridge.AddDelegate(delegateType, ret); delegate_bridges[reference] = new WeakReference(bridge); return(ret); } catch (Exception e) { bridge.Dispose(); throw e; } }
public static void ReflectionWrap(RealStatePtr L, Type type) { int top_enter = LuaAPI.lua_gettop(L); ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); //create obj meta table LuaAPI.luaL_getmetatable(L, type.FullName); if (LuaAPI.lua_isnil(L, -1)) { LuaAPI.lua_pop(L, 1); LuaAPI.luaL_newmetatable(L, type.FullName); } LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag()); LuaAPI.lua_pushnumber(L, 1); LuaAPI.lua_rawset(L, -3); int obj_meta = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_meta = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int obj_field = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int obj_getter = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int obj_setter = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_field = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_getter = LuaAPI.lua_gettop(L); LuaAPI.lua_newtable(L); int cls_setter = LuaAPI.lua_gettop(L); BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; FieldInfo[] fields = type.GetFields(flag); for (int i = 0; i < fields.Length; ++i) { FieldInfo field = fields[i]; if (field.IsStatic && (field.IsInitOnly || field.IsLiteral)) { LuaAPI.xlua_pushasciistring(L, field.Name); translator.PushAny(L, field.GetValue(null)); LuaAPI.lua_rawset(L, cls_field); } else { LuaAPI.xlua_pushasciistring(L, field.Name); translator.PushFixCSFunction(L, genFieldGetter(type, field)); LuaAPI.lua_rawset(L, field.IsStatic ? cls_getter : obj_getter); LuaAPI.xlua_pushasciistring(L, field.Name); translator.PushFixCSFunction(L, genFieldSetter(type, field)); LuaAPI.lua_rawset(L, field.IsStatic ? cls_setter : obj_setter); } } EventInfo[] events = type.GetEvents(flag); for (int i = 0; i < events.Length; ++i) { EventInfo eventInfo = events[i]; LuaAPI.xlua_pushasciistring(L, eventInfo.Name); translator.PushFixCSFunction(L, translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name)); bool is_static = (eventInfo.GetAddMethod() != null) ? eventInfo.GetAddMethod().IsStatic : eventInfo.GetRemoveMethod().IsStatic; LuaAPI.lua_rawset(L, is_static ? cls_field : obj_field); } Dictionary <string, PropertyInfo> prop_map = new Dictionary <string, PropertyInfo>(); List <PropertyInfo> items = new List <PropertyInfo>(); PropertyInfo[] props = type.GetProperties(flag); for (int i = 0; i < props.Length; ++i) { PropertyInfo prop = props[i]; if (prop.Name == "Item") { items.Add(prop); } else { prop_map.Add(prop.Name, prop); } } var item_array = items.ToArray(); LuaCSFunction item_getter = item_array.Length > 0 ? genItemGetter(type, item_array) : null; LuaCSFunction item_setter = item_array.Length > 0 ? genItemSetter(type, item_array) : null;; MethodInfo[] methods = type.GetMethods(flag); Dictionary <MethodKey, List <MemberInfo> > pending_methods = new Dictionary <MethodKey, List <MemberInfo> >(); for (int i = 0; i < methods.Length; ++i) { MethodInfo method = methods[i]; string method_name = method.Name; MethodKey method_key = new MethodKey { Name = method_name, IsStatic = method.IsStatic }; List <MemberInfo> overloads; if (pending_methods.TryGetValue(method_key, out overloads)) { overloads.Add(method); continue; } PropertyInfo prop = null; if (method_name.StartsWith("add_") || method_name.StartsWith("remove_") || method_name == "get_Item" || method_name == "set_Item") { continue; } if (method_name.StartsWith("op_")) // 操作符 { if (support_op.ContainsKey(method_name)) { if (overloads == null) { overloads = new List <MemberInfo>(); pending_methods.Add(method_key, overloads); } overloads.Add(method); } continue; } else if (method_name.StartsWith("get_") && prop_map.TryGetValue(method.Name.Substring(4), out prop)) // getter of property { LuaAPI.xlua_pushasciistring(L, prop.Name); translator.PushFixCSFunction(L, genPropGetter(type, prop, method.IsStatic)); LuaAPI.lua_rawset(L, method.IsStatic ? cls_getter : obj_getter); } else if (method_name.StartsWith("set_") && prop_map.TryGetValue(method.Name.Substring(4), out prop)) // setter of property { LuaAPI.xlua_pushasciistring(L, prop.Name); translator.PushFixCSFunction(L, genPropSetter(type, prop, method.IsStatic)); LuaAPI.lua_rawset(L, method.IsStatic ? cls_setter : obj_setter); } else if (method_name == ".ctor" && method.IsConstructor) { continue; } else { if (overloads == null) { overloads = new List <MemberInfo>(); pending_methods.Add(method_key, overloads); } overloads.Add(method); } } foreach (var kv in pending_methods) { if (kv.Key.Name.StartsWith("op_")) // 操作符 { LuaAPI.xlua_pushasciistring(L, support_op[kv.Key.Name]); translator.PushFixCSFunction(L, new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call)); LuaAPI.lua_rawset(L, obj_meta); } else { LuaAPI.xlua_pushasciistring(L, kv.Key.Name); translator.PushFixCSFunction(L, new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call)); LuaAPI.lua_rawset(L, kv.Key.IsStatic ? cls_field : obj_field); } } IEnumerable <MethodInfo> extend_methods = GetExtensionMethodsOf(type); if (extend_methods != null) { foreach (var kv in (from extend_method in extend_methods select(MemberInfo) extend_method into member group member by member.Name)) { LuaAPI.xlua_pushasciistring(L, kv.Key); translator.PushFixCSFunction(L, new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key, kv).Call)); LuaAPI.lua_rawset(L, obj_field); } } // init obj metatable LuaAPI.xlua_pushasciistring(L, "__gc"); LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta); LuaAPI.lua_rawset(L, obj_meta); LuaAPI.xlua_pushasciistring(L, "__tostring"); LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta); LuaAPI.lua_rawset(L, obj_meta); LuaAPI.xlua_pushasciistring(L, "__index"); LuaAPI.lua_pushvalue(L, obj_field); LuaAPI.lua_pushvalue(L, obj_getter); translator.PushFixCSFunction(L, item_getter); translator.PushAny(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.lua_pushnil(L); LuaAPI.gen_obj_indexer(L); //store in lua indexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, obj_meta); // set __index LuaAPI.xlua_pushasciistring(L, "__newindex"); LuaAPI.lua_pushvalue(L, obj_setter); translator.PushFixCSFunction(L, item_setter); translator.Push(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.lua_pushnil(L); LuaAPI.gen_obj_newindexer(L); //store in lua newindexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, obj_meta); // set __newindex //finish init obj metatable LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType"); translator.PushAny(L, type); LuaAPI.lua_rawset(L, cls_field); if (type != null && type.IsEnum) { LuaAPI.xlua_pushasciistring(L, "__CastFrom"); translator.PushFixCSFunction(L, genEnumCastFrom(type)); LuaAPI.lua_rawset(L, cls_field); } //set cls_field to namespace SetCSTable(L, type, cls_field); //finish set cls_field to namespace //init class meta LuaAPI.xlua_pushasciistring(L, "__index"); LuaAPI.lua_pushvalue(L, cls_getter); LuaAPI.lua_pushvalue(L, cls_field); translator.Push(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.gen_cls_indexer(L); //store in lua indexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaClassIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, cls_meta); // set __index LuaAPI.xlua_pushasciistring(L, "__newindex"); LuaAPI.lua_pushvalue(L, cls_setter); translator.Push(L, type.BaseType); LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); LuaAPI.gen_cls_newindexer(L); //store in lua newindexs function tables LuaAPI.xlua_pushasciistring(L, Utils.LuaClassNewIndexsFieldName); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX); translator.Push(L, type); LuaAPI.lua_pushvalue(L, -3); LuaAPI.lua_rawset(L, -3); LuaAPI.lua_pop(L, 1); LuaAPI.lua_rawset(L, cls_meta); // set __newindex LuaCSFunction constructor = translator.methodWrapsCache.GetConstructorWrap(type); if (constructor == null) { constructor = (RealStatePtr LL) => { return(LuaAPI.luaL_error(LL, "No constructor for " + type)); }; } LuaAPI.xlua_pushasciistring(L, "__call"); translator.PushFixCSFunction(L, constructor); LuaAPI.lua_rawset(L, cls_meta); LuaAPI.lua_pushvalue(L, cls_meta); LuaAPI.lua_setmetatable(L, cls_field); LuaAPI.lua_pop(L, 8); System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L)); }