A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EventEmitter.h 1.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #pragma once
  2. #include <functional>
  3. #include "util.h"
  4. #include "SlotVector.h"
  5. namespace Swan {
  6. // So that EventListener doesn't have to be a template
  7. class EventEmitterInterface {
  8. public:
  9. virtual void unsubscribe(size_t id) = 0;
  10. protected:
  11. ~EventEmitterInterface() = default;
  12. };
  13. class EventListener: NonCopyable {
  14. public:
  15. EventListener() {}
  16. EventListener(EventEmitterInterface *emitter, size_t id):
  17. emitter_(emitter), id_(id) {}
  18. EventListener(EventListener &&other) noexcept:
  19. emitter_(other.emitter_), id_(other.id_) {
  20. other.emitter_ = nullptr;
  21. }
  22. EventListener &operator=(EventListener &&other) noexcept {
  23. emitter_ = other.emitter_;
  24. id_ = other.id_;
  25. other.emitter_ = nullptr;
  26. return *this;
  27. }
  28. ~EventListener() {
  29. if (emitter_)
  30. emitter_->unsubscribe(id_);
  31. }
  32. void unsubscribe() {
  33. if (emitter_) {
  34. emitter_->unsubscribe(id_);
  35. emitter_ = nullptr;
  36. }
  37. }
  38. private:
  39. EventEmitterInterface *emitter_ = nullptr;
  40. size_t id_;
  41. };
  42. template<typename... Evt>
  43. class EventEmitter final: public EventEmitterInterface {
  44. public:
  45. using Callback = std::function<void(Evt...)>;
  46. void emit(Evt... evt) {
  47. for (auto &cb: callbacks_)
  48. cb(evt...);
  49. }
  50. EventListener subscribe(Callback cb) {
  51. size_t id = callbacks_.insert(std::move(cb));
  52. return EventListener(this, id);
  53. }
  54. void unsubscribe(size_t id) {
  55. callbacks_.erase(id);
  56. }
  57. private:
  58. SlotVector<Callback, SlotVectorDefaultSentinel<std::nullptr_t>> callbacks_;
  59. };
  60. }