quick cocos2dx c-lua(3)

LUA_REGISTRYINDEX伪索引处也存放着一个table,它就是Lua注册表(registry)。这个注册表可以用来保存任何C代码想保存 的Lua值。
加入到注册表里的数据相当于全局变量,不过只有C代码可以存取而Lua代码不能。因此用它来存储函数库(在下一节介绍)中的一些公共变量再好不过了。


/* Map module

    * It creates a new module
*/
#if 1
TOLUA_API void
tolua_module (lua_State* L, const char* name, int hasvar)
{
    if (name)
    {
        /* tolua module */
        lua_pushstring(L,name);
        lua_rawget(L,-2);
 // t[name]入栈
        if (!lua_istable(L,-1))  /* check if module already exists */  
        {//不存在
            lua_pop(L,1);//出栈
            lua_newtable(L);
            lua_pushstring(L,name);
            lua_pushvalue(L,-2);
            lua_rawset(L,-4);       /* assing module into module */  t[name] = {}
        }
    }
    else
    {
        /* global table */
        lua_pushvalue(L,LUA_GLOBALSINDEX);
    }
    if (hasvar)
    {
        if (!tolua_ismodulemetatable(L))  /* check if it already has a module metatable */
        {
            /* create metatable to get/set C/C++ variable */
            lua_newtable(L);
            tolua_moduleevents(L);
            if (lua_getmetatable(L,-2))
                lua_setmetatable(L,-2);  /* set old metatable as metatable of metatable */
            lua_setmetatable(L,-2);
        }
    }
    lua_pop(L,1);               /* pop module */
}


/* Begin module
    * It pushes the module (or class) table on the stack
*/
TOLUA_API void tolua_beginmodule (lua_State* L, const char* name)
{
    if (name) { // ... module
//---- now module[name] is a table, get it's metatable to store keys
        // get module[name]
        lua_pushstring(L,name); // ... module name
        lua_rawget(L,-2);       // ... module module[name]   入栈

        // Is module[name] a class table?
        lua_pushliteral(L, ".isclass");
        lua_rawget(L, -2);                  // stack: ... module module[name] class_flag     module[name].isclass 入栈
        if (lua_isnil(L, -1)) {
            lua_pop(L, 1);                  // stack: ... module module[name]     不是class时  栈顶module[name]直接返回
            return;                         // not a class table, use origin table
        }
        lua_pop(L, 1);                      // stack: ... module class_table
        // get metatable
        if (lua_getmetatable(L, -1)) {  // ... module class_table mt   如果module[name]有元表  元表入栈 否则返回0
            lua_remove(L, -2);          // ... module mt   移除module[name]   栈顶为元表
        }
//---- by SunLightJuly, 2014.6.5
    } else {
        lua_pushvalue(L,LUA_GLOBALSINDEX);
    }
}


/* Create metatable
    * Create and register new metatable
*/
static int tolua_newmetatable (lua_State* L, const char* name)
{
    int r = luaL_newmetatable(L,name);  

#ifdef LUA_VERSION_NUM /* only lua 5.1 */
    if (r) {
        lua_pushvalue(L, -1);
        lua_pushstring(L, name);
        lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */
    };
#endif


    if (r)
        tolua_classevents(L); /* set meta events */  //给元表添加方法 metamethod
    lua_pop(L,1); // 出栈
    return r;
}


LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
  lua_getfield(L, LUA_REGISTRYINDEX, tname);  /* get registry.name */
  if (!lua_isnil(L, -1))  /* name already in use? */
    return 0;  /* leave previous value on top, but return 0 */
  lua_pop(L, 1);
  lua_newtable(L);  /* create metatable */  入栈
  lua_pushvalue(L, -1);  入栈
  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */void lua_setfield (lua_State *L, int index, const char *k);做一个等价于 t[k] = v 的操作,这里 t 是给出的有效索引 index 处的值,而 v 是栈顶的那个值。这个函数将把这个值弹出堆栈。

  return 1;
}


