2013-10-05 23 views
1

我用lualite包住下面的對象在LUA:的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 

我甚至試過一些these表打印機,但沒有運氣。

+0

你能說明你是如何試圖建立你所指的列表嗎? –

+0

我嘗試基於[this](http://stackoverflow.com/questions/2620377/lua-reflection-get-list-of-functions-fields-on-an-object)的問題。我在帖子中增加了更多細節。 –

+0

你的意思是說,在那個循環中,你只有'key'兩個值:'name'和'__instance'?更具體地說,在你的Lua循環中只放入'print(key,「 - >」value)'併發布結果。 –

回答

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"); 

這指向默認的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存根,該存根將處理參數和返回值。

+0

嗨,非常感謝你回答和寫這麼好的圖書館:)我實際上在這期間發現了這些。我還發現了一個錯誤(有點),我可以在哪裏提交? –

+0

@fish這裏http://code.google.com/p/lualite/issues/list,歡迎所有的錯誤 – user1095108

+0

謝謝,我現在覺得啞巴:)提交。 –

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 
+0

是的,這個想法是使用我提供給lualite的信息作爲原始反射形式 - 所以我不想重複屬性名稱,不幸的是。我將嘗試調整lualite以在綁定時構建信息。 –

+0

@fish是的,但我也爲你公開了一些成員,所以你可以從'C++'端獲得屬性。 – user1095108