tolua++分析

来源:互联网 发布:淘宝店铺dsr 编辑:程序博客网 时间:2024/05/22 15:59

_R 代表LUA_REGISTRYINDEX

在C++中输出一个模块的步骤,如cc.Node
向_R中加入函数

举例:cc.Layer派生与cc.Node,cc.Node派生与cc.Ref


上面的代码主要做下列操作:

cc.Layer的元表被设置成cc.Node

cc.Node的元表被设置成cc.Ref

cc.Ref的元表被设置成tolua_commonclass

如果你调用cc.Layer函数,例如对象layer:abc()(layer是一个cc.Layer对象)。layer的元表被成cc.Layer

lua先在cc.Layer中查找abc函数,然后是cc.Node,最后是cc.Ref。

tolua++的继承关系和上面的代码一样。


最终tolua++要解决下列问题:

1.已知元表mt取的元表名称_R[mt]

2.已知名称取的原表luaL_getmetatable(L,name)

3.已知元表取继承关系

_R["tolua_super"][mt] = { 

super1 = true,

super2 = true,

...,

}

4.已知一个lua对象,取C++对象.

如果该lua对象是一个userdata,返回userdata,如果是一个表返回表的c_instance

可以使用tolua_isusertype来检查对象是不是给定的类型,例如tolua_isusertype(tolua_S,1,"cc.Ref",0,&tolua_err)检查堆栈1,是不是一个cc.Ref对象.

而cobj = (cocos2d::Ref*)tolua_tousertype(tolua_S,1,0);将取出该对象。

5.tolua.getpeer(target) 取的target的环境.如果等于_R,就返回nil

tolua.setpeer(target,t)设置target的环境,target必须是一个userdata

 例如:

function HomeWork.extend(target)
    local t = tolua.getpeer(target)
    if not t then
        t = {}
        tolua.setpeer(target, t)
    end
    setmetatable(t, HomeWork)
    return target
end

local layer = HomeWork.extend(cc.Layer:create())

对于一个函数的调用顺序是这样的,先t表(layer的环境表)中的,然后到t的元表HomeWork中,其实才是cc.Layer

6.lua对象的绑定

例如:绑定一个场景对象为一个lua对象

 object_to_luaval<cocos2d::Scene>(tolua_S, "cc.Scene",(cocos2d::Scene*)scene);


7.对象的释放

对象都从Ref派生,都使用引用计数管理。

~Ref的实现如下:

最后调用toluafix_remove_ccobject_by_refid(_state, pObj->_luaID);和void ScriptHandlerMgr::removeObjectAllHandlers(void* object)


8.tolua_ubox

9.对象创建


用法:创建类元表

_R[mt] = class_name

int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err)

int lua_isusertype (lua_State* L, int lo, const char* type)

lo必须是一个userdata或者table.(mt是lo的原表),并且lo必须有元表

如果_R[mt] == type ,表示他是一个type 类型数据.

或者_R["tolua_super"][mt]是一个表ST,并且ST[type]如果不为nil或者false,表示lo是type的子类的实例.


static  int lua_isusertable (lua_State* L, int lo, const char* type)

如果_R[lo]==type,返回true


int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index)


void tolua_pushusertype_internal (lua_State* L, void* value, const char* type, int addToRoot)

如果存在名称为type的原表mt.

C = mt["tolua_ubox"] or _R["tolua_ubox"]

C[value]

0 0