I used lualite to wrap the following object in 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);
};
The binding code:
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)
);
Is there a way (either on the lua side or the C++ side) to get a list of properties? If I list the pairs in the resulting table, I only get name
and __instance
.
local o = SpriteComponent.new()
for key,value in pairs(o) do
print("found member " .. key);
end
I even tried some of these table printers, but no luck.
I'm the author of lualite
. I wrote the library to be minimalist and fast and did not foresee the need for reflection :) Anyway, what you are looking for can be found as 2 static members:
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_;
the char const*
is the name of the property, the value being a map_member_info_type
, which are essentially two pointers, one to a lualite
stub, the other to the C++
member function.
struct map_member_info_type
{
lua_CFunction callback;
member_func_type func;
};
If you like, I can make both members public. The way properties work is as follows:
A default getter is (usually) set in the wrapped class's instance table:
lua_pushcclosure(L, default_getter<C>, 2);
rawsetfield(L, -2, "__index");
This points to the default getter:
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));
}
which looks for the name of the property (which is on the stack). That could be anything really and if it does not find the name, it returns 0, otherwise, it forwards the call to the lualite
stub made for the member function, which then handles the arguments and the return value(s).