/* Register class events
    * It expects the metatable on the top of the stack
*/
TOLUA_API void tolua_classevents (lua_State* L)
{
    lua_pushstring(L,"__index");
    lua_pushcfunction(L,class_index_event);
    lua_rawset(L,-3);
    lua_pushstring(L,"__newindex");
    lua_pushcfunction(L,class_newindex_event);
    lua_rawset(L,-3);


    lua_pushstring(L,"__add");
    lua_pushcfunction(L,class_add_event);
    lua_rawset(L,-3);
    lua_pushstring(L,"__sub");
    lua_pushcfunction(L,class_sub_event);
    lua_rawset(L,-3);
    lua_pushstring(L,"__mul");
    lua_pushcfunction(L,class_mul_event);
    lua_rawset(L,-3);
    lua_pushstring(L,"__div");
    lua_pushcfunction(L,class_div_event);
    lua_rawset(L,-3);


    lua_pushstring(L,"__lt");
    lua_pushcfunction(L,class_lt_event);
    lua_rawset(L,-3);
    lua_pushstring(L,"__le");
    lua_pushcfunction(L,class_le_event);
    lua_rawset(L,-3);
    lua_pushstring(L,"__eq");
    lua_pushcfunction(L,class_eq_event);
    lua_rawset(L,-3);


    lua_pushstring(L,"__call");
    lua_pushcfunction(L,class_call_event);
    lua_rawset(L,-3);


    lua_pushstring(L,"__gc");
    lua_pushstring(L, "tolua_gc_event");
    lua_rawget(L, LUA_REGISTRYINDEX);
    /*lua_pushcfunction(L,class_gc_event);*/
    lua_rawset(L,-3);
}

TOLUA_API void tolua_function (lua_State* L, const char* name, lua_CFunction func)
{
    lua_pushstring(L,name);
    lua_pushcfunction(L,func);
    lua_rawset(L,-3);
}


// from 2dx
static unsigned int _Hash(const char *key)
{
    unsigned int len = strlen(key);
    const char *end=key+len;
    unsigned int hash;
    
    for (hash = 0; key < end; key++)
    {
        hash *= 16777619;
        hash ^= (unsigned int) (unsigned char) toupper(*key);
//按位异或
    }
    return (hash);
}


unsigned int class_hash_code(const std::type_info& info)
{
    // hash name() to size_t value by pseudorandomizing transform
    return _Hash(info.name());
}


TOLUA_API void tolua_constant (lua_State* L, const char* name, lua_Number value)
{
    lua_pushstring(L,name);
    tolua_pushnumber(L,value);

    lua_rawset(L,-3);

}


/* Map variable
    * It assigns a variable into the current module (or class)
*/
TOLUA_API void tolua_variable (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set)
{
    /* get func */
    lua_pushstring(L,".get");
    lua_rawget(L,-2);
    if (!lua_istable(L,-1))
    {
        /* create .get table, leaving it at the top */
        lua_pop(L,1);
        lua_newtable(L);
        lua_pushstring(L,".get");
        lua_pushvalue(L,-2);
        lua_rawset(L,-4);
    }
    lua_pushstring(L,name);
    lua_pushcfunction(L,get);
    lua_rawset(L,-3);                  /* store variable */
    lua_pop(L,1);                      /* pop .get table */


    /* set func */
    if (set)
    {
        lua_pushstring(L,".set");
        lua_rawget(L,-2);
        if (!lua_istable(L,-1))
        {
            /* create .set table, leaving it at the top */
            lua_pop(L,1);
            lua_newtable(L);
            lua_pushstring(L,".set");
            lua_pushvalue(L,-2);
            lua_rawset(L,-4);
        }
        lua_pushstring(L,name);
        lua_pushcfunction(L,set);
        lua_rawset(L,-3);                  /* store variable */
        lua_pop(L,1);                      /* pop .set table */
    }
}


/* Open function */

