有没有更好的方法来制作 EventManager
Is there a better way to make an EventManager
我为我的 EventManager
编写了一些代码,它工作正常,但问题是,我创建它时进行了大量的复制粘贴,我认为每次你开始复制粘贴在几行中,您的代码设计得很糟糕。
所以,在 EventManager
上做了很多复制粘贴之后,我认为是时候找出是否有另一种方法来制作它了(可能有,而且可能更好)。
我实现的是当一个事件发生时(window.pollEvent(event)
),它调用EventManager
class的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);
我为我的 EventManager
编写了一些代码,它工作正常,但问题是,我创建它时进行了大量的复制粘贴,我认为每次你开始复制粘贴在几行中,您的代码设计得很糟糕。
所以,在 EventManager
上做了很多复制粘贴之后,我认为是时候找出是否有另一种方法来制作它了(可能有,而且可能更好)。
我实现的是当一个事件发生时(window.pollEvent(event)
),它调用EventManager
class的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);