我为我的EventManager
制作了一些代码,它工作正常,但问题是,我用很多复制粘贴创建了它,我想每次你开始复制粘贴一个几行,你的代码设计得很糟糕。
所以,在EventManager
上做了很多复制粘贴后,我认为现在是时候找出是否有另一种方法来制作它(可能有,也可能更好)。
我所取得的成就是当一个事件发生时(window.pollEvent(event)
),它会调用onEvent(sf::Event, sf::RenderWindow*)
类的EventManager
方法,对于我需要监听的每个事件,我都会调用所有听众的实例。
这是班级:
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个,但是因为代码总是相似的,所以显示它们没有用。)
我的问题是我希望一个类能够一次监听一个,两个或更多事件,所以我的所有监听器都有一个不同的函数,当事件发生时调用它。例如,这三个侦听器具有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);
}
我必须为每个事件复制此代码。如果有错误,你就会明白纠正它会有很多工作,所以我希望你能帮我找到更好的方法来实现它。
感谢您的帮助。
答案 0 :(得分:0)
您可以使用公共类:
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;
}
您现在可以在类中定义一个地图,键是事件类型,值是他的侦听器矢量。
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);