TOLUA_API int tolua_Cocos2d_open (lua_State* tolua_S)
{

 tolua_open(tolua_S); // cocos2dx之tolua++全面分析(二):类注册

/* static int class_gc_event (lua_State* L);  */ GC有多层含义,一是计算机术语,指Garbage Collection; 三是网络域中的GC,就是“全局目录”Global Catalog;

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); //(t[LUA_REGISTRYINDEX] )["tolua_opened"] =1
        
        // create value root table
        lua_pushstring(L, TOLUA_VALUE_ROOT);
        lua_newtable(L);
        lua_rawset(L, LUA_REGISTRYINDEX); //(t[LUA_REGISTRYINDEX] )[TOLUA_VALUE_ROOT] ={}


#ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */
        /* create peer object table */
        lua_pushstring(L, "tolua_peers");
        lua_newtable(L);
        /* make weak key metatable for peers indexed by userdata object */
        lua_newtable(L);
        lua_pushliteral(L, "__mode");
        lua_pushliteral(L, "k");
        lua_rawset(L, -3);                /* stack: string peers mt */
        lua_setmetatable(L, -2);   /* stack: string peers */
        lua_rawset(L,LUA_REGISTRYINDEX);
#endif


        /* create object ptr -> udata mapping table */
        lua_pushstring(L,"tolua_ubox");
        lua_newtable(L); //t1
        /* make weak value metatable for ubox table to allow userdata to be
           garbage-collected */
        lua_newtable(L);
        lua_pushliteral(L, "__mode");  //同lua_pushstring
        lua_pushliteral(L, "v");
        lua_rawset(L, -3); //t["__mode"]   =v   
     /*stack: string ubox mt */
        lua_setmetatable(L, -2);  /* stack: string ubox */
 
        lua_rawset(L,LUA_REGISTRYINDEX); //(t[LUA_REGISTRYINDEX] )["tolua_ubox"] =t1
        
//        /* create object ptr -> class type mapping table */
//        lua_pushstring(L, "tolua_ptr2type");
//        lua_newtable(L);
//        lua_rawset(L, LUA_REGISTRYINDEX);


        lua_pushstring(L,"tolua_super");
        lua_newtable(L);
        lua_rawset(L,LUA_REGISTRYINDEX);//(t[LUA_REGISTRYINDEX] )["tolua_super"] ={}
        lua_pushstring(L,"tolua_gc");
        lua_newtable(L);
        lua_rawset(L,LUA_REGISTRYINDEX);//(t[LUA_REGISTRYINDEX] )["tolua_gc"] ={}


        /* create gc_event closure */
        lua_pushstring(L, "tolua_gc_event");
        lua_pushstring(L, "tolua_gc");
        lua_rawget(L, LUA_REGISTRYINDEX); //(t[LUA_REGISTRYINDEX] )["tolua_gc"]入栈
        lua_pushstring(L, "tolua_super");
        lua_rawget(L, LUA_REGISTRYINDEX); //(t[LUA_REGISTRYINDEX] )["tolua_super"]入栈
        lua_pushcclosure(L, class_gc_event, 2);  //class_gc_event + (t[LUA_REGISTRYINDEX] )["tolua_super"] +//(t[LUA_REGISTRYINDEX] )["tolua_gc"]

        lua_rawset(L, LUA_REGISTRYINDEX); //(t[LUA_REGISTRYINDEX] )["tolua_gc_event"] =class_gc_event


        tolua_newmetatable(L,"tolua_commonclass"); //(t[LUA_REGISTRYINDEX] )["tolua_commonclass"] =添加了一些metamethod的元表



        tolua_module(L,NULL,0);  //好像什么都没做、、?????????
        tolua_beginmodule(L,NULL); //lua_pushvalue(L,LUA_GLOBALSINDEX); 入栈
        tolua_module(L,"tolua",0);  //  t[LUA_REGISTRYINDEX["tolua"] = {}
        tolua_beginmodule(L,"tolua"); //t[L UA_REGISTRYINDEX [ "tolua" ] 入栈
        tolua_function(L,"type",tolua_bnd_type); t[L UA_REGISTRYINDEX [ "tolua" ]["type"]=tolua_bnd_type
        tolua_function(L,"takeownership",tolua_bnd_takeownership); t[L UA_REGISTRYINDEX [ "tolua" ]["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_endmodule(L);// t[L UA_REGISTRYINDEX [ "tolua" ] 出栈     lua_pushvalue(L,LUA_GLOBALSINDEX); 出栈
        tolua_endmodule(L);
    }
    lua_settop(L,top);

}

 tolua_reg_types(tolua_S);  ///* function to register type */

/* function to register type */
static void tolua_reg_types (lua_State* tolua_S)
{
 
tolua_usertype(tolua_S,"CCTransitionProgressOutIn");  //通过userdata+元表 注册c函数到lua  Lua中的userdata

/* Register a usertype
    * It creates the correspoding(一致的) metatable in the registry, for both 'type' and 'const type'.
    * It maps(映射) 'const type' as(also 同样) being also a 'type'
*/
TOLUA_API void tolua_usertype (lua_State* L, const char* type)
{
    char ctype[128] = "const ";
    strncat(ctype,type,120);
    /* create both metatables */
    if (tolua_newmetatable(L,ctype) && tolua_newmetatable(L,type))
        mapsuper(L,type,ctype);             /* 'type' is also a 'const type' */
}

 toluafix_add_type_mapping(CLASS_HASH_CODE(typeid(CCTransitionProgressOutIn)), "CCTransitionProgressOutIn"); 
 //ccluastack中(处理栈操作的cpp)  把CCTransitionProgressOutIn 注册到类型全局表中   通过把ccoco的类(副本) 入栈供lua使用 
 /*
 static map<unsigned int, char*> hash_type_mapping;


TOLUA_API void
toluafix_add_type_mapping(unsigned int type, const char *clsName)
{
    if (hash_type_mapping.find(type) == hash_type_mapping.end())
    {
        hash_type_mapping[type] = strdup(clsName);
    }
}
*/

...........

..........
}

 tolua_module(tolua_S,NULL,0); 
 tolua_beginmodule(tolua_S,NULL);
  tolua_constant(tolua_S,"GL_ZERO",GL_ZERO);
  tolua_constant(tolua_S,"GL_ONE",GL_ONE);
  tolua_constant(tolua_S,"GL_SRC_COLOR",GL_SRC_COLOR);
  tolua_constant(tolua_S,"GL_ONE_MINUS_SRC_COLOR",GL_ONE_MINUS_SRC_COLOR);
  tolua_constant(tolua_S,"GL_SRC_ALPHA",GL_SRC_ALPHA);
  tolua_constant(tolua_S,"GL_ONE_MINUS_SRC_ALPHA",GL_ONE_MINUS_SRC_ALPHA);
  tolua_constant(tolua_S,"GL_DST_ALPHA",GL_DST_ALPHA);
  tolua_constant(tolua_S,"GL_ONE_MINUS_DST_ALPHA",GL_ONE_MINUS_DST_ALPHA);
  tolua_constant(tolua_S,"GL_DST_COLOR",GL_DST_COLOR);
  tolua_constant(tolua_S,"GL_ONE_MINUS_DST_COLOR",GL_ONE_MINUS_DST_COLOR);
  #ifdef __cplusplus
  tolua_cclass(tolua_S,"ccColor3B","ccColor3B","",tolua_collect_ccColor3B);//内部元表实现
  #else
  tolua_cclass(tolua_S,"ccColor3B","ccColor3B","",NULL);
  #endif
  tolua_beginmodule(tolua_S,"ccColor3B");
   tolua_function(tolua_S,"new",tolua_Cocos2d_ccColor3B_new00);
   tolua_function(tolua_S,"new_local",tolua_Cocos2d_ccColor3B_new00_local);
   tolua_function(tolua_S,".call",tolua_Cocos2d_ccColor3B_new00_local);
   tolua_function(tolua_S,"delete",tolua_Cocos2d_ccColor3B_delete00);
   tolua_variable(tolua_S,"r",tolua_get_ccColor3B_unsigned_r,tolua_set_ccColor3B_unsigned_r);
   tolua_variable(tolua_S,"g",tolua_get_ccColor3B_unsigned_g,tolua_set_ccColor3B_unsigned_g);
   tolua_variable(tolua_S,"b",tolua_get_ccColor3B_unsigned_b,tolua_set_ccColor3B_unsigned_b);


 tolua_module(tolua_S,NULL,0); 

 tolua_beginmodule(tolua_S,NULL);
  tolua_constant(tolua_S,"GL_ZERO",GL_ZERO);
  tolua_constant(tolua_S,"GL_ONE",GL_ONE);
  tolua_constant(tolua_S,"GL_SRC_COLOR",GL_SRC_COLOR);
  tolua_constant(tolua_S,"GL_ONE_MINUS_SRC_COLOR",GL_ONE_MINUS_SRC_COLOR);
  tolua_constant(tolua_S,"GL_SRC_ALPHA",GL_SRC_ALPHA);
  tolua_constant(tolua_S,"GL_ONE_MINUS_SRC_ALPHA",GL_ONE_MINUS_SRC_ALPHA);
  tolua_constant(tolua_S,"GL_DST_ALPHA",GL_DST_ALPHA);
  tolua_constant(tolua_S,"GL_ONE_MINUS_DST_ALPHA",GL_ONE_MINUS_DST_ALPHA);
  tolua_constant(tolua_S,"GL_DST_COLOR",GL_DST_COLOR);
  tolua_constant(tolua_S,"GL_ONE_MINUS_DST_COLOR",GL_ONE_MINUS_DST_COLOR);
  #ifdef __cplusplus
  tolua_cclass(tolua_S,"ccColor3B","ccColor3B","",tolua_collect_ccColor3B);//内部元表实现
  #else
  tolua_cclass(tolua_S,"ccColor3B","ccColor3B","",NULL);
  #endif
  tolua_beginmodule(tolua_S,"ccColor3B");
   tolua_function(tolua_S,"new",tolua_Cocos2d_ccColor3B_new00);
   tolua_function(tolua_S,"new_local",tolua_Cocos2d_ccColor3B_new00_local);
   tolua_function(tolua_S,".call",tolua_Cocos2d_ccColor3B_new00_local);
   tolua_function(tolua_S,"delete",tolua_Cocos2d_ccColor3B_delete00);
   tolua_variable(tolua_S,"r",tolua_get_ccColor3B_unsigned_r,tolua_set_ccColor3B_unsigned_r);
   tolua_variable(tolua_S,"g",tolua_get_ccColor3B_unsigned_g,tolua_set_ccColor3B_unsigned_g);
   tolua_variable(tolua_S,"b",tolua_get_ccColor3B_unsigned_b,tolua_set_ccColor3B_unsigned_b);

  tolua_endmodule(tolua_S);

..............

..............

  { /* begin embedded lua code */    // 好像是给lua解读器加密????????
   int top = lua_gettop(tolua_S);
   static const unsigned char B[] = {
    10,102,117,110, 99,116,105,111,110, 32,116,111,108,117, 97,
     46,114,101,115,101,116, 99,102,117,110, 99,116,105,111,110,
     40, 99,108,115, 44, 32,109,101,116,104,111,100,110, 97,109,
    101, 41, 10,108,111, 99, 97,108, 32, 99,102,117,110, 99,116,
    105,111,110, 32, 61, 32,116,111,108,117, 97, 46,103,101,116,
     99,102,117,110, 99,116,105,111,110, 40, 99,108,115, 44, 32,
    109,101,116,104,111,100,110, 97,109,101, 41, 10,105,102, 32,
     99,102,117,110, 99,116,105,111,110, 32,116,104,101,110, 10,
     99,108,115, 91,109,101,116,104,111,100,110, 97,109,101, 93,
     32, 61, 32, 99,102,117,110, 99,116,105,111,110, 10,101,110,
    100, 10,101,110,100, 45, 45, 45, 45, 45,32
   };
   tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code 1");
   lua_settop(tolua_S, top);
  } /* end of embedded lua code */


 tolua_endmodule(tolua_S);
 return 1;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值