From 63395f5a7e3dd9f2a52b2d6a254da89ec1d6e5e9 Mon Sep 17 00:00:00 2001 From: Dawid Drozd Date: Fri, 27 Jul 2018 14:38:40 +0200 Subject: [PATCH] Secure EventBus from wrong usage For example user previously could do such thing: bus.listen(...) bus.listen(...) Those we 2 different events :/ --- lib/include/eventbus/EventBus.h | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/include/eventbus/EventBus.h b/lib/include/eventbus/EventBus.h index d55d981..d4ffc7e 100644 --- a/lib/include/eventbus/EventBus.h +++ b/lib/include/eventbus/EventBus.h @@ -12,13 +12,21 @@ namespace Dexode template void type_id() // Helper for getting "type id" -{ -} +{} using type_id_t = void (*)(); // Function pointer class EventBus { + template + constexpr void validateEvent() + { + static_assert(std::is_const::value == false, "Struct must be without const"); + static_assert(std::is_volatile::value == false, "Struct must be without volatile"); + static_assert(std::is_reference::value == false, "Struct must be without reference"); + static_assert(std::is_pointer::value == false, "Struct must be without pointer"); + } + public: EventBus() = default; @@ -43,6 +51,8 @@ public: template int listen(const std::function& callback) { + validateEvent(); + const int token = ++_tokener; listen(token, callback); return token; @@ -56,6 +66,8 @@ public: template void listen(const int token, const std::function& callback) { + validateEvent(); + using Vector = VectorImpl; assert(callback && "callback should be valid"); //Check for valid object @@ -88,6 +100,8 @@ public: template void unlisten(const int token) { + validateEvent(); + auto found = _callbacks.find(type_id); if(found != _callbacks.end()) { @@ -103,8 +117,11 @@ public: template void notify(const Event& event) { - using Vector = VectorImpl; - auto found = _callbacks.find(type_id); + using CleanEventType = typename std::remove_const::type; + validateEvent(); + + using Vector = VectorImpl; + auto found = _callbacks.find(type_id); if(found == _callbacks.end()) { return; // no such notifications @@ -151,9 +168,9 @@ private: //Invalidation rules: https://stackoverflow.com/questions/6438086/iterator-invalidation-rules auto removeFrom = std::remove_if( - container.begin(), container.end(), [token](const ContainerElement& element) { - return element.first == token; - }); + container.begin(), container.end(), [token](const ContainerElement& element) { + return element.first == token; + }); if(removeFrom != container.end()) { container.erase(removeFrom, container.end());