Remove Subscriber and make Listener more safe

There could be not nice situation when bus dies and Listener wants to unlisten. That was easy to
achieve e.g. bad order in class fields. (Order of destruction matters)
This commit is contained in:
Dawid Drozd 2019-09-14 15:56:09 +02:00
parent 0efc4264fc
commit 8f6eb24549
5 changed files with 10 additions and 111 deletions

View File

@ -46,9 +46,8 @@ add_library(EventBus
# New version of EventBus 3.0 # New version of EventBus 3.0
include/dexode/EventBus.hpp include/dexode/EventBus.hpp
include/dexode/eventbus/Listener.hpp include/dexode/eventbus/Listener.hpp
include/dexode/eventbus/Subscriber.hpp
src/dexode/eventbus/strategy/Protected.cpp include/dexode/eventbus/strategy/Protected.hpp src/dexode/eventbus/strategy/Protected.cpp include/dexode/eventbus/strategy/Protected.hpp
src/dexode/eventbus/strategy/Transaction.cpp include/dexode/eventbus/strategy/Transaction.hpp include/dexode/eventbus/strategy/Transaction.hpp
) )
add_library(Dexode::EventBus ALIAS EventBus) add_library(Dexode::EventBus ALIAS EventBus)
@ -63,7 +62,6 @@ target_include_directories(EventBus PUBLIC
set(EventBus_PUBLIC_HEADERS set(EventBus_PUBLIC_HEADERS
include/dexode/EventBus.hpp include/dexode/EventBus.hpp
include/dexode/eventbus/Listener.hpp include/dexode/eventbus/Listener.hpp
include/dexode/eventbus/Subscriber.hpp
include/dexode/eventbus/strategy/Protected.hpp include/dexode/eventbus/strategy/Protected.hpp
include/dexode/eventbus/strategy/Transaction.hpp include/dexode/eventbus/strategy/Transaction.hpp
) )

View File

@ -9,7 +9,6 @@
#include <eventbus/EventBus.h> #include <eventbus/EventBus.h>
#include "eventbus/Listener.hpp" #include "eventbus/Listener.hpp"
#include "eventbus/Subscriber.hpp"
#include "eventbus/internal/common.h" #include "eventbus/internal/common.h"
namespace dexode namespace dexode
@ -22,7 +21,6 @@ class EventBus
public: public:
using Listener = eventbus::Listener<EventBus<Strategy>>; using Listener = eventbus::Listener<EventBus<Strategy>>;
using Subscriber = eventbus::Subscriber<EventBus<Strategy>>;
constexpr EventBus() = default; constexpr EventBus() = default;
~EventBus() = default; ~EventBus() = default;
@ -33,11 +31,6 @@ public:
EventBus& operator=(EventBus&&) = delete; EventBus& operator=(EventBus&&) = delete;
EventBus& operator=(const EventBus&) = delete; EventBus& operator=(const EventBus&) = delete;
Listener createListener()
{
return Listener{*this};
}
template <typename Event> template <typename Event>
constexpr void post(const Event& event) constexpr void post(const Event& event)
{ {

View File

@ -13,20 +13,17 @@ class Listener
public: public:
explicit Listener() = default; // Dummy listener explicit Listener() = default; // Dummy listener
explicit Listener(Bus& bus) explicit Listener(std::shared_ptr<Bus> bus)
: _id{bus.newListenerID()} : _id{bus->newListenerID()}
, _bus{&bus} , _bus{std::move(bus)}
{} {}
Listener(const Listener& other) = delete; Listener(const Listener& other) = delete;
Listener(Listener&& other) Listener(Listener&& other)
: _id(other._id) : _id(other._id)
, _bus(other._bus) , _bus(std::move(other._bus))
{ {}
other._id = 0;
other._bus = nullptr;
}
~Listener() ~Listener()
{ {
@ -38,7 +35,7 @@ public:
Listener& operator=(const Listener& other) = delete; Listener& operator=(const Listener& other) = delete;
Listener& operator=(Listener&& other) Listener& operator=(Listener&& other) noexcept
{ {
if(this == &other) if(this == &other)
{ {
@ -47,12 +44,10 @@ public:
if(_bus != nullptr) if(_bus != nullptr)
{ {
unlistenAll(); unlistenAll(); // remove previous
} }
_id = other._id; _id = other._id;
other._id = 0; _bus = std::move(other._bus);
_bus = other._bus;
other._bus = nullptr;
return *this; return *this;
} }
@ -68,16 +63,6 @@ public:
std::forward<std::function<void(const Event&)>>(callback)); std::forward<std::function<void(const Event&)>>(callback));
} }
template <class Event>
void listen(const std::function<void(const Event&)>& callback)
{
if(_bus == nullptr)
{
throw std::runtime_error{"bus is null"};
}
_bus->template listen<Event>(_id, callback);
}
void unlistenAll() void unlistenAll()
{ {
if(_bus == nullptr) if(_bus == nullptr)
@ -99,7 +84,7 @@ public:
private: private:
std::uint32_t _id = 0; std::uint32_t _id = 0;
Bus* _bus = nullptr; std::shared_ptr<Bus> _bus = nullptr;
}; };
} // namespace dexode::eventbus } // namespace dexode::eventbus

View File

@ -1,71 +0,0 @@
#pragma once
#include "dexode/EventBus.hpp"
namespace dexode::eventbus
{
template <class Bus>
class Subscriber
{
public:
Subscriber(std::shared_ptr<Bus> retainBus)
: _listener{*retainBus}
, _bus{std::move(retainBus)}
{}
Subscriber(Subscriber&& other)
: _listener(std::move(other._listener))
, _bus(std::move(other._bus))
{}
~Subscriber()
{
unlistenAll(); // extra safety if order of members is inverse
}
Subscriber& operator=(Subscriber&& other)
{
if(this == &other)
{
return *this;
}
_listener = std::move(other._listener);
_bus = std::move(other._bus);
return *this;
}
template <class Event>
void listen(std::function<void(const Event&)>&& callback)
{
_listener.template listen<Event>(std::forward<std::function<void(const Event&)>>(callback));
}
template <class Event>
void listen(const std::function<void(const Event&)>& callback)
{
_listener.template listen<Event>(callback);
}
void unlistenAll()
{
_listener.unlistenAll();
}
template <typename Event>
void unlisten()
{
_listener.template unlisten<Event>();
}
const std::shared_ptr<Bus>& getEventBus() const
{
return _bus;
}
private:
Listener<Bus> _listener;
std::shared_ptr<Bus> _bus; // own
};
} // namespace dexode::eventbus

View File

@ -1,6 +0,0 @@
#include "dexode/eventbus/strategy/Transaction.hpp"
namespace dexode::eventbus::strategy
{
}