diff options
Diffstat (limited to 'deps/entityx/entityx/Event.h')
-rw-r--r-- | deps/entityx/entityx/Event.h | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/deps/entityx/entityx/Event.h b/deps/entityx/entityx/Event.h deleted file mode 100644 index cb7b3ab..0000000 --- a/deps/entityx/entityx/Event.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2012 Alec Thomas <alec@swapoff.org> - * All rights reserved. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. - * - * Author: Alec Thomas <alec@swapoff.org> - */ - -#pragma once - -#include <cstdint> -#include <cstddef> -#include <vector> -#include <list> -#include <unordered_map> -#include <memory> -#include <utility> -#include "entityx/config.h" -#include "entityx/3rdparty/simplesignal.h" -#include "entityx/help/NonCopyable.h" - - -namespace entityx { - - -/// Used internally by the EventManager. -class BaseEvent { - public: - typedef std::size_t Family; - - virtual ~BaseEvent(); - - protected: - static Family family_counter_; -}; - - -typedef Simple::Signal<void (const void*)> EventSignal; -typedef std::shared_ptr<EventSignal> EventSignalPtr; -typedef std::weak_ptr<EventSignal> EventSignalWeakPtr; - - -/** - * Event types should subclass from this. - * - * struct Explosion : public Event<Explosion> { - * Explosion(int damage) : damage(damage) {} - * int damage; - * }; - */ -template <typename Derived> -class Event : public BaseEvent { - public: - /// Used internally for registration. - static Family family() { - static Family family = family_counter_++; - return family; - } -}; - - -class BaseReceiver { - public: - virtual ~BaseReceiver() { - for (auto connection : connections_) { - auto &ptr = connection.second.first; - if (!ptr.expired()) { - ptr.lock()->disconnect(connection.second.second); - } - } - } - - // Return number of signals connected to this receiver. - std::size_t connected_signals() const { - std::size_t size = 0; - for (auto connection : connections_) { - if (!connection.second.first.expired()) { - size++; - } - } - return size; - } - - private: - friend class EventManager; - std::unordered_map<BaseEvent::Family, std::pair<EventSignalWeakPtr, std::size_t>> connections_; -}; - - -template <typename Derived> -class Receiver : public BaseReceiver { - public: - virtual ~Receiver() {} -}; - - -/** - * Handles event subscription and delivery. - * - * Subscriptions are automatically removed when receivers are destroyed.. - */ -class EventManager : entityx::help::NonCopyable { - public: - EventManager(); - virtual ~EventManager(); - - /** - * Subscribe an object to receive events of type E. - * - * Receivers must be subclasses of Receiver and must implement a receive() method accepting the given event type. - * - * eg. - * - * struct ExplosionReceiver : public Receiver<ExplosionReceiver> { - * void receive(const Explosion &explosion) { - * } - * }; - * - * ExplosionReceiver receiver; - * em.subscribe<Explosion>(receiver); - */ - template <typename E, typename Receiver> - void subscribe(Receiver &receiver) { - void (Receiver::*receive)(const E &) = &Receiver::receive; - auto sig = signal_for(Event<E>::family()); - auto wrapper = EventCallbackWrapper<E>(std::bind(receive, &receiver, std::placeholders::_1)); - auto connection = sig->connect(wrapper); - BaseReceiver &base = receiver; - base.connections_.insert(std::make_pair(Event<E>::family(), std::make_pair(EventSignalWeakPtr(sig), connection))); - } - - /** - * Unsubscribe an object in order to not receive events of type E anymore. - * - * Receivers must have subscribed for event E before unsubscribing from event E. - * - */ - template <typename E, typename Receiver> - void unsubscribe(Receiver &receiver) { - BaseReceiver &base = receiver; - // Assert that it has been subscribed before - assert(base.connections_.find(Event<E>::family()) != base.connections_.end()); - auto pair = base.connections_[Event<E>::family()]; - auto connection = pair.second; - auto &ptr = pair.first; - if (!ptr.expired()) { - ptr.lock()->disconnect(connection); - } - base.connections_.erase(Event<E>::family()); - } - - template <typename E> - void emit(const E &event) { - auto sig = signal_for(Event<E>::family()); - sig->emit(&event); - } - - /** - * Emit an already constructed event. - */ - template <typename E> - void emit(std::unique_ptr<E> event) { - auto sig = signal_for(Event<E>::family()); - sig->emit(event.get()); - } - - /** - * Emit an event to receivers. - * - * This method constructs a new event object of type E with the provided arguments, then delivers it to all receivers. - * - * eg. - * - * std::shared_ptr<EventManager> em = new EventManager(); - * em->emit<Explosion>(10); - * - */ - template <typename E, typename ... Args> - void emit(Args && ... args) { - // Using 'E event(std::forward...)' causes VS to fail with an internal error. Hack around it. - E event = E(std::forward<Args>(args) ...); - auto sig = signal_for(std::size_t(Event<E>::family())); - sig->emit(&event); - } - - std::size_t connected_receivers() const { - std::size_t size = 0; - for (EventSignalPtr handler : handlers_) { - if (handler) size += handler->size(); - } - return size; - } - - private: - EventSignalPtr &signal_for(std::size_t id) { - if (id >= handlers_.size()) - handlers_.resize(id + 1); - if (!handlers_[id]) - handlers_[id] = std::make_shared<EventSignal>(); - return handlers_[id]; - } - - // Functor used as an event signal callback that casts to E. - template <typename E> - struct EventCallbackWrapper { - explicit EventCallbackWrapper(std::function<void(const E &)> callback) : callback(callback) {} - void operator()(const void *event) { callback(*(static_cast<const E*>(event))); } - std::function<void(const E &)> callback; - }; - - std::vector<EventSignalPtr> handlers_; -}; - -} // namespace entityx |