fork(2) download
  1. #include <iostream>
  2. #include <map>
  3. #include <vector>
  4.  
  5. /**
  6. * Receiver
  7. */
  8. class EBaseReceiver
  9. {
  10. protected:
  11. static std::size_t nextId;
  12. };
  13.  
  14. template <typename TEventData>
  15. class Receiver : public EBaseReceiver
  16. {
  17. friend class EventManager;
  18. public:
  19. virtual void onEventReceive( const TEventData& event ) = 0;
  20. static std::size_t getId() { return ID; }
  21. private:
  22. static std::size_t ID;
  23. };
  24.  
  25. /**
  26. * Event
  27. */
  28. struct BaseEvent
  29. {
  30. protected:
  31. static std::size_t nextId;
  32. };
  33.  
  34. template <typename T>
  35. struct Event : public BaseEvent
  36. {
  37. static std::size_t getId() { return ID; }
  38. static std::size_t ID;
  39. };
  40.  
  41. /**
  42. * EventManager
  43. */
  44. class EventManager
  45. {
  46. private:
  47.  
  48. typedef std::vector<EBaseReceiver*> ReceiverArray;
  49. typedef std::map<std::size_t, ReceiverArray> ImplSubscriberArray;
  50. ImplSubscriberArray subscribers;
  51.  
  52. public:
  53.  
  54. template< class TEvent, template<class> class TReceiver>
  55. void subscribe( TReceiver<TEvent>* receiver )
  56. {
  57. const std::size_t eventId = TEvent::getId();
  58. this->subscribers[eventId].push_back(receiver);
  59. }
  60.  
  61. template <typename TEvent>
  62. void emit( const TEvent& event )
  63. {
  64. const ReceiverArray& receivers = this->subscribers[TEvent::getId()];
  65. for( auto& receiver : receivers )
  66. {
  67. static_cast<Receiver<TEvent>&>((*receiver)).onEventReceive(event);
  68. }
  69. }
  70. };
  71.  
  72. /**
  73. * Test events
  74. */
  75. EventManager eventManager;
  76. struct HealthEvent : public Event<HealthEvent>{};
  77. struct DamageEvent : public Event<DamageEvent>{};
  78.  
  79. /**
  80. * Test classes
  81. */
  82. class DamageSystem : public Receiver<HealthEvent>, public Receiver<DamageEvent>
  83. {
  84. DamageSystem()
  85. {
  86. eventManager.subscribe<HealthEvent>(this);
  87. eventManager.subscribe<DamageEvent>(this);
  88. }
  89.  
  90. void onEventReceive( const HealthEvent& event ) { std::cout << "HealthEvent !" << std::endl; };
  91. void onEventReceive( const DamageEvent& event ) { std::cout << "DamageEvent !" << std::endl; };
  92. };
  93.  
  94. int main()
  95. {
  96. DamateSystem system;
  97. eventManager.emit(DamageEvent());
  98. return 0;
  99. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In constructor ‘DamageSystem::DamageSystem()’:
prog.cpp:86:43: error: no matching function for call to ‘EventManager::subscribe(DamageSystem* const)’
   eventManager.subscribe<HealthEvent>(this);
                                           ^
prog.cpp:86:43: note: candidate is:
prog.cpp:55:8: note: template<class TEvent, template<class> class TReceiver> void EventManager::subscribe(TReceiver<TEvent>*)
   void subscribe( TReceiver<TEvent>* receiver )
        ^
prog.cpp:55:8: note:   template argument deduction/substitution failed:
prog.cpp:86:43: note:   can't deduce a template for ‘TReceiver<TEvent>’ from non-template type ‘DamageSystem’
   eventManager.subscribe<HealthEvent>(this);
                                           ^
prog.cpp:87:43: error: no matching function for call to ‘EventManager::subscribe(DamageSystem* const)’
   eventManager.subscribe<DamageEvent>(this);
                                           ^
prog.cpp:87:43: note: candidate is:
prog.cpp:55:8: note: template<class TEvent, template<class> class TReceiver> void EventManager::subscribe(TReceiver<TEvent>*)
   void subscribe( TReceiver<TEvent>* receiver )
        ^
prog.cpp:55:8: note:   template argument deduction/substitution failed:
prog.cpp:87:43: note:   can't deduce a template for ‘TReceiver<TEvent>’ from non-template type ‘DamageSystem’
   eventManager.subscribe<DamageEvent>(this);
                                           ^
prog.cpp: In function ‘int main()’:
prog.cpp:96:2: error: ‘DamateSystem’ was not declared in this scope
  DamateSystem system;
  ^
prog.cpp:96:15: error: expected ‘;’ before ‘system’
  DamateSystem system;
               ^
stdout
Standard output is empty