Самоанализ объекта Lua

я использовал 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

Я даже попробовал некоторые из эти настольные принтеры, но не повезло.

1

Решение

Я автор 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 Заглушка сделана для функции-члена, которая затем обрабатывает аргументы и возвращаемые значения.

1

Другие решения

Если бы вы могли допустить необходимость перечисления имен свойств в вашем коде 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
0

По вопросам рекламы [email protected]