// 针对普通类和单例类有不同的注册过程,通过LuaxState的两个工厂方法Register_实现 // 注册工厂,分为注册interface table和class table,以type name为键设置在名称空间上。在注册阶段不会设置元表,等到New方法调用的时候才会。 template void LuaxState::RegisterFactory() { lua_State* L = mState; int top = lua_gettop(L); // namespace table const char* type = T::GetLuaxFactoryName(); // interface table. lua_newtable(L); int idx = AbsIndex(-1); LuaxClass::RegisterLuaxInterface(*this); T::RegisterLuaxInterface(*this); // 检测T里面是否没有注册必须的方法 #define assertMethods(I, NAME)\ GetField(I, NAME);\ assert(IsType(-1, LUA_TFUNCTION));\ Pop(); assertMethods(idx, "New"); #undef assertMethods lua_settop(L, top); // class table. lua_newtable(L); assert(lua_istable(L, -1)); lua_pushvalue(L, -1); LuaxClass::RegisterLuaxClass(*this); LuaxClass::RegisterLuaxFactoryClass(*this); T::RegisterLuaxClass(*this); SetField(top, type); // reset top lua_settop(L, top); } // 注册单例 template void LuaxState::RegisterSingleton() { lua_State* L = mState; int top = lua_gettop(L); // namespace table const char* type = T::GetLuaxSingletonName(); // class table. lua_newtable(L); assert(lua_istable(L, -1)); lua_pushvalue(L, -1); LuaxClass::RegisterLuaxClass(*this); LuaxClass::RegisterLuaxFactoryClass(*this); T::RegisterLuaxClass(*this); SetField(top, type); // reset top lua_settop(L, top); } template void LuaxState::SetField(int idx, cc8* key, T value) { if (IsTableOrUserdata(idx)) { idx = AbsIndex(idx); this->Push(value); lua_setfield(mState, idx, key); } } template T LuaxState::GetField(int idx, cc8* key, T value) { GetField(idx, key); T result = GetValue < T >(-1, value); this->Pop(); return result; } template T LuaxState::GetField(int idx, int key, T value) { GetField(idx, key); T result = GetValue < T >(-1, value); Pop(); return result; }