2013-10-07 78 views
0

我的目標是編寫一個處理遊戲事件的系統,可以通過發生某種事件觸發事件,例如玩家走路殺死某物或獲取物品或您有什麼。要做到這一點,我需要一個虛擬函數,當事件被觸發時執行。下面是我想要做的要點(我知道這並不在它的當前狀態的工作,但它是我能解釋我的目標是什麼,最好的方法):將虛擬功能放入結構中

class EventManager 
{ 
    public: 
     typedef struct 
     { 
      virtual void run(); 
      bool triggered; 
      std::string name; 
     } Event; 

     void newEvent(std::string eventName) 
     { 
      Event newEvent; 
      newEvent.name = eventName; 
      newEvent.triggered = false; 
      eventStack.push_back(newEvent); 
     } 

     void triggerEvent(std::string eventName) 
     { 
      std::vector<Event>::iterator itr; 

      for(itr = eventStack.begin(); itr != eventStack.end(); itr++) 
      { 
       if(itr->name == eventName) itr->triggered = true; 
      } 
     } 

     std::vector<Event> eventStack; 
}; 

int main() 
{ 
    EventManager* myEventManager = 0; 
    myEventManager = new EventManager(); 

    myEventManager->newEvent("Event1"); 
    myEventManager->eventStack.back()::run() 
    { 
     std::cout << "Event1 has been triggered"; 
    } 

    std::vector<EventManager::Event>::iterator itr; 

    for(itr = myEventManager->eventStack.begin(); itr != myEventManager->eventStack.end(); itr++) 
    { 
     if(itr->triggered) 
     { 
      itr->run(); 
      itr->triggered = false; 
     } 
    } 

    return 0; 
} 

所以基本上我的問題是,如何我可以允許我的圖書館的用戶定義在觸發事件時會發生什麼情況,而不必讓他們爲每個事件編寫課程或其他內容?

+0

他們必須把每個事件的代碼放在某個地方,對吧?作爲放置地點的課程有什麼問題? –

+0

讓用戶創建一個類來定義一個函數似乎過於複雜。這將是接近一行的東西。就像玩家在這個方塊上的步驟將他傳送到別處的另一個方塊一樣,從字面上來說,一次調用setPosition(x,y)就是這樣。 – Mike

回答

1

想一想:什麼是真正的事件?事件(從其實現的角度來看)只是處理程序(回調)的列表。

你叫Event是一個真正代表事件處理程序的類,而你的EventManager本身就是事件。

問題的解決方案非常簡單:使用函數引用(函數指針,lambdas,函子)來存儲處理程序集。例如:

template<typename... ARGS> 
struct event 
{ 
    typedef void(*)(ARGS...) handler_type; 


    void add_handler(handler_type handler) 
    { 
     handlers.push_back(handler); 
    } 

    void raise_event(ARGS args...) 
    { 
     for(handler_type handler : handlers) 
      handler(args...); 
    } 

private: 
    std::vector<handler_type> handlers; 
}; 


void on_foo(int a,int b) { std::cout << "on foo!!! (" << a << "," << b << ")" << std::end; } 


int main() 
{ 
    event<int,int> foo; 

    foo.add_handler(on_foo); 

    foo.raise_event(0,0); 
} 

上面的實現可以使用完美的轉發優化,但我不想過分複雜的例子。

+0

很好的答案!謝謝! – Mike