Code
37template<class Derived, class InstanceType>38void CvLuaScopedInstance<Derived, InstanceType>::Push(lua_State* L, InstanceType* pkType)39{40 //Pushing an instance involves more than just actually pushing a pointer into the41 //Lua stack. There are some caching optimizations that are done as well as some42 //checks.43 //The first step is to load or create a global table <Typename> to store all member44 //methods and all pushed instances. This conserves memory and offers faster pushing45 //speed.46 //If <Typename>.__instances[pkType] is not nil, return that value.47 //otherwise push a new instance and assign it to __instances.4849 //NOTE: Raw gets and sets are used as an optimization over using lua_[get,set]field50 if(pkType)51 {52 //const int t = lua_gettop(L);5354 lua_getglobal(L, Derived::GetTypeName());55 if(lua_isnil(L, -1))56 {57 //Typename wasn't found, time to build it.58 lua_pop(L, 1);59 lua_newtable(L);6061 //Create weak __instances table.62 lua_pushstring(L, "__instances");63 lua_newtable(L);6465 //Create __instances.mt66 lua_newtable(L);67 lua_pushstring(L, "__mode");68 lua_pushstring(L, "v");69 lua_rawset(L, -3); // mt.__mode = "v";70 lua_setmetatable(L, -2);7172 lua_rawset(L, -3); //type.__instances = t;737475 lua_pushvalue(L, -1);76 lua_setglobal(L, Derived::GetTypeName());7778 Derived::PushMethods(L, lua_gettop(L));79 }80 const int type_index = lua_gettop(L);8182 lua_pushstring(L, "__instances");83 lua_rawget(L, -2);8485 const int instances_index = lua_gettop(L);8687 lua_pushlightuserdata(L, pkType);8889 lua_rawget(L, -2); //retrieve type.__instances[pkType]9091 if(lua_isnil(L, -1))92 {93 lua_pop(L, 1);9495 //Push new instance96 lua_createtable(L, 0, 1);97 lua_pushlightuserdata(L, pkType);98 lua_setfield(L, -2, "__instance");99100 lua_createtable(L, 0, 1); // create mt101 lua_pushstring(L, "__index");102 lua_pushvalue(L, type_index);103 lua_rawset(L, -3); // mt.__index = Type104 lua_setmetatable(L, -2);105106 //Assign it in instances107 lua_pushlightuserdata(L, pkType);108 lua_pushvalue(L, -2);109 lua_rawset(L, instances_index); //__instances[pkType] = t;110 }111112 //VERIFY(instances_index > type_index);113 lua_remove(L, instances_index);114 lua_remove(L, type_index);115116 //const int dt = lua_gettop(L);117 //VERIFY(dt == t + 1)118 }119 else120 {121 lua_pushnil(L);122 }123}