mirror of
https://github.com/gelldur/EventBus.git
synced 2024-12-27 12:21:02 +08:00
Add TagEventBus
This commit is contained in:
parent
890eaff178
commit
2bb9c3e679
@ -44,6 +44,7 @@ add_library(EventBus
|
|||||||
src/dexode/eventbus/Listener.hpp
|
src/dexode/eventbus/Listener.hpp
|
||||||
src/dexode/eventbus/strategy/Protected.cpp src/dexode/eventbus/strategy/Protected.hpp
|
src/dexode/eventbus/strategy/Protected.cpp src/dexode/eventbus/strategy/Protected.hpp
|
||||||
src/dexode/eventbus/strategy/Transaction.hpp
|
src/dexode/eventbus/strategy/Transaction.hpp
|
||||||
|
src/dexode/eventbus/TagEventBus.hpp
|
||||||
)
|
)
|
||||||
add_library(Dexode::EventBus ALIAS EventBus)
|
add_library(Dexode::EventBus ALIAS EventBus)
|
||||||
|
|
||||||
|
121
lib/src/dexode/eventbus/TagEventBus.hpp
Normal file
121
lib/src/dexode/eventbus/TagEventBus.hpp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
//
|
||||||
|
// Created by gelldur on 30.10.2019.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "dexode/EventBus.hpp"
|
||||||
|
|
||||||
|
namespace dexode::eventbus
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class Strategy>
|
||||||
|
class TagEventBus
|
||||||
|
{
|
||||||
|
template <typename>
|
||||||
|
friend class dexode::eventbus::internal::ListenerAttorney;
|
||||||
|
|
||||||
|
using EventBus_t = EventBus<Strategy>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using ListenerAll = eventbus::Listener<TagEventBus<Strategy>>;
|
||||||
|
using Listener = typename EventBus<Strategy>::Listener; // alias
|
||||||
|
|
||||||
|
TagEventBus(const std::vector<std::string>& tags)
|
||||||
|
{
|
||||||
|
for(const auto& tag : tags)
|
||||||
|
{
|
||||||
|
_tagToBus.emplace(tag, std::make_shared<EventBus_t>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~TagEventBus() = default;
|
||||||
|
|
||||||
|
TagEventBus(const TagEventBus&) = delete;
|
||||||
|
TagEventBus(TagEventBus&&) = delete;
|
||||||
|
|
||||||
|
TagEventBus& operator=(TagEventBus&&) = delete;
|
||||||
|
TagEventBus& operator=(const TagEventBus&) = delete;
|
||||||
|
|
||||||
|
template <typename Event>
|
||||||
|
void post(const Event& event)
|
||||||
|
{
|
||||||
|
_allBus.post(event);
|
||||||
|
for(auto& element : _tagToBus)
|
||||||
|
{
|
||||||
|
element.second->post(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Event>
|
||||||
|
void postpone(Event event)
|
||||||
|
{
|
||||||
|
_allBus.postpone(event);
|
||||||
|
for(auto& element : _tagToBus)
|
||||||
|
{
|
||||||
|
element.second->postpone(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Event>
|
||||||
|
void post(const std::string& tag, const Event& event)
|
||||||
|
{
|
||||||
|
_allBus.post(event);
|
||||||
|
_tagToBus.at(tag)->post(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Event>
|
||||||
|
void postpone(const std::string& tag, Event event)
|
||||||
|
{
|
||||||
|
_allBus.postpone(event);
|
||||||
|
_tagToBus.at(tag)->postpone(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t processAll()
|
||||||
|
{
|
||||||
|
return processLimit(std::numeric_limits<std::size_t>::max());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t processLimit(const std::size_t maxCountOfEvents)
|
||||||
|
{
|
||||||
|
return _allBus.processLimit(maxCountOfEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<EventBus<Strategy>>& get(const std::string& tag)
|
||||||
|
{
|
||||||
|
return _tagToBus.at(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EventBus_t _allBus;
|
||||||
|
std::map<std::string, std::shared_ptr<EventBus_t>> _tagToBus;
|
||||||
|
|
||||||
|
constexpr std::uint32_t newListenerID()
|
||||||
|
{
|
||||||
|
return internal::ListenerAttorney<EventBus_t>::newListenerID(_allBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Event>
|
||||||
|
constexpr void listen(const std::uint32_t listenerID,
|
||||||
|
std::function<void(const Event&)> callback)
|
||||||
|
{
|
||||||
|
internal::ListenerAttorney<EventBus_t>::template listen<Event>(
|
||||||
|
_allBus, listenerID, std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void unlistenAll(const std::uint32_t listenerID)
|
||||||
|
{
|
||||||
|
internal::ListenerAttorney<EventBus_t>::unlistenAll(_allBus, listenerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Event>
|
||||||
|
constexpr void unlisten(const std::uint32_t listenerID)
|
||||||
|
{
|
||||||
|
internal::ListenerAttorney<EventBus_t>::template unlisten<Event>(_allBus, listenerID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dexode::eventbus
|
@ -9,6 +9,9 @@ namespace dexode::eventbus
|
|||||||
{
|
{
|
||||||
template <typename>
|
template <typename>
|
||||||
class Listener;
|
class Listener;
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
class TagEventBus;
|
||||||
} // namespace dexode::eventbus
|
} // namespace dexode::eventbus
|
||||||
|
|
||||||
namespace dexode::eventbus::internal
|
namespace dexode::eventbus::internal
|
||||||
@ -20,6 +23,9 @@ class ListenerAttorney
|
|||||||
template <typename>
|
template <typename>
|
||||||
friend class dexode::eventbus::Listener;
|
friend class dexode::eventbus::Listener;
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
friend class eventbus::TagEventBus;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr std::uint32_t newListenerID(EventBus_t& bus)
|
static constexpr std::uint32_t newListenerID(EventBus_t& bus)
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@ add_executable(EventBusTest
|
|||||||
src/EventCollectorTest.cpp
|
src/EventCollectorTest.cpp
|
||||||
src/EventIdTest.cpp
|
src/EventIdTest.cpp
|
||||||
src/NotifierTest.cpp
|
src/NotifierTest.cpp
|
||||||
|
src/TestTagEventBus.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(EventBusTest PUBLIC
|
target_compile_options(EventBusTest PUBLIC
|
||||||
|
67
test/src/TestTagEventBus.cpp
Normal file
67
test/src/TestTagEventBus.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// Created by gelldur on 30.10.2019.
|
||||||
|
//
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
#include "dexode/eventbus/TagEventBus.hpp"
|
||||||
|
#include "dexode/eventbus/strategy/Protected.hpp"
|
||||||
|
|
||||||
|
using TagEventBus = dexode::eventbus::TagEventBus<dexode::eventbus::strategy::Protected>;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct EventWithMessage
|
||||||
|
{
|
||||||
|
std::string message = "no-msg";
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("Should notify only listeners with specific tag When using TagEventBus", "[TagEventBus]")
|
||||||
|
{
|
||||||
|
TagEventBus bus{{"gui", "backend"}};
|
||||||
|
auto listenerGlobal = TagEventBus::ListenerAll::createNotOwning(bus);
|
||||||
|
|
||||||
|
int counterGlobalListener = 0;
|
||||||
|
int counterTagGUIListener = 0;
|
||||||
|
int counterTagBackendListener = 0;
|
||||||
|
|
||||||
|
listenerGlobal.listen<EventWithMessage>([&](const EventWithMessage& event) {
|
||||||
|
INFO("[Global listener] Received: EventWithMessage:" << event.message);
|
||||||
|
++counterGlobalListener;
|
||||||
|
});
|
||||||
|
|
||||||
|
TagEventBus::Listener guiListener{bus.get("gui")};
|
||||||
|
guiListener.listen<EventWithMessage>([&](const EventWithMessage& event) {
|
||||||
|
INFO("[GUI listener] Received: EventWithMessage:" << event.message);
|
||||||
|
++counterTagGUIListener;
|
||||||
|
});
|
||||||
|
|
||||||
|
TagEventBus::Listener backendListener{bus.get("backend")};
|
||||||
|
backendListener.listen<EventWithMessage>([&](const EventWithMessage& event) {
|
||||||
|
INFO("[Backend listener] Received: EventWithMessage:" << event.message);
|
||||||
|
++counterTagBackendListener;
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
bus.post(EventWithMessage{"everyone should get this message (global listeners included)"});
|
||||||
|
REQUIRE(counterGlobalListener == 1);
|
||||||
|
REQUIRE(counterTagGUIListener == 1);
|
||||||
|
REQUIRE(counterTagBackendListener == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
bus.post("gui", EventWithMessage{"gui + global should get this message"});
|
||||||
|
REQUIRE(counterGlobalListener == 2);
|
||||||
|
REQUIRE(counterTagGUIListener == 2);
|
||||||
|
REQUIRE(counterTagBackendListener == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
bus.post("backend", EventWithMessage{"backend + global should get this message"});
|
||||||
|
REQUIRE(counterGlobalListener == 3);
|
||||||
|
REQUIRE(counterTagGUIListener == 2);
|
||||||
|
REQUIRE(counterTagBackendListener == 2);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user