1

我使用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

我什至尝试了其中一些台式打印机,但没有运气。

4

2 回答 2

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_;

thechar const*是属性的名称,值为 a map_member_info_type,它们本质上是两个指针,一个指向lualite存根,另一个指向C++成员函数。

struct map_member_info_type
{
  lua_CFunction callback;

  member_func_type func;
};

如果你愿意,我可以将两个成员都公开。属性的工作方式如下:

默认 getter(通常)设置在包装类的实例表中:

lua_pushcclosure(L, default_getter<C>, 2);

rawsetfield(L, -2, "__index");

这指向默认的 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));
}

它查找属性的名称(在堆栈上)。这实际上可以是任何东西,如果它没有找到名称,则返回 0,否则,它将调用转发给lualite为成员函数所做的存根,然后由它处理参数和返回值。

于 2013-11-04T08:17:17.163 回答
0

如果您可以容忍必须在 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  -- do


for k, v in pairs( GetPropertyList(o) ) do
    print( k, v )
end
于 2013-10-06T12:21:22.790 回答