mirror of
https://github.com/gelldur/EventBus.git
synced 2024-12-26 10:41:01 +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/strategy/Protected.cpp src/dexode/eventbus/strategy/Protected.hpp
|
||||
src/dexode/eventbus/strategy/Transaction.hpp
|
||||
src/dexode/eventbus/TagEventBus.hpp
|
||||
)
|
||||
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>
|
||||
class Listener;
|
||||
|
||||
template <typename>
|
||||
class TagEventBus;
|
||||
} // namespace dexode::eventbus
|
||||
|
||||
namespace dexode::eventbus::internal
|
||||
@ -20,6 +23,9 @@ class ListenerAttorney
|
||||
template <typename>
|
||||
friend class dexode::eventbus::Listener;
|
||||
|
||||
template <typename>
|
||||
friend class eventbus::TagEventBus;
|
||||
|
||||
private:
|
||||
static constexpr std::uint32_t newListenerID(EventBus_t& bus)
|
||||
{
|
||||
|
@ -20,6 +20,7 @@ add_executable(EventBusTest
|
||||
src/EventCollectorTest.cpp
|
||||
src/EventIdTest.cpp
|
||||
src/NotifierTest.cpp
|
||||
src/TestTagEventBus.cpp
|
||||
)
|
||||
|
||||
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