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); }
void Entity::Enable() { assert(this->_self.IsTable()); this->_self.Set("id", this->_id); Luasel::Ref metatable(this->_engine.GetInterpreter().MakeTable()); this->_self.SetMetaTable(metatable); this->_self.Set("prototype", this->_type.GetPrototype()); metatable.Set("__index", this->_type.GetPrototype()); this->_engine.GetEntityManager().GetWeakEntityRefManager().GetResource(this->_weakReferenceId).disabled = false; }
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(); }