有没有更好的方法来制作 EventManager

Is there a better way to make an EventManager

我为我的 EventManager 编写了一些代码,它工作正常,但问题是,我创建它时进行了大量的复制粘贴,我认为每次你开始复制粘贴在几行中,您的代码设计得很糟糕。

所以,在 EventManager 上做了很多复制粘贴之后,我认为是时候找出是否有另一种方法来制作它了(可能有,而且可能更好)。

我实现的是当一个事件发生时(window.pollEvent(event)),它调用EventManagerclass的onEvent(sf::Event, sf::RenderWindow*)方法,并且对于我需要的每个事件为了听,我调用了监听器的所有实例。

这是 class :

public:
    void registerKeyPressed(std::shared_ptr<KeyPressedEventListener> listener);
    void registerWindowResized(std::shared_ptr<WindowResizedEventListener> listener);
    void registerWindowFrameUpdate(std::shared_ptr<WindowFrameUpdateEventListener> listener);
private:
    std::vector<std::shared_ptr<KeyPressedEventListener>> m_keyPressedListeners;
    std::vector<std::shared_ptr<WindowResizedEventListener>> m_windowResizedListeners;
    std::vector<std::shared_ptr<WindowFrameUpdateEventListener>> m_windowFrameUpdateListeners;

所以,问题是,只有 3 个听众需要很多代码(我目前有 6 个,但显示它们没有用,因为代码总是相似的)。

我的问题是我希望 class 能够一次收听一个、两个或更多事件,因此我所有的听众都有一个不同的函数,该函数在事件发生时被调用。例如,这三个侦听器具有函数 onKeypressed(sf::Event);onWindowResized(sf::Event, sf::RenderWindow* window);onFrameUpdate(sf::RenderWindow* window);。这是我发现使这段代码工作的唯一方法。

它确实有效,但我想做得更好,因为每个事件都有很多代码:

void EventManager::onEvent(sf::Event event, sf::RenderWindow* window) { // The window argument is used further, but it's not useful to show it here as the code is quite the same
    switch (event.type) {
    case sf::Event::Resized:
        for (unsigned int i = 0; i < m_windowResizedListeners.size(); i++) {
            if (m_windowResizedListeners.at(i)->onWindowResized(event)) break; // The events return a bool value : True if the loop has to stop (for an error, for example), false otherwise. I always return false unless an error happen, but it's in case I need to stop it.
        }
        break;
    }
}
void EventManager::registerWindowResized(std::shared_ptr<WindowResizedEventListener> listener) {
    m_windowResizedListeners.push_back(listener);
}

而且我必须为每个事件复制此代码。如果有错误,您明白要更正它需要很多工作,所以我希望您能帮助我找到更好的方法来实现它。

感谢您的帮助。

你可以使用一个普通的 class:

class EventHandler{

public:

    virtual void handle(sf::RenderWindow &window) = 0;
};

class EventManager {

public:
    void registerKeyPressed(std::shared_ptr<EventHandler> listener);
    void registerWindowResized(std::shared_ptr<EventHandler> listener);
    void registerWindowFrameUpdate(std::shared_ptr<EventHandler> listener);
private:
    std::vector<std::shared_ptr<EventHandler>> m_keyPressedListeners;
    std::vector<std::shared_ptr<EventHandler>> m_windowResizedListeners;
    std::vector<std::shared_ptr<EventHandler>> m_windowFrameUpdateListeners;
}

现在可以在class中定义一个map了,key是事件类型,value是他的listener的vector。

    std::map<int,std::vector<std::shared_ptr<EventHandler>>*> eventType;
}

//...

EventManager::EventManager(){
    eventType[sf::EventType::Resized] = &m_windowResizedListeners;
    eventType[sf::EventType::KeyPressed] = &m_keyPressedListeners;

    //Keep going...
}

现在,onEvent 函数非常简单:

void EventManager::onEvent(sf::Event event, sf::RenderWindow* window) {
    std::vector<std::shared_ptr<EventHandler>>* ptr = eventType[event.type];
    for (int i = 0;i < ptr->size();i++)
        (*ptr)[i]->handle(window);
}

举个例子:

class SettingsSaver : public EventHandler{

   public:
       void handle(sf::RenderWindow &window) override {
           std::cout << "I am saving the state in the hardrive before of exit" << std::endl;
       }
}

class MoveHero : public EventHandler{

   public:
       void handle(sf::RenderWindow &window) override {
           std::cout << "I am moving the character" << std::endl;
       }
}

// Main

std::shared_ptr<EventHandler> settingsSaver(new SettingsSaver);
std::shared_ptr<EventHandler> moveHero(new MoveHero);

EventManager manager;
manager.registerWindowClosed(settingsSaver);
manager.registerKeyPressed(moveHero);