я использовал lualite обернуть следующий объект в lua:
class SpriteComponent : public Component
{
public:
SpriteComponent();
std::string name() const;
std::string textureId() const;
void setTextureId(const std::string& id);
int spriteCoordX() const;
void setSpriteCoordX(int value);
int spriteCoordY() const;
void setSpriteCoordY(int value);
};
Обязательный код:
module(L,
class_<SpriteComponent>("SpriteComponent")
.constructor("new")
.def("name", &SpriteComponent::name)
.property("textureId",
&SpriteComponent::textureId, &SpriteComponent::setTextureId)
.property("spriteCoordX",
&SpriteComponent::spriteCoordX, &SpriteComponent::setSpriteCoordX)
.property("spriteCoordY",
&SpriteComponent::spriteCoordY, &SpriteComponent::setSpriteCoordY)
);
Есть ли способ (либо на стороне lua, либо на стороне C ++) получить список свойств? Если я перечислю пары в итоговой таблице, я получу только name
а также __instance
,
local o = SpriteComponent.new()
for key,value in pairs(o) do
print("found member " .. key);
end
Я даже попробовал некоторые из эти настольные принтеры, но не повезло.
Я автор lualite
, Я написал библиотеку, чтобы она была минималистичной и быстрой и не предусматривала необходимость размышлений 🙂 В любом случае, то, что вы ищете, может быть найдено как 2 статических члена:
static ::std::unordered_map<char const*, detail::map_member_info_type,
detail::unordered_hash, detail::unordered_eq> getters_;
static ::std::unordered_map<char const*, detail::map_member_info_type,
detail::unordered_hash, detail::unordered_eq> setters_;
char const*
это имя свойства, значение которого является map_member_info_type
по сути два указателя, один на lualite
заглушка, другой к C++
функция-член.
struct map_member_info_type
{
lua_CFunction callback;
member_func_type func;
};
Если хотите, я могу сделать обоих участников публичными. Способ работы свойств заключается в следующем:
Получатель по умолчанию (обычно) устанавливается в таблице экземпляров упакованного класса:
lua_pushcclosure(L, default_getter<C>, 2);
rawsetfield(L, -2, "__index");
Это указывает на получатель по умолчанию:
template <class C>
int default_getter(lua_State* const L)
{
assert(2 == lua_gettop(L));
auto const i(lualite::class_<C>::getters_.find(lua_tostring(L, 2)));
return lualite::class_<C>::getters_.end() == i
? 0
: (lua_pushlightuserdata(L, &i->second.func),
lua_replace(L, lua_upvalueindex(2)),
(i->second.callback)(L));
}
который ищет имя свойства (которое находится в стеке). На самом деле это может быть что угодно, и если он не находит имя, он возвращает 0, в противном случае он пересылает вызов lualite
Заглушка сделана для функции-члена, которая затем обрабатывает аргументы и возвращаемые значения.
Если бы вы могли допустить необходимость перечисления имен свойств в вашем коде Lua, это может быть решением:
local GetPropertyList
do -- to make `property_names` "private" to GetPropertyList
property_names = {
["SpriteComponent"] = { "textureId", "spriteCoordX", "spriteCoordY" },
-- property names for other components, e.g.
["AnotherComponentName"] = { "propName1", "propName2" },
}
function GetPropertyList( object ) --[[local]]
local component_name = object:name()
local prop_names = property_names[component_name]
if not prop_names then
error( "unsupported component" )
end
local res = {}
for _, p_name in ipairs( prop_names ) do
local p_val = object[p_name]
res[ #res + 1 ] = p_val
-- or use this if you want a key-value map:
-- res[p_name] = p_val
end
return res
end -- function
end -- dofor k, v in pairs( GetPropertyList(o) ) do
print( k, v )
end