※LuaEnv
NewTable() 返回一个LuaTable
①
var _L = L;
int oldTop = LuaAPI.lua_gettop(_L);
//得到虚拟栈中的栈顶索引,也即栈中元素的个数
②
lua_newtable
//原型: void lua_newtable (lua_State *L);
//描述: 创建一个新的table并将之放在栈顶. 等同于lua_createtable(L, 0, 0).
③
LuaTable returnVal = (LuaTable)translator.GetObject(_L, -1, typeof(LuaTable));
//调用translator中的GetObject()方法返回一个object并将其转为LuaTable
④
//该函数用于指定栈的高度,栈只能从栈顶压栈,不能从栈底添加数据。所以栈底的数据会保持不变。
//当新的高度大于原来的高度时,会从栈顶压入数据,压入的数据不可用(因为是随机的)。
//当新的高度小于原来的高度时,会从栈顶移除多余的元素。
//当输入参数为负数时,表示从栈顶开始的索引(最栈顶元素为-1)。该函数会移除栈顶到该元素
//之间的所以元素。-1则无,-2 则移除-1 。-3则移除-1,-2。以此类推。
//但是负数编号不能超出栈底的负数索引,超出会抛出异常。lua_pop函数及是使用了该特性。
LuaAPI.lua_settop(_L, oldTop);
return returnVal;
※Translator
GetObject(_L, -1, typeof(LuaTable)) 返回一个object
①
int udata = LuaAPI.xlua_tocsobj_safe(L, index);
//这里index = -1,即从上往下索引一个,也即刚刚在栈顶创建的table
//这个方法将table转换为了一个索引,取出的是代理对象在 C# 侧的 ObjectPool 实例对象数组索引
②
//这里如果udata不等于-1则证明ObjectPool中存的有对应的table了,直接取出就行了
if (udata != -1)
{
object obj = objects.Get(udata);
RawObject rawObject = obj as RawObject;
return rawObject == null ? obj : rawObject.Target;
}
③
//等于-1则证明还没有存对应的table
else
{
④
//这里判断table的类型,这里应该是LUA_TTABLE类型,类似还有LUA_TNUMBER,LUA_TBOOLEAN
//,LUA_TSTRING,LUA_TTABLE,LUA_TFUNCTION,LUA_TTHREAD,LUA_TUERDATA,LUA_TLIGHTUSERDATA等枚举值
if (LuaAPI.lua_type(L, index) == LuaTypes.LUA_TUSERDATA)
{
GetCSObject get;
int type_id = LuaAPI.xlua_gettypeid(L, index);
if (type_id != -1 && type_id == decimal_type_id)
{
decimal d;
Get(L, index, out d);
return d;
}
Type type_of_struct;
if (type_id != -1 && typeMap.TryGetValue(type_id, out type_of_struct) && type.IsAssignableFrom(type_of_struct) && custom_get_funcs.TryGetValue(type, out get))
{
return get(L, index);
}
}
⑤
//直接返回一个转换函数,并直接调用转换委托对type进行转换,这里转换成了table,调用了getLuaTable()
return (objectCasters.GetCaster(type)(L, index, null));
}
※ObjectCasters
getLuaTable(RealStatePtr L, int idx, object target) 返回一个object
①
//判断是不是userdata 这里不是,是table
if (LuaAPI.lua_type(L, idx) == LuaTypes.LUA_TUSERDATA)
{
object obj = translator.SafeGetCSObj(L, idx);
return (obj != null && obj is LuaTable) ? obj : null;
}
②
//这里是table,所以不会返回
if (!LuaAPI.lua_istable(L, idx))
{
return null;
}
③
//向lua栈中push一个原栈中索引为idx的元素的copy,这里idx = -1应该是copy的栈顶的
LuaAPI.lua_pushvalue(L, idx);
//返回一个新的LuaTable 其中LuaAPI.luaL_ref(L)会调用luaL_ref(L,LuaIndexes.LUA_REGISTRYINDEX)并返回一个int
//其作用是
//在当前栈索引t处的元素是一个table, 在该table中创建一个对象, 对象是当前栈顶的元素, 并返回创建对象在表中的索引值, 之后会pop栈顶的对象; (即将栈顶元素放到t对应的table中)
return new LuaTable(LuaAPI.luaL_ref(L), translator.luaEnv);
GetCaster(Type LuaTable) 返回一个ObjectCast
①
if (type.IsByRef) type = type.GetElementType();
//看type是否由引用传递,是的话为true,不是的话为false
②
Type underlyingType = Nullable.GetUnderlyingType(type);
//GetUnderlyingType()返回一个可空类型下面的具体类型
if (underlyingType != null)
{
return genNullableCaster(GetCaster(underlyingType));
}
③
ObjectCast oc;
//castersMap是一个<Type,ObjectCast>的字典,在ObjectCasters初始化时候为其添加内容
//里边的委托分别类似为类型的转换,比如(char)LuaAPI.xlua_tointeger(),LuaAPI.lua_toint64()类似的转换
if (!castersMap.TryGetValue(type, out oc))
{
oc = genCaster(type);
//genCaster()会生成一个ObjectCaster并将这个type和委托添加到字典中
castersMap.Add(type, oc);
}
//这里找到了LuaTable
//返回这个转换函数
return oc;
genCaster(Type) 返回一个ObjectCast即对应的转换的委托
①
//定义了一个转换委托,并为其进行了赋值
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;
};
②
//一系列的判断Type能不能作为某些类型的变量接收
if (typeof(Delegate).IsAssignableFrom(type))
else if (typeof(DelegateBridgeBase).IsAssignableFrom(type))
else if (type.IsInterface())
else if (type.IsEnum())
else if (type.IsArray)
else if (typeof(IList).IsAssignableFrom(type) && type.IsGenericType())
else if (typeof(IDictionary).IsAssignableFrom(type) && type.IsGenericType())
else if ((type.IsClass() && type.GetConstructor(System.Type.EmptyTypes) != null) || (type.IsValueType() && !type.IsEnum()))
else return fixTypeGetter;
※ObjectCast public delegate object ObjectCast(RealStatePtr L, int idx, object target)这是一个委托,代表一个方法
※加粗的代表类,紫色代表方法,红色为方法的代码,//开头为注释。第一次分享,有错误还望大家指出。