xluaExample(二) luaEnv.NewTable()

※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)这是一个委托,代表一个方法

※加粗的代表类,紫色代表方法,红色为方法的代码,//开头为注释。第一次分享,有错误还望大家指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值