xlua原理解析
版本记录
日期 | 版本 | 说明 | 作者 |
---|---|---|---|
2018-7-25 | 1.0 | xlua实现提纲 | 李俊 |
2018-7-27 | 2.0 | xlua实现 | 李俊 |
2018-7-30 | 3.0 | xlua实现 | 李俊 |
lua53 对象类型
lua | C |
---|---|
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交互
一切交互都可以简化成相互函数调用
栈
交互函数
操作 | 函数 |
---|---|
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实例
- 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);
}
- GetObject(RealStatePtr L, int index, Type type)
xlua实现
- 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
- c#调用lua
EventTriggerListener.AddEventOnPressEventTriggerListenerWrap._m_AddEventOnPressObjectTraslator.GetDelegate<EventTriggerListener.BoolDelegate>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
-
lua强制回收
meditor还有引用,引用在注册到c#的回调呢 -
c#强制回收
meditor没有引用了,等待垃圾回收 -
lua第二次强制回收
meditor回收成功