LuaRef registerClass(lua_State* state)const { util::ScopedSavedStack save(state); if (class_userdata::newmetatable<class_type>(state)) { LuaTable metatable(state, StackTop()); metatable.push(); registerMember(state); if (!traits::is_same<base_class_type, void>::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod { for (PropMapType::const_iterator it = property_map_.begin(); it != property_map_.end(); ++it) { int count = lua_type_traits<FunctorType>::push(state, it->second); if (count > 1) { lua_pop(state, count - 1); count = 1; } if (count == 1) { lua_setfield(state, -2, ("_prop_" + it->first).c_str()); } } LuaFunction indexfun = kaguya::LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];" "return function(table, index)" // " if type(table) == 'userdata' then " " local propfun = metatable['_prop_'..index];" " if propfun then return propfun(table) end " // " end " " return metatable[index]" " end")(metatable); metatable.setField("__index", indexfun); LuaFunction newindexfn = LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];" " return function(table, index, value) " " if type(table) == 'userdata' then " " local propfun = metatable['_prop_'..index];" " if propfun then return propfun(table,value) end " " end " " rawset(table,index,value) " " end")(metatable); metatable.setField("__newindex", newindexfn); } else { metatable.setField("__index", metatable); } set_base_metatable(state, metatable, types::typetag<base_class_type>()); return metatable; } else { except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered")); } return LuaRef(state); }
LuaTable createMatatable(lua_State* state)const { util::ScopedSavedStack save(state); if (!class_userdata::newmetatable<class_type>(state)) { except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered")); return LuaTable(); } int metatable_index = lua_gettop(state); Metatable::setMembers(state, metatable_index,member_map_,property_map_); if (!traits::is_same<base_class_type, void>::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod { if (member_map_.count("__index") == 0) { Metatable::setPropertyIndexMetamethod(state, metatable_index); } if (member_map_.count("__newindex") == 0) { Metatable::setPropertyNewIndexMetamethod(state, metatable_index); } } else { if (member_map_.count("__index") == 0) { lua_pushstring(state, "__index"); lua_pushvalue(state, metatable_index); lua_rawset(state, metatable_index); } } set_base_metatable(state, metatable_index, types::typetag<base_class_type>()); if (lua_getmetatable(state, metatable_index))//get base_metatable { lua_pushstring(state, "__call"); lua_pushcfunction(state, &Metatable::call_constructor_function); lua_rawset(state,-3);//base_metatable["__call"] = Metatable::call_constructor_function } else { Metatable::get_call_constructor_metatable(state); lua_setmetatable(state, metatable_index); } return LuaStackRef(state, metatable_index); }
LuaTable createMatatable(lua_State* state)const { util::ScopedSavedStack save(state); if (class_userdata::newmetatable<class_type>(state)) { LuaStackRef metatable(state, -1); registerMember(state); if (!traits::is_same<base_class_type, void>::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod { LuaFunction indexfun = kaguya::LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];" "return function(table, index)" // " if type(table) == 'userdata' then " " local propfun = metatable['_prop_'..index];" " if propfun then return propfun(table) end " // " end " " return metatable[index]" " end")(metatable); metatable.setField("__index", indexfun); LuaFunction newindexfn = LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];" " return function(table, index, value) " " if type(table) == 'userdata' then " " local propfun = metatable['_prop_'..index];" " if propfun then return propfun(table,value) end " " end " " rawset(table,index,value) " " end")(metatable); metatable.setField("__newindex", newindexfn); } else { metatable.setField("__index", metatable); } set_base_metatable(state, metatable, types::typetag<base_class_type>()); return metatable; } else { except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered")); } return LuaTable(); }