2015-02-09 29 views
4

我正在爲2D遊戲引擎編寫一個實體組件系統,該引擎使用可變參數模板來構造遊戲對象。這是對象類,它只是所有組件的容器。我刪除了不相關的東西。動態檢查使用可變繼承的類的類型的最佳方法是什麼?

template<class ... Components> 
class Object : public Components...{ 
public: 
    Object(Game* game) : Components(game)...{ 

    } 
}; 

的部件是由對象繼承,但我試圖找到檢查這些部件的類型,使他們能夠正確地相互溝通的最佳方式。例如,Physics組件將包含對象的更新位置。 Drawable組件需要獲取該位置,以便它可以在世界上的正確位置上繪製。我想向Object添加一個更新函數,它可以更新每個組件並傳輸任何可以/需要在當前組件之間傳輸的信息。

+0

你能有更多的代碼說明你的要求,比如?我可能失去了一些東西,因爲如果你只需要簡單的繪製對象組件使用從物理學的協調,只是喜歡寫東西'無效對象::更新(){這個 - >畫(*此);}',假設你有' void Drawable :: draw(const Physics&)'。只要右邊的'Drawable'和'Physics'處於可變元件'Components ...'中,就會工作 – 2015-03-23 20:51:10

回答

0

多態性是你想要的。 簡單地使所有組件這樣的:

public Object 
{ 
enum TYPE{ 
COMPONENT,, 
GAMEOBJECT, 
ETC,,, 
}; 
Object(TYPE id){m_id = id;} 
protected: 
    TYPE m_id; 
    virtual void Update(void) = 0; 

    virtual void Render(void) = 0; 

public: 
    void GetTypeOf(void)const{return m_id;} 
}; 

class Component : Object 
{ 
    enum COMPONENT_TYPE 
{ 
    COLLIDER, 
    RENDERER, 
    ETC,,,, 
}; 
    Component() : Object (COMPONENT){/**/} 
    virtual void Update(void){return;} 
    virtual void Render(void){return;} 
    }; 

    class BoxCollider : Component 
    { 
     BoxCollider(void) : Component(BOXCOLLIDER){/**/} 
     void Update(void) 
     { 
     //to do 
     } 
     void Render(void) 
     { 
      //to do 
     } 
    }; 

,那麼你可以簡單地擁有對象*或組件* 的數據結構,你可以通過這種方式遍歷:

std::vector<Component*>::iterator components = ComponentVector.begin(); 
    for(;components != ComponentVector.end() ; ++components) 
    { 
     *(component)->Update(); 
     *(component)->Render(); 
     std::cout << "id" << *component->getTypeOf() << std::endl; 
    } 
0

Object類繼承自它的所有Components,這意味着它實際上它的所有組件。
您可以使用此信息來設計你的update方法。
作爲一個例子:

#include <cassert> 

struct Game { }; 

struct Physics { 
    int position{0}; 

    Physics(Game *) { } 
    void update(void *) { } 
}; 

struct Drawable { 
    Drawable(Game *) { } 

    void update(Physics *physics) { 
     physics->position = 42; 
    } 
}; 

template<class ... Components> 
class Object: public Components... { 
public: 
    Object(Game* game) : Components(game)... { } 

    void update() { 
     int a[] = { (Components::update(this), 0)... }; 
    } 
}; 

int main() { 
    Game game; 
    Object<Physics, Drawable> object{&game}; 
    assert(object.position == 0); 
    object.update(); 
    assert(object.position == 42); 
} 

在這裏你可以看到爲Drawable接收Physics當其update方法被調用。
這種解決方案的缺點是:

  • 組件的update方法必須得到一個指針參數,即使他們並不需要參考任何其他組件。
  • 如果存在需要引用多個組件的組件,則您必須獲取兩個或多個指針作爲update方法的參數,或者要投入void *
相關問題