/* Map inheritance * It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name' */ static void mapinheritance (lua_State* L, const char* name, const char* base) { /* set metatable inheritance */ tolua_getmetatable(L,name); if (base && *base) tolua_getmetatable(L,base); else tolua_getmetatable(L,"tolua_commonclass"); lua_setmetatable(L,-2); lua_pop(L,1); }
/***************************************************************************** Mark any, if exported, full userdata representing 'object' in the current script state as 'Nonexistent'. This changes the type of the lua variable. *****************************************************************************/ void luascript_remove_exported_object(struct fc_lua *fcl, void *object) { if (fcl && fcl->state) { fc_assert_ret(object != NULL); /* The following is similar to tolua_release(..) in src/lib/tolua_map.c */ /* Find the userdata representing 'object' */ lua_pushstring(fcl->state,"tolua_ubox"); /* stack: ubox */ lua_rawget(fcl->state, LUA_REGISTRYINDEX); /* stack: ubox u */ lua_pushlightuserdata(fcl->state, object); /* stack: ubox ubox[u] */ lua_rawget(fcl->state, -2); if (!lua_isnil(fcl->state, -1)) { fc_assert(object == tolua_tousertype(fcl->state, -1, NULL)); /* Change API type to 'Nonexistent' */ /* stack: ubox ubox[u] mt */ tolua_getmetatable(fcl->state, "Nonexistent"); lua_setmetatable(fcl->state, -2); /* Set the userdata payload to NULL */ *((void **)lua_touserdata(fcl->state, -1)) = NULL; /* Remove from ubox */ /* stack: ubox ubox[u] u */ lua_pushlightuserdata(fcl->state, object); /* stack: ubox ubox[u] u nil */ lua_pushnil(fcl->state); lua_rawset(fcl->state, -4); } lua_pop(fcl->state, 2); } }
/* Map super classes * It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name' */ static void mapsuper (lua_State* L, const char* name, const char* base) { /* push registry.super */ lua_pushstring(L,"tolua_super"); lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super */ tolua_getmetatable(L,name); /* stack: super mt */ lua_rawget(L,-2); /* stack: super table */ if (lua_isnil(L,-1)) { /* create table */ lua_pop(L,1); lua_newtable(L); /* stack: super table */ tolua_getmetatable(L,name); /* stack: super table mt */ lua_pushvalue(L,-2); /* stack: super table mt table */ lua_rawset(L,-4); /* stack: super table */ } /* set base as super class */ lua_pushstring(L,base); lua_pushboolean(L,1); lua_rawset(L,-3); /* stack: super table */ /* set all super class of base as super class of name */ tolua_getmetatable(L,base); /* stack: super table base_mt */ lua_rawget(L,-3); /* stack: super table base_table */ if (lua_istable(L,-1)) { /* traverse base table */ lua_pushnil(L); /* first key */ while (lua_next(L,-2) != 0) { /* stack: ... base_table key value */ lua_pushvalue(L,-2); /* stack: ... base_table key value key */ lua_insert(L,-2); /* stack: ... base_table key key value */ lua_rawset(L,-5); /* stack: ... base_table key */ } } lua_pop(L,3); /* stack: <empty> */ }
/* Type casting */ static int tolua_bnd_cast (lua_State* L) { void* v = tolua_tousertype(L,1,NULL); const char* s = tolua_tostring(L,2,NULL); if (!v) lua_pushnil(L); else if (v && s) { tolua_getmetatable(L,s); /* stack: ubox[u] super super[mt] flag mt */ if (lua_isnil(L,-1)) { tolua_error(L,"Unknown 'type' for 'tolua.cast' function",NULL); } tolua_pushusertype(L,v,s); } else { tolua_error(L,"Invalid arguments for 'tolua.cast' function",NULL); } return 1; }
/* Map C class * It maps a C class, setting the appropriate inheritance and super classes. */ TOLUA_API void tolua_cclass (lua_State* L, const char* lname, const char* name, const char* base, lua_CFunction col) { char cname[128] = "const "; char cbase[128] = "const "; strncat(cname,name,120); strncat(cbase,base,120); mapinheritance(L,name,base); mapinheritance(L,cname,name); mapsuper(L,cname,cbase); mapsuper(L,name,base); lua_pushstring(L,lname); tolua_getmetatable(L,name); lua_pushstring(L,".collector"); lua_pushcfunction(L,col); lua_rawset(L,-3); /* store collector function into metatable */ lua_rawset(L,-3); /* assign class metatable to module */ }