xlua原理解析

版本记录

日期版本说明作者
2018-7-25 1.0 xlua实现提纲 李俊
2018-7-27 2.0 xlua实现 李俊
2018-7-30 3.0 xlua实现 李俊

lua53 对象类型


luaC
int64 lua_Integer
double lua_Number
boolean int
string TString
function Closure
table Table
userdata Udata
typedef union Value {
  GCObject *gc;    /* collectable objects */
  void *p;         /* light userdata */
  int b;           /* booleans */
  lua_CFunction f; /* light C functions */
  lua_Integer i;   /* integer numbers */
  lua_Number n;    /* float numbers */
} Value;
typedef struct lua_TValue {
  TValuefields;
} TValue;

c#与lua交互


一切交互都可以简化成相互函数调用

image

交互函数

操作函数
lua_push* lua_pushnil
lua_pushnumber
lua_pushinteger
lua_pushcclosure
lua_pushboolean
lua_to* lua_tonil
lua_tonumber
lua_tointeger
lua_toclosure
lua_toboolean
lua_totable
lua_new* lua_newuserdata
lua_newtable
lua_pop lua_pop
lua_call lua_call
lua_pcall

注册函数

table.binfind

static int table_clear(lua_State* L)
{
     Table* tab = lua_totable(L, 1);
      ...
     return 0;
}
lua_getglobal(L, "table")
lua_pushstring(L, "clear")
lua_pushfunction(L, table_clear)
lua_settable(L, -3)
lua_pop(L,1)

class实例

  1. Push(RealStatePtr L, object o)

o.GetTypeObjectTransltor.GetTypeIdObjectTransltor.TryDelayWrapLoader*Wrap.__RegisterObjectTranslator.addObjectxlua_pushcsobjgraph TB A[o.GetType] B[ObjectTransltor.GetTypeId] C[ObjectTransltor.TryDelayWrapLoader] D[*Wrap.__Register] E[ObjectTranslator.addObject] F[xlua_pushcsobj] A-->B B-->C C-->D D-->E E-->F

Utils.BeginObjectRegister(type, L, translator, 0, 4, 1, 1);
			
Utils.RegisterFunc(L, Utils.METHOD_IDX, "Init", _m_Init);
Utils.RegisterFunc(L, Utils.METHOD_IDX, "ChangeGameState", _m_ChangeGameState);
Utils.RegisterFunc(L, Utils.METHOD_IDX, "DeActive", _m_DeActive);
Utils.RegisterFunc(L, Utils.METHOD_IDX, "IsActive", _m_IsActive);
			
			
Utils.RegisterFunc(L, Utils.GETTER_IDX, "CurGameSate", _g_get_CurGameSate);
            
Utils.RegisterFunc(L, Utils.SETTER_IDX, "CurGameSate", _s_set_CurGameSate);
            
			
Utils.EndObjectRegister(type, L, translator, null, null,null, null, null);
{
//upvalue --- [1]:getters, [2]:feilds, [3]:base, [4]:indexfuncs, [5]:baseindex
//param   --- [1]: obj, [2]: key
   __index = cls_indexer,
//upvalue --- [1]:setters, [2]:base, [3]:indexfuncs, [4]:baseindex
//param   --- [1]: obj, [2]: key, [3]: value
   __newindex = cls_newindexer,
}
LUA_API void xlua_pushcsobj(lua_State *L, int key, int meta_ref, int need_cache, int cache_ref) {
	int* pointer = (int*)lua_newuserdata(L, sizeof(int));
	*pointer = key;
	
	if (need_cache) cacheud(L, key, cache_ref);

    lua_rawgeti(L, LUA_REGISTRYINDEX, meta_ref);

	lua_setmetatable(L, -2);
}
  1. GetObject(RealStatePtr L, int index, Type type)

xlua实现


  1. lua调用c#

触发metatable.__newindexImage.sprite=SpriteUnityEngineUIImageWrap._s_set_spriteObjectTranslator.FastGetCSObjLuaAPI.xlua_tocsobj_fastObjectTranslator.getCsObjgraph TB A[Image.sprite=Sprite] B[UnityEngineUIImageWrap._s_set_sprite] C[ObjectTranslator.FastGetCSObj] D[LuaAPI.xlua_tocsobj_fast] E[ObjectTranslator.getCsObj] A--触发metatable.__newindex-->B B-->C C-->D D-->E

  1. c#调用lua

EventTriggerListener.AddEventOnPressEventTriggerListenerWrap._m_AddEventOnPressObjectTraslator.GetDelegate&lt;EventTriggerListener.BoolDelegate&gt;ObjectTraslator.CreateDelegateBridgenew DelegateBridgeDelegate.CreateDelegategraph TB A[EventTriggerListener.AddEventOnPress] B[EventTriggerListenerWrap._m_AddEventOnPress] C[ObjectTraslator.GetDelegate<EventTriggerListener.BoolDelegate>] D[ObjectTraslator.CreateDelegateBridge] E[new DelegateBridge] F[Delegate.CreateDelegate] A-->B B-->C C-->D D-->E E-->F

问题


回调泄漏

local btn = GameObject.Find( "/XXXXX" ):GetComponent( "Button" )
btn.OnClick.AddListener( funciton()
btn.disabled = true
end)
btn = nil

垃圾回收等待

meditor释放

function DeleteObjectListItem:releas()
    log("释放".. self.uiName.."index:".. self.index)
    local tb ={}
    setmetatable(tb,{__mode ="k"})
    local mediator = UIManager:GetUI(self.uiName).mediator
    tb[mediator] =1
    UIManager:removeTargetUI( self.uiName)
    mediator=nil
    collectgarbage"collect"
    LuaHelper.CsSharpGc()
    collectgarbage"collect"
    if not next(tb)  then
        self.state =5
        self.text_state.text="状态:内存已被回收"
        self.text_state.color =UIUtil.CodeToColor(ColorCodeType.AssetEnough_Green)
        self.bt.gameObject:SetActiveVirtual(false)
        self:setState()
    else
        self.state =4
        self.text_state.color =UIUtil.CodeToColor(ColorCodeType.AssetNotEnough)
        self.bt_text.text="查看引用"
        self:setState()
    end
end
    1. lua强制回收
      meditor还有引用,引用在注册到c#的回调呢

    2. c#强制回收
      meditor没有引用了,等待垃圾回收

    3. lua第二次强制回收
      meditor回收成功

posted on 2020-01-07 14:48  marcher  阅读(622)  评论(0编辑  收藏  举报

导航