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;
}

1332

被折叠的 条评论
为什么被折叠?



