入手cocos2dx3.9笔记 3 tolua++解析

入手cocos2dx3.9笔记 3 tolua++解析,第1张

概述因为需求,最近又重新回忆了下tolua++的相关流程, 以 3.9的 lua stack 的初始化相关代码开始解析: _state = lua_open(); luaL_openlibs(_state); toluafix_open(_state); // Register our version of the global "print" function

因为需求,最近又重新回忆了下tolua++的相关流程, 以 3.9的 lua stack 的初始化相关代码开始解析:

    _state = lua_open();    luaL_openlibs(_state);    toluafix_open(_state);    // Register our version of the global "print" function    const luaL_reg global_functions [] = {        {"print",lua_print},{"release_print",lua_release_print},{nullptr,nullptr}    };    luaL_register(_state,"_G",global_functions);    g_luaType.clear();    register_all_cocos2dx(_state);

register_all_cocos2dx 如下:

<pre name="code" >TolUA_API int register_all_cocos2dx(lua_State* tolua_S){	tolua_open(tolua_S);		tolua_module(tolua_S,"cc",0);	tolua_beginmodule(tolua_S,"cc");	lua_register_cocos2dx_Ref(tolua_S);
<span >	</span>...
<span >	</span>	tolua_endmodule(tolua_S);
<span >	return 1;</span>
}
 
TolUA_API voID tolua_open (lua_State* L){    int top = lua_gettop(L);    lua_pushstring(L,"tolua_opened");    lua_rawget(L,LUA_REGISTRYINDEX);    if (!lua_isboolean(L,-1))    {        lua_pushstring(L,"tolua_opened");        lua_pushboolean(L,1);        lua_rawset(L,LUA_REGISTRYINDEX);                // create value root table        lua_pushstring(L,TolUA_VALUE_ROOT);        lua_newtable(L);        lua_rawset(L,LUA_REGISTRYINDEX);        /* create object ptr -> udata mapPing table */        lua_pushstring(L,"tolua_uBox");        lua_newtable(L);        /* make weak value Metatable for uBox table to allow userdata to be           garbage-collected */        lua_newtable(L);        lua_pushliteral(L,"__mode");        lua_pushliteral(L,"v");        lua_rawset(L,-3);               /* stack: string uBox mt */        lua_setMetatable(L,-2);  /* stack: string uBox */        lua_rawset(L,LUA_REGISTRYINDEX);                lua_pushstring(L,"tolua_super");        lua_newtable(L);        lua_rawset(L,LUA_REGISTRYINDEX);        lua_pushstring(L,"tolua_gc");        lua_newtable(L);        lua_rawset(L,LUA_REGISTRYINDEX);        /* create gc_event closure */        lua_pushstring(L,"tolua_gc_event");        lua_pushstring(L,"tolua_gc");        lua_rawget(L,"tolua_super");        lua_rawget(L,LUA_REGISTRYINDEX);        lua_pushcclosure(L,class_gc_event,2);        lua_rawset(L,LUA_REGISTRYINDEX);        tolua_newMetatable(L,"tolua_commonclass");        tolua_module(L,NulL,0);        tolua_beginmodule(L,NulL);        tolua_module(L,"tolua","tolua");        tolua_function(L,"type",tolua_bnd_type);        tolua_function(L,"takeownership",tolua_bnd_takeownership);        tolua_function(L,"releaSEOwnership",tolua_bnd_releaSEOwnership);        tolua_function(L,"cast",tolua_bnd_cast);        tolua_function(L,"isnull",tolua_bnd_isnulluserdata);        tolua_function(L,"inherit",tolua_bnd_inherit);#ifdef LUA_VERSION_NUM /* lua 5.1 */        tolua_function(L,"setpeer",tolua_bnd_setpeer);        tolua_function(L,"getpeer",tolua_bnd_getpeer);#endif        tolua_function(L,"getcfunction",tolua_bnd_getcfunction);        tolua_function(L,"iskindof",tolua_bnd_iskindof);        tolua_endmodule(L);        tolua_endmodule(L);    }    lua_settop(L,top);}


对 tolua_open 解析如下:

tolua_open:	LUA_REGISTRYINDEX["tolua_opened"] = true	LUA_REGISTRYINDEX[TolUA_VALUE_ROOT] = {}	LUA_REGISTRYINDEX["tolua_uBox"] = setMetatable({},{__mode = v})	LUA_REGISTRYINDEX["tolua_super"] = {}	LUA_REGISTRYINDEX["tolua_gc"] = {}	LUA_REGISTRYINDEX["tolua_gc_event"] = class_gc_event [closure: LUA_REGISTRYINDEX["tolua_gc"] LUA_REGISTRYINDEX["tolua_super"]]	tolua_newMetatable(L,"tolua_commonclass")		mt = {}		LUA_REGISTRYINDEX["tolua_commonclass"] = mt		LUA_REGISTRYINDEX[mt] = "tolua_commonclass"		tolua_classevents(mt)			tolua_module(L,0);						确保拥有该模块, 该木块没有 moduleevent __index,__newindex	tolua_beginmodule(L,NulL); 					push _G (not .isclass,a normal table not mt) 	tolua_module(L,0); 					_G["tolua"] = {}	tolua_beginmodule(L,"tolua");				push _G["tolua"]	tolua_function(L,tolua_bnd_type); 	_G["tolua"]["type"] = tolua_bnd_type	...	tolua_endmodule(L); 						pop	tolua_endmodule(L); 						pop			restore stack
需要留意的:
1.其中TolUA_VALUE_ROOT 用于额外存放push到lua中的userdata 如果push的时候放入了这个table中,那么析构的时候需要从中移除

2.当push的 userdata 类的 mt 中没有 tolua_uBox 则这个userdata 会放入到这个 全局 tolua_uBox 中

3.tolua_super 存储注册到lua中类的继承关系,例如 c_derived 继承 c_base 那么 tolua_super[mt_c_derived] = {cbasename = true},cbasename为c_base 在注册表的 class name

4.注册的lua类的基类都会索引 tolua_commonclass,他的 __index,__newindex,__gc 值得注意下,


其他流程用伪代码解析如下:

主流程调用:register_all_cocos2dx: 						//栈顶已经有一个 _G 了	tolua_open(tolua_S); 					//见核心一	tolua_module(tolua_S,0); 			//确保拥有 _G["cc"]	tolua_beginmodule(tolua_S,"cc"); 		//push _G["cc"]		lua_register_cocos2dx_Ref(tolua_S);	...	tolua_endmodule(tolua_S); 				//pop	注册详细信息:int lua_register_cocos2dx_Ref(lua_State* tolua_S){    tolua_usertype(tolua_S,"cc.Ref");:		tolua_newMetatable("cc.Ref")		tolua_newMetatable("const cc.Ref")		mapsuper(L,type,ctype);:			mapsuper (lua_State* L,const char* name,const char* base)				mt = LUA_REGISTRYINDEX[name]				LUA_REGISTRYINDEX["tolua_super"][mt] = {$base = true}				mtbase = LUA_REGISTRYINDEX[base]				merge(LUA_REGISTRYINDEX["tolua_super"][mt],LUA_REGISTRYINDEX["tolua_super"][mtbase]) 右侧内容 merge 到左侧								    tolua_cclass(tolua_S,"Ref","cc.Ref","",nullptr);:		tolua_cclass (lua_State* L,const char* lname,const char* base,lua_CFunction col):			mapinheritance(L,name,base);			mapinheritance(L,cname,name);				mapinheritance (lua_State* L,const char* base)					push mt_name 											as mt					push mt_base or LUA_REGISTRYINDEX["tolua_commonclass"] 	as base_mt					set_uBox(L);:						mt["tolua_uBox"] = base_mt["tolua_uBox"] or setMetatable({},{__mode = v})					setMetatable(mt,base_mt)								mapsuper(L,cbase);			mapsuper(L,base);			LUA_REGISTRYINDEX[name][".collector"] = col			LUA_REGISTRYINDEX[cname][".collector"] = col			module[lname] = setMetatable({[".isclass"] = true},mt_name)			// stack: module			    tolua_beginmodule(tolua_S,"Ref");        tolua_function(tolua_S,"release",lua_cocos2dx_Ref_release);		...    tolua_endmodule(tolua_S);    std::string typename = typeID(cocos2d::Ref).name();    g_luaType[typename] = "cc.Ref";    g_typeCast["Ref"] = "cc.Ref";    return 1;}

至于 cocos2dx 新增的 tolua_fix代码就不做笔记了,大概就是额外记录了下push 进lua的userdata,以及 function 相关的事情, 确保当析构的时候 userdata 置 nil, 让注册表functions 与对应索引ID之类的事情。


OK,完毕, 知道了这些, 在 lua中 扩充、派生 那些注册进lua中的类就已经不是问题了。


干吧爹~,争取这几周内把框架搭建出来。

总结

以上是内存溢出为你收集整理的入手cocos2dx3.9笔记 3 tolua++解析全部内容,希望文章能够帮你解决入手cocos2dx3.9笔记 3 tolua++解析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1075381.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存