SHARE
TWEET

Event system for C++11

ulfben Oct 6th, 2016 (edited) 33 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2. #include <vector>
  3. #include <map>
  4. #include <functional>
  5. #include <algorithm>
  6. #include "GameEvents.h"
  7. using CallBack = std::function<void(const Event&)>;
  8. class Broadcaster {    
  9.     using Listener = std::pair<void*, CallBack>;
  10.     using Listeners = std::vector<Listener>;
  11.     std::map<EventName, Listeners> _listeners;
  12.     void removeListener(Listeners& l, const void* const object) {
  13.         l.erase(std::remove_if(l.begin(), l.end(), [object](const Listener& t) {return t.first == object; }), l.end());
  14.     }
  15. public:
  16.     template<class T>  
  17.     void addEventListener(const EventName name, T* object, void(T::*member)(const Event&)) {   
  18.         addEventListener(name, object, std::bind(member, object, std::placeholders::_1));
  19.     };
  20.     void addEventListener(const EventName name, void* object, CallBack method) {
  21.         _listeners[name].push_back(std::make_pair(object, method));
  22.     };
  23.     void removeEventListener(const EventName name, const void* const object) {
  24.         removeListener(_listeners[name], object);
  25.     }; 
  26.     void removeEventListener(const void* const object) {
  27.         for (auto& kv : _listeners) {
  28.             removeListener(kv.second, object);
  29.         }
  30.     }
  31.     ~Broadcaster() { _listeners.clear(); };
  32. protected:
  33.     void broadCastEvent(const Event& e) {
  34.         if (_listeners.find(e.type()) == _listeners.end()) return; //avoid creating an index in the map    
  35.         for (Listener& listener : _listeners[e.type()]) {
  36.             listener.second(e);
  37.         }
  38.     };
  39. };
  40.  
  41. //Used as such:
  42. InputManager _input{}; //InputManager inherits from Broadcaster
  43.     //it can call the protected function broadCastEvent(const Event&)
  44.      
  45. Game::Game() {
  46.     //Register for events (these calls are practically equivalent, use whichever form you like):
  47.     _input.addEventListener(OnKeyUp::NAME, this, &Game::onKeyEvent);
  48.     _input.addEventListener(OnKeyDown::NAME, this, [=](const Event& e) { this->onKeyEvent(e);  });
  49. }
  50.  
  51. Game::~Game() {
  52.     //Remember to de-register before your listener is destroyed!
  53.     _input.removeEventListener(OnKeyUp::NAME, this);  //remove me from this event type
  54.     _input.removeEventListener(this);                 //remove me from *all* events
  55. }
  56.  
  57. //listeners callback signature: void(const Event&)
  58. void Game::onKeyEvent(const Event& e) {
  59.     InputManager* i = e.source(); //my Events hold a pointer to the source
  60.     switch(e.type()){/**/}
  61. }
RAW Paste Data
Top