|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- #pragma once
-
- #include <functional>
-
- #include "util.h"
- #include "SlotVector.h"
-
- namespace Swan {
-
- // So that EventListener doesn't have to be a template
- class EventEmitterInterface {
- public:
- virtual void unsubscribe(size_t id) = 0;
-
- protected:
- ~EventEmitterInterface() = default;
- };
-
- class EventListener: NonCopyable {
- public:
- EventListener() {}
-
- EventListener(EventEmitterInterface *emitter, size_t id):
- emitter_(emitter), id_(id) {}
-
- EventListener(EventListener &&other) noexcept:
- emitter_(other.emitter_), id_(other.id_) {
- other.emitter_ = nullptr;
- }
-
- EventListener &operator=(EventListener &&other) noexcept {
- emitter_ = other.emitter_;
- id_ = other.id_;
- other.emitter_ = nullptr;
- return *this;
- }
-
- ~EventListener() {
- if (emitter_)
- emitter_->unsubscribe(id_);
- }
-
- void unsubscribe() {
- if (emitter_) {
- emitter_->unsubscribe(id_);
- emitter_ = nullptr;
- }
- }
-
- private:
- EventEmitterInterface *emitter_ = nullptr;
- size_t id_;
- };
-
- template<typename... Evt>
- class EventEmitter final: public EventEmitterInterface {
- public:
- using Callback = std::function<void(Evt...)>;
-
- void emit(Evt... evt) {
- for (auto &cb: callbacks_)
- cb(evt...);
- }
-
- EventListener subscribe(Callback cb) {
- size_t id = callbacks_.insert(std::move(cb));
- return EventListener(this, id);
- }
-
- void unsubscribe(size_t id) {
- callbacks_.erase(id);
- }
-
- private:
- SlotVector<Callback, SlotVectorDefaultSentinel<std::nullptr_t>> callbacks_;
- };
-
- }
|