generic Observer Pattern.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include <iostream>
  2. #include <string>
  3. #include "dispatcher.h" // the implementation is here
  4. // https://www.theimpossiblecode.com/blog/c11-generic-observer-pattern/
  5. //
  6. // https://gist.github.com/sagi-z/d044c7daeaa9e8ef8e8ceae17d472bdb
  7. // https://gist.github.com/sagi-z/f8b734a2240ce203ba5b2977e54b4414
  8. using namespace std;
  9. // a dummy enum for this example
  10. enum EventEnum { EVENT1, EVENT2, EVENT3 };
  11. int main(int argc, char* argv[])
  12. {
  13. // 2 example dispatchers, any number of arguments and types can be used:
  14. Dispatcher<string, EventEnum> d1;// here any cb(string, EventEnum) can register
  15. Dispatcher<int, long, double> d2;// here any cb(int, long, double) can register
  16. // From the "most simple" lambda usage example ...
  17. auto cbid1 = d1.addCB([](string str, EventEnum evt) {
  18. cout << "CB1:" << str << " got event " << evt << endl;
  19. });
  20. auto cbid2 = d1.addCB([](string str, EventEnum evt) {
  21. cout << "CB2:" << str << " got event " << evt << endl;
  22. });
  23. d1.broadcast("** Dispatching to 2 is **", EVENT1);
  24. d1.broadcast("** E a s y **", EVENT2);
  25. d1.delCB(cbid1); // remove the first callback
  26. d1.broadcast("** Dispatching to 1 is **", EVENT1);
  27. d1.broadcast("** E a s y **", EVENT2);
  28. d1.delCB(cbid2); // remove the second callback
  29. d1.broadcast("** No one will see this **", EVENT3);
  30. // ... to the "most complex" **live** instance (not copy) usage example:
  31. class MyClassWithMethod {
  32. public:
  33. void registerCB(Dispatcher<int, long, double>& dispatcher) {
  34. using namespace std::placeholders;
  35. dispatcher.addCB(std::bind(&MyClassWithMethod::listener, this, _1, _2, _3));
  36. }
  37. private:
  38. // any method with the right signature can be used:
  39. void listener(int i, long l, double d) {
  40. cout << "listener() for " << this << ", got: " <<
  41. i << ", " << l << ", " << d << endl;
  42. }
  43. };
  44. MyClassWithMethod instance1;
  45. MyClassWithMethod instance2;
  46. instance1.registerCB(d2);
  47. instance2.registerCB(d2);
  48. d2.broadcast(65000, 12345678910, 3.14159265);
  49. d2.broadcast(56000, 1987654321, 14159265.3);
  50. return 0;
  51. }
  52. /* Example output:
  53. CB1:** Dispatching to 2 is ** got event 0
  54. CB2:** Dispatching to 2 is ** got event 0
  55. CB1:** E a s y ** got event 1
  56. CB2:** E a s y ** got event 1
  57. CB2:** Dispatching to 1 is ** got event 0
  58. CB2:** E a s y ** got event 1
  59. listener() for 0x7ffcb1bfe6fe, got: 65000, 12345678910, 3.14159
  60. listener() for 0x7ffcb1bfe6ff, got: 65000, 12345678910, 3.14159
  61. listener() for 0x7ffcb1bfe6fe, got: 56000, 1987654321, 1.41593e+07
  62. listener() for 0x7ffcb1bfe6ff, got: 56000, 1987654321, 1.41593e+07
  63. */