fork download
  1. #include <iostream>
  2. #include <forward_list>
  3. using namespace std;
  4.  
  5. class EventResizeEventListener
  6. {
  7. public:
  8. virtual ~EventResizeEventListener() = default;
  9. virtual void Resize(uint32_t w, uint32_t h) = 0;
  10. };
  11.  
  12. template<typename T, typename ... Args>
  13. class EventSignal
  14. {
  15. typedef void(T::*Func)(Args ...);
  16. struct listData
  17. {
  18. void operator()(Args ...args) { (listener->*func)(args ...); }
  19.  
  20. T *listener = nullptr;
  21. Func func;
  22. bool active = false;
  23. };
  24.  
  25. public:
  26.  
  27. void Connect(T *listener, void(T::*f)(Args ...))
  28. {
  29. // todo: register id
  30. listData data = { listener, f, true };
  31. m_lists.emplace_front(data);
  32. }
  33.  
  34. void operator()(Args ...args) noexcept
  35. {
  36. for (auto &i : m_lists)
  37. {
  38. if (i.active)
  39. {
  40. i(args...);
  41. }
  42. else
  43. ;// todo: remove
  44. }
  45. }
  46.  
  47. private:
  48. std::forward_list<listData> m_lists;
  49. };
  50.  
  51.  
  52. // кастомный класс
  53. class FooBla : public EventResizeEventListener
  54. {
  55. public:
  56. void Resize(uint32_t w, uint32_t h) final
  57. {
  58. std::cout << w << " " << h << std::endl;
  59. }
  60. };
  61.  
  62.  
  63. int main() {
  64. FooBla fff;
  65.  
  66. // класс оповещения
  67. EventSignal<EventResizeEventListener, uint32_t, uint32_t> siga;
  68.  
  69. // регистрация слушателя
  70. siga.Connect(&fff, &EventResizeEventListener::Resize);
  71.  
  72. // оповещение
  73. siga(10, 20);
  74.  
  75. return 0;
  76. }
Success #stdin #stdout 0s 4492KB
stdin
Standard input is empty
stdout
10 20