Ver código fonte

Merge branch 'events-reworked' of public/ls-standard-library into development

Patrick-Christopher Mattulat 5 meses atrás
pai
commit
ed3abd4d11
60 arquivos alterados com 854 adições e 1885 exclusões
  1. 1 0
      .gitignore
  2. 7 17
      CMakeLists.txt
  3. 6 3
      README.md
  4. BIN
      doc/event-handling-uml.png
  5. 0 0
      doc/internal/check-list.txt
  6. 0 0
      doc/internal/section-pair-2023-standard.odt
  7. BIN
      doc/state-machine-test.png
  8. 0 31
      include/ls-std/core/exception/EventNotSubscribedException.hpp
  9. 0 32
      include/ls-std/core/interface/IEventSubscriber.hpp
  10. 0 27
      include/ls-std/core/type/EventTypes.hpp
  11. 13 23
      include/ls-std/event/Event.hpp
  12. 0 40
      include/ls-std/event/EventHandler.hpp
  13. 48 0
      include/ls-std/event/EventListener.hpp
  14. 33 26
      include/ls-std/event/EventManager.hpp
  15. 35 0
      include/ls-std/event/EventParameter.hpp
  16. 0 42
      include/ls-std/event/Narrator.hpp
  17. 0 51
      include/ls-std/event/serialization/SerializableJsonEvent.hpp
  18. 22 0
      include/ls-std/event/type/EventTypes.hpp
  19. 1 4
      include/ls-std/ls-std-core.hpp
  20. 4 4
      include/ls-std/ls-std-event.hpp
  21. 0 31
      source/ls-std/core/exception/EventNotSubscribedException.cpp
  22. 0 16
      source/ls-std/core/interface/IEventSubscriber.cpp
  23. 24 56
      source/ls-std/event/Event.cpp
  24. 0 34
      source/ls-std/event/EventHandler.cpp
  25. 93 0
      source/ls-std/event/EventListener.cpp
  26. 86 60
      source/ls-std/event/EventManager.cpp
  27. 28 0
      source/ls-std/event/EventParameter.cpp
  28. 0 76
      source/ls-std/event/Narrator.cpp
  29. 0 87
      source/ls-std/event/serialization/SerializableJsonEvent.cpp
  30. 0 72
      test/cases/core/exception/EventNotSubscribedExceptionTest.cpp
  31. 0 49
      test/cases/event/EventHandlerTest.cpp
  32. 131 0
      test/cases/event/EventListenerTest.cpp
  33. 81 246
      test/cases/event/EventManagerTest.cpp
  34. 40 0
      test/cases/event/EventParameterTest.cpp
  35. 33 83
      test/cases/event/EventTest.cpp
  36. 0 161
      test/cases/event/NarratorTest.cpp
  37. 0 96
      test/cases/event/serialization/SerializableJsonEventTest.cpp
  38. 39 0
      test/classes/event/Button.cpp
  39. 37 0
      test/classes/event/Button.hpp
  40. 18 0
      test/classes/event/ChangeColorEvent.cpp
  41. 26 0
      test/classes/event/ChangeColorEvent.hpp
  42. 0 25
      test/classes/event/Colour.cpp
  43. 0 33
      test/classes/event/Colour.hpp
  44. 0 42
      test/classes/event/DailyNewsAgency.cpp
  45. 0 43
      test/classes/event/DailyNewsAgency.hpp
  46. 0 47
      test/classes/event/GossipNewsAgency.cpp
  47. 0 43
      test/classes/event/GossipNewsAgency.hpp
  48. 0 24
      test/classes/event/GossipNewsEvent.cpp
  49. 0 27
      test/classes/event/GossipNewsEvent.hpp
  50. 0 24
      test/classes/event/NewsAgency.cpp
  51. 0 32
      test/classes/event/NewsAgency.hpp
  52. 18 0
      test/classes/event/OnClickEvent.cpp
  53. 26 0
      test/classes/event/OnClickEvent.hpp
  54. 0 24
      test/classes/event/SeriousNewsEvent.cpp
  55. 0 27
      test/classes/event/SeriousNewsEvent.hpp
  56. 0 28
      test/classes/event/TestDataCar.cpp
  57. 0 34
      test/classes/event/TestDataCar.hpp
  58. 0 27
      test/classes/event/TestDataMercedesCar.cpp
  59. 0 29
      test/classes/event/TestDataMercedesCar.hpp
  60. 4 9
      test/ls-std-event-test.hpp

+ 1 - 0
.gitignore

@@ -4,4 +4,5 @@ cmake-build-release
 cmake-build-debug-coverage
 cmake-build-wsl_debug
 cmake-build-default
+cmake-build-debug-visual-studio
 test/TestHelper.hpp

+ 7 - 17
CMakeLists.txt

@@ -168,7 +168,6 @@ set(SOURCE_FILES_CORE
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/evaluator/NullPointerArgumentEvaluator.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/evaluator/NullPointerEvaluator.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/EventNotHandledException.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/EventNotSubscribedException.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/Exception.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/ExceptionMessage.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/exception/FileNotFoundException.cpp
@@ -182,7 +181,6 @@ set(SOURCE_FILES_CORE
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IBoxing.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IEncoding.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IEvaluator.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IEventSubscriber.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IListener.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IReader.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/ISerializable.cpp
@@ -206,11 +204,10 @@ set(SOURCE_FILES_ENCODING
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/encoding/Base64.cpp)
 
 set(SOURCE_FILES_EVENT
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/serialization/SerializableJsonEvent.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/Event.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/EventHandler.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/EventListener.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/EventManager.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/Narrator.cpp)
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/event/EventParameter.cpp)
 
 set(SOURCE_FILES_IO
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/evaluator/FileExistenceEvaluator.cpp
@@ -312,7 +309,6 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/evaluator/RawNullPointerArgumentEvaluatorTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/evaluator/RawNullPointerEvaluatorTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/EventNotHandledExceptionTest.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/EventNotSubscribedExceptionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/ExceptionMessageTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/FileNotFoundExceptionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/exception/FileOperationExceptionTest.cpp
@@ -341,19 +337,13 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/encoding/Base64Test.cpp)
 
     set(UNIT_TEST_FILES_EVENT
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/serialization/SerializableJsonEventTest.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventHandlerTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventListenerTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventManagerTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventParameterTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventTest.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/NarratorTest.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/Colour.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/DailyNewsAgency.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/GossipNewsAgency.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/GossipNewsEvent.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/NewsAgency.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/SeriousNewsEvent.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/TestDataCar.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/TestDataMercedesCar.cpp)
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/ChangeColorEvent.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/OnClickEvent.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/Button.cpp)
 
     set(UNIT_TEST_FILES_IO
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/evaluator/FileExistenceEvaluatorTest.cpp

+ 6 - 3
README.md

@@ -1,4 +1,4 @@
-# Lynar Studios - Standard Library 2023.3.0 #
+# Lynar Studios - Standard Library 2024.1.0.0 #
 
 This is a cross-platform standard library written in C++ offering functionalities you would usually miss in C++'s standard library, especially if you would search for cross-platform implementations.  
 This library has been tested on __Windows__, __Linux__ and __MacOS__ systems.
@@ -34,11 +34,14 @@ A __Date__ class comes with this submodule, which you can use to represent a dat
 
 #### Features ####
 
-- none
+- a reworked version of Event handling is now available, which orients more on nowadays standards - this implementation
+  is replacing the old Event based implementation
 
 #### Improvements ####
 
 - an OS-specific initialization-script is now being provided for setting up the project and preparing it for the developer for code-contribution
+- the library version scheme is now reflecting major-, minor- and patch-level additionally to the year of release to
+  rightfully reflect on the change impact, resulting into the format YYYY.MAJOR.MINOR.PATCH
 
 #### Fixes ####
 
@@ -78,7 +81,7 @@ To build this library you'd need a supported __toolchain__ in place, consisting
 | GCC                                | Linux Mint 20.3 | 12.2.0                                     | CMake                      | \>= 3.24.0                     |
 | Clang                              | Linux Mint 20.3 | 12.0.0-3ubuntu1~20.04.5                    | CMake                      | \>= 3.24.0                     |
 | MinGW-w64 / GCC                    | Windows 10      | 11.2.0                                     | CMake                      | \>= 3.24.0                     |
-| MSVC                               | Windows 10      | 19.32.31332.0                              | CMake                      | \>= 3.24.0                     |
+| MSVC                               | Windows 10      | 19.40.33811.0                              | CMake                      | \>= 3.24.0                     |
 | AppleClang                         | MacOS Monterey  | 14.0.0                                     | CMake                      | \>= 3.24.0                     |
 
 Please note, that where the underlying operating system is optional in this listing, the toolchain itself is not! This means, that by default you should use one of the supported listed toolchains.  

BIN
doc/event-handling-uml.png


+ 0 - 0
doc/check-list.txt → doc/internal/check-list.txt


+ 0 - 0
doc/section-pair-2023-standard.odt → doc/internal/section-pair-2023-standard.odt


BIN
doc/state-machine-test.png


+ 0 - 31
include/ls-std/core/exception/EventNotSubscribedException.hpp

@@ -1,31 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2021-05-27
- * Changed:         2023-05-19
- *
- * */
-
-#ifndef LS_STD_EVENT_NOT_SUBSCRIBED_EXCEPTION_HPP
-#define LS_STD_EVENT_NOT_SUBSCRIBED_EXCEPTION_HPP
-
-#include <ls-std/core/exception/Exception.hpp>
-#include <ls-std/os/dynamic-goal.hpp>
-#include <string>
-
-namespace ls::std::core
-{
-  class LS_STD_DYNAMIC_GOAL EventNotSubscribedException : public ls::std::core::Exception
-  {
-    public:
-
-      EventNotSubscribedException();
-      explicit EventNotSubscribedException(const ::std::string &_message);
-      ~EventNotSubscribedException() noexcept override;
-
-      [[nodiscard]] const char *what() const noexcept override;
-  };
-}
-
-#endif

+ 0 - 32
include/ls-std/core/interface/IEventSubscriber.hpp

@@ -1,32 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-02-08
- *
- * */
-
-#ifndef LS_STD_I_EVENT_SUBSCRIBER_HPP
-#define LS_STD_I_EVENT_SUBSCRIBER_HPP
-
-#include "IListener.hpp"
-#include <ls-std/core/type/EventTypes.hpp>
-#include <ls-std/os/dynamic-goal.hpp>
-#include <memory>
-
-namespace ls::std::core::interface_type
-{
-  class LS_STD_DYNAMIC_GOAL IEventSubscriber
-  {
-    public:
-
-      IEventSubscriber();
-      virtual ~IEventSubscriber();
-
-      virtual void subscribe(const ls::std::core::type::event_id &_id, const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener) = 0;
-      virtual void unsubscribe(const ls::std::core::type::event_id &_id, const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener) = 0;
-  };
-}
-
-#endif

+ 0 - 27
include/ls-std/core/type/EventTypes.hpp

@@ -1,27 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-26
- * Changed:         2023-05-17
- *
- * */
-
-#ifndef LS_STD_EVENT_TYPES_HPP
-#define LS_STD_EVENT_TYPES_HPP
-
-#include <functional>
-#include <map>
-#include <string>
-#include <vector>
-
-namespace ls::std::core::type
-{
-  using event_id = ::std::string;
-  using event_parameter_id = ::std::string;
-  using event_parameter_value = ::std::string;
-  using event_parameter = ::std::pair<::std::string, ::std::string>;
-  using event_parameter_list = ::std::map<ls::std::core::type::event_parameter_id, ls::std::core::type::event_parameter_value, ::std::less<>>;
-}
-
-#endif

+ 13 - 23
include/ls-std/event/Event.hpp

@@ -1,20 +1,19 @@
 /*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-26
- * Changed:         2023-05-16
- *
- * */
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
 
 #ifndef LS_STD_EVENT_HPP
 #define LS_STD_EVENT_HPP
 
 #include <ls-std/core/Class.hpp>
-#include <ls-std/core/interface/ISerializable.hpp>
-#include <ls-std/core/type/EventTypes.hpp>
 #include <ls-std/os/dynamic-goal.hpp>
 #include <memory>
+#include <string>
 
 namespace ls::std::event
 {
@@ -22,25 +21,16 @@ namespace ls::std::event
   {
     public:
 
-      explicit Event(const ls::std::core::type::event_id &_id);
+      explicit Event(const ::std::string &_name);
       ~Event() noexcept override;
 
-      // additional functionality
-
-      bool addParameter(const ls::std::core::type::event_parameter &_eventParameter); // nodiscard is optional here
-      void clearParameterList();
-      [[nodiscard]] ls::std::core::type::event_id getId() const;
-      [[nodiscard]] ls::std::core::type::event_parameter_list getParameterList() const;
-      bool removeParameter(const ls::std::core::type::event_parameter_id &_id); // nodiscard is optional here
-      void setId(const ls::std::core::type::event_id &_id);
+      [[nodiscard]] ::std::shared_ptr<ls::std::core::Class> getManager() const;
+      void setManager(const ::std::shared_ptr<ls::std::core::Class> &_manager);
+      [[nodiscard]] ls::std::event::Event supervisedBy(const ::std::shared_ptr<ls::std::core::Class> &_manager) const;
 
     private:
 
-      ls::std::core::type::event_id id{};
-      ls::std::core::type::event_parameter_list parameterList{};
-
-      void _assignId(const ls::std::core::type::event_id &_id);
-      [[nodiscard]] bool _hasParameter(const ls::std::core::type::event_id &_id);
+      ::std::shared_ptr<ls::std::core::Class> manager{};
   };
 }
 

+ 0 - 40
include/ls-std/event/EventHandler.hpp

@@ -1,40 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-17
- *
- * */
-
-#ifndef LS_STD_EVENT_HANDLER_HPP
-#define LS_STD_EVENT_HANDLER_HPP
-
-#include "Event.hpp"
-#include "Narrator.hpp"
-#include <list>
-#include <ls-std/core/Class.hpp>
-#include <ls-std/core/interface/IListener.hpp>
-#include <ls-std/os/dynamic-goal.hpp>
-#include <memory>
-
-namespace ls::std::event
-{
-  class LS_STD_DYNAMIC_GOAL EventHandler : public ls::std::event::Narrator
-  {
-    public:
-
-      explicit EventHandler(const ls::std::core::type::event_id &_id);
-      ~EventHandler() noexcept override;
-
-      [[nodiscard]] ls::std::core::type::event_id getId() const;
-
-    private:
-
-      ls::std::core::type::event_id id{};
-
-      void _assignId(const ls::std::core::type::event_id &_id);
-  };
-}
-
-#endif

+ 48 - 0
include/ls-std/event/EventListener.hpp

@@ -0,0 +1,48 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
+#ifndef LS_STD_EVENT_LISTENER_HPP
+#define LS_STD_EVENT_LISTENER_HPP
+
+#include "Event.hpp"
+#include "EventParameter.hpp"
+#include <ls-std/core/Class.hpp>
+#include <ls-std/event/type/EventTypes.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::event
+{
+  class LS_STD_DYNAMIC_GOAL EventListener : public ::std::enable_shared_from_this<EventListener>, public ls::std::core::Class
+  {
+    public:
+
+      explicit EventListener();
+      ~EventListener() noexcept override;
+
+      [[nodiscard]] ls::std::event::type::listener_id getId() const;
+      void setId(ls::std::event::type::listener_id _id);
+      void setParameter(const ls::std::event::EventParameter &_parameter);
+      [[maybe_unused]] bool subscribe(const ls::std::event::Event &_event, const ls::std::event::type::event_action &_action);
+      [[maybe_unused]] bool unsubscribe(const ls::std::event::Event &_event);
+
+    protected:
+
+    ls::std::event::EventParameter parameter{};
+
+    private:
+
+      ls::std::event::type::listener_id id{};
+
+      void _requestListenerId(const ::std::shared_ptr<ls::std::core::Class> &_manager);
+      [[nodiscard]] bool _subscribe(const ls::std::event::Event &_event, const ls::std::event::type::event_action &_action);
+      [[nodiscard]] bool _unsubscribe(const ls::std::event::Event &_event);
+  };
+}
+
+#endif

+ 33 - 26
include/ls-std/event/EventManager.hpp

@@ -1,50 +1,57 @@
 /*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-17
- *
- * */
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
 
 #ifndef LS_STD_EVENT_MANAGER_HPP
 #define LS_STD_EVENT_MANAGER_HPP
 
-#include "EventHandler.hpp"
+#include "Event.hpp"
+#include "EventListener.hpp"
+#include "EventParameter.hpp"
+
+#include <list>
 #include <ls-std/core/Class.hpp>
-#include <ls-std/core/interface/IEventSubscriber.hpp>
-#include <ls-std/core/type/EventTypes.hpp>
+#include <ls-std/event/type/EventTypes.hpp>
 #include <ls-std/os/dynamic-goal.hpp>
-#include <map>
 #include <memory>
+#include <unordered_map>
+
+namespace ls::std::event::type
+{
+  using event_listeners = ::std::list<::std::pair<::std::shared_ptr<ls::std::event::EventListener>, ls::std::event::type::event_action>>;
+  using event_observability_inventory = ::std::unordered_map<::std::string, ls::std::event::type::event_listeners>;
+}
 
 namespace ls::std::event
 {
-  class LS_STD_DYNAMIC_GOAL EventManager : public ls::std::core::Class, public ls::std::core::interface_type::IEventSubscriber
+  class LS_STD_DYNAMIC_GOAL EventManager : public ls::std::core::Class
   {
     public:
 
       explicit EventManager();
       ~EventManager() noexcept override;
 
-      // implementation
-
-      void subscribe(const ls::std::core::type::event_id &_id, const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener) override;
-      void unsubscribe(const ls::std::core::type::event_id &_id, const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener) override;
-
-      // additional functionality
-
-      bool addEventHandler(const ::std::shared_ptr<ls::std::event::EventHandler> &_eventHandler); // nodiscard is optional here
-      void fire(const ls::std::event::Event &_event);
-      [[nodiscard]] bool hasEventHandler(const ls::std::core::type::event_id &_id);
-      bool removeEventHandler(const ::std::shared_ptr<ls::std::event::EventHandler> &_eventHandler); // nodiscard is optional here
+      [[nodiscard]] ls::std::event::type::listener_id getNextProvisionId() const;
+      [[nodiscard]] bool holdsListenerForEvent(ls::std::event::type::listener_id _id, const ls::std::event::Event &_event);
+      void invoke(const ls::std::event::Event &_event);
+      void invoke(const ls::std::event::Event &_event, const ls::std::event::EventParameter &_parameter);
+      [[nodiscard]] ls::std::event::type::listener_id requestListenerId();
+      void subscribeListenerForEvent(::std::shared_ptr<ls::std::event::EventListener> _listener, const ls::std::event::Event &_event, ls::std::event::type::event_action _action);
+      void unsubscribeListenerForEvent(const ::std::shared_ptr<ls::std::event::EventListener> &_listener, const ls::std::event::Event &_event);
 
     private:
 
-      ::std::map<ls::std::core::type::event_id, ::std::shared_ptr<ls::std::event::EventHandler>, ::std::less<>> eventHandlers{};
+      ls::std::event::type::event_observability_inventory inventory{};
+      ls::std::event::type::listener_id provisionId = 1;
 
-      [[nodiscard]] bool _hasEventHandler(const ls::std::core::type::event_id &_id);
-      [[nodiscard]] bool _removeEventHandler(const ::std::shared_ptr<ls::std::event::EventHandler> &_eventHandler);
+      static void _giveListenersParameter(const ls::std::event::type::event_listeners &_listeners, const ls::std::event::EventParameter &_parameter);
+      static void _notifyListeners(const ls::std::event::type::event_listeners &_listeners);
+      bool _observesEvent(const ls::std::event::Event &_event) const;
   };
 }
 

+ 35 - 0
include/ls-std/event/EventParameter.hpp

@@ -0,0 +1,35 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-30
+* Changed:         2024-05-30
+*
+* */
+
+#ifndef EVENT_PARAMETER_HPP
+#define EVENT_PARAMETER_HPP
+
+#include <list>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <string>
+
+namespace ls::std::event
+{
+  class LS_STD_DYNAMIC_GOAL EventParameter
+  {
+    public:
+
+      EventParameter();
+      ~EventParameter();
+
+      void addParameter(const ::std::string &_parameter);
+      [[nodiscard]] ::std::list<::std::string> get() const;
+
+    private:
+
+      ::std::list<::std::string> parameters{};
+  };
+}
+
+#endif

+ 0 - 42
include/ls-std/event/Narrator.hpp

@@ -1,42 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-05-16
- *
- * */
-
-#ifndef LS_STD_NARRATOR_HPP
-#define LS_STD_NARRATOR_HPP
-
-#include <list>
-#include <ls-std/core/Class.hpp>
-#include <ls-std/core/interface/IListener.hpp>
-#include <ls-std/os/dynamic-goal.hpp>
-#include <memory>
-
-namespace ls::std::event
-{
-  class LS_STD_DYNAMIC_GOAL Narrator : public ls::std::core::Class
-  {
-    public:
-
-      Narrator();
-      ~Narrator() noexcept override;
-
-      bool addListener(const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener); // nodiscard is optional here
-      void clear();
-      [[nodiscard]] ::std::list<::std::shared_ptr<ls::std::core::interface_type::IListener>> getListeners() const;
-      bool removeListener(const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener); // nodiscard is optional here
-      void tell(const ls::std::core::Class &_info) const;
-
-    private:
-
-      ::std::list<::std::shared_ptr<ls::std::core::interface_type::IListener>> listeners{};
-
-      [[nodiscard]] bool _hasListener(const ::std::shared_ptr<ls::std::core::interface_type::IListener> &_listener);
-  };
-}
-
-#endif

+ 0 - 51
include/ls-std/event/serialization/SerializableJsonEvent.hpp

@@ -1,51 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-12-07
- * Changed:         2023-05-19
- *
- * */
-
-#ifndef LS_STD_SERIALIZABLE_JSON_EVENT_HPP
-#define LS_STD_SERIALIZABLE_JSON_EVENT_HPP
-
-#include <ls-std/core/Class.hpp>
-#include <ls-std/core/interface/ISerializable.hpp>
-#include <ls-std/core/type/Types.hpp>
-#include <ls-std/event/Event.hpp>
-#include <ls-std/os/dynamic-goal.hpp>
-#include <memory>
-
-namespace ls::std::event
-{
-  class LS_STD_DYNAMIC_GOAL SerializableJsonEvent : public ls::std::core::Class, public ls::std::core::interface_type::ISerializable
-  {
-    public:
-
-      explicit SerializableJsonEvent(const ::std::shared_ptr<ls::std::event::Event> &_value);
-      ~SerializableJsonEvent() noexcept override;
-
-      // implementation
-
-      [[nodiscard]] ls::std::core::type::byte_field marshal() override;
-      void unmarshal(const ls::std::core::type::byte_field &_data) override;
-
-      // additional functionality
-
-      [[nodiscard]] ::std::shared_ptr<ls::std::event::Event> getValue() const;
-      void setValue(const ::std::shared_ptr<ls::std::event::Event> &_value);
-
-    private:
-
-      ls::std::core::type::json jsonObject{};
-      ::std::shared_ptr<ls::std::event::Event> value{};
-
-      void _assignValue(const ::std::shared_ptr<ls::std::event::Event> &_value);
-      void _unmarshalParameterList();
-      void _update();
-      void _updateEventParameterList();
-  };
-}
-
-#endif

+ 22 - 0
include/ls-std/event/type/EventTypes.hpp

@@ -0,0 +1,22 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-17
+*
+* */
+
+#ifndef LS_STD_EVENT_TYPES_HPP
+#define LS_STD_EVENT_TYPES_HPP
+
+#include <cstdint>
+#include <functional>
+
+namespace ls::std::event::type
+{
+  using event_action = ::std::function<void()>;
+  using listener_id = uint32_t;
+}
+
+#endif

+ 1 - 4
include/ls-std/ls-std-core.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-13
- * Changed:         2023-05-24
+ * Changed:         2024-05-17
  *
  * */
 
@@ -18,7 +18,6 @@
 #include <ls-std/core/evaluator/RawNullPointerEvaluator.hpp>
 
 #include <ls-std/core/exception/EventNotHandledException.hpp>
-#include <ls-std/core/exception/EventNotSubscribedException.hpp>
 #include <ls-std/core/exception/Exception.hpp>
 #include <ls-std/core/exception/ExceptionMessage.hpp>
 #include <ls-std/core/exception/FileNotFoundException.hpp>
@@ -32,7 +31,6 @@
 
 #include <ls-std/core/interface/IBoxing.hpp>
 #include <ls-std/core/interface/IEncoding.hpp>
-#include <ls-std/core/interface/IEventSubscriber.hpp>
 #include <ls-std/core/interface/IListener.hpp>
 #include <ls-std/core/interface/IReader.hpp>
 #include <ls-std/core/interface/ISerializable.hpp>
@@ -40,7 +38,6 @@
 #include <ls-std/core/interface/IValidator.hpp>
 #include <ls-std/core/interface/IWriter.hpp>
 
-#include <ls-std/core/type/EventTypes.hpp>
 #include <ls-std/core/type/RawPointer.hpp>
 #include <ls-std/core/type/Types.hpp>
 

+ 4 - 4
include/ls-std/ls-std-event.hpp

@@ -3,18 +3,18 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-14
- * Changed:         2023-02-03
+ * Changed:         2024-05-30
  *
  * */
 
 #ifndef LS_STD_LS_STD_EVENT_HPP
 #define LS_STD_LS_STD_EVENT_HPP
 
-#include <ls-std/event/serialization/SerializableJsonEvent.hpp>
+#include <ls-std/event/type/EventTypes.hpp>
 
 #include <ls-std/event/Event.hpp>
-#include <ls-std/event/EventHandler.hpp>
+#include <ls-std/event/EventListener.hpp>
 #include <ls-std/event/EventManager.hpp>
-#include <ls-std/event/Narrator.hpp>
+#include <ls-std/event/EventParameter.hpp>
 
 #endif

+ 0 - 31
source/ls-std/core/exception/EventNotSubscribedException.cpp

@@ -1,31 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2023-02-04
- * Changed:         2023-05-19
- *
- * */
-
-#include <ls-std/core/exception/EventNotSubscribedException.hpp>
-#include <ls-std/core/exception/ExceptionMessage.hpp>
-
-using ls::std::core::EventNotSubscribedException;
-using ls::std::core::Exception;
-using std::move;
-using std::string;
-
-EventNotSubscribedException::EventNotSubscribedException() : Exception("EventNotSubscribedException")
-{}
-
-EventNotSubscribedException::EventNotSubscribedException(const string &_message) : EventNotSubscribedException()
-{
-  this->_setMessage(_message);
-}
-
-EventNotSubscribedException::~EventNotSubscribedException() noexcept = default;
-
-const char *EventNotSubscribedException::what() const noexcept
-{
-  return this->_getIdentifiedMessage("event was not subscribed!");
-}

+ 0 - 16
source/ls-std/core/interface/IEventSubscriber.cpp

@@ -1,16 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2023-02-04
- * Changed:         2023-02-23
- *
- * */
-
-#include <ls-std/core/interface/IEventSubscriber.hpp>
-
-using ls::std::core::interface_type::IEventSubscriber;
-
-IEventSubscriber::IEventSubscriber() = default;
-
-IEventSubscriber::~IEventSubscriber() = default;

+ 24 - 56
source/ls-std/event/Event.cpp

@@ -1,74 +1,42 @@
 /*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-26
- * Changed:         2023-05-16
- *
- * */
-
-#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
 #include <ls-std/event/Event.hpp>
 
 using ls::std::core::Class;
-using ls::std::core::EmptyStringArgumentEvaluator;
-using ls::std::core::type::event_id;
-using ls::std::core::type::event_parameter;
-using ls::std::core::type::event_parameter_id;
-using ls::std::core::type::event_parameter_list;
+using ls::std::core::NullPointerArgumentEvaluator;
 using ls::std::event::Event;
+using ::std::shared_ptr;
+using ::std::string;
 
-Event::Event(const event_id &_id) : Class("Event")
-{
-  this->_assignId(_id);
-}
+Event::Event(const string &_name) : Class(_name)
+{}
 
 Event::~Event() noexcept = default;
 
-bool Event::addParameter(const event_parameter &_eventParameter)
-{
-  bool wasAdded{};
-
-  if (!this->_hasParameter(_eventParameter.first))
-  {
-    wasAdded = this->parameterList.insert(_eventParameter).second;
-  }
-
-  return wasAdded;
-}
-
-void Event::clearParameterList()
+shared_ptr<Class> Event::getManager() const
 {
-  this->parameterList.clear();
+  return this->manager;
 }
 
-event_id Event::getId() const
+void Event::setManager(const shared_ptr<Class> &_manager)
 {
-  return this->id;
+  NullPointerArgumentEvaluator(_manager).evaluate();
+  this->manager = _manager;
 }
 
-event_parameter_list Event::getParameterList() const
+Event Event::supervisedBy(const shared_ptr<Class> &_manager) const
 {
-  return this->parameterList;
-}
+  NullPointerArgumentEvaluator(_manager).evaluate();
+  auto event = Event(this->getClassName());
+  event.setManager(_manager);
 
-bool Event::removeParameter(const event_parameter_id &_id)
-{
-  return this->parameterList.erase(_id) == 1;
-}
-
-void Event::setId(const event_id &_id)
-{
-  this->_assignId(_id);
-}
-
-void Event::_assignId(const event_id &_id)
-{
-  EmptyStringArgumentEvaluator{_id, "event id is empty!"}.evaluate();
-  this->id = _id;
-}
-
-bool Event::_hasParameter(const event_id &_id)
-{
-  return this->parameterList.find(_id) != this->parameterList.end();
+  return event;
 }

+ 0 - 34
source/ls-std/event/EventHandler.cpp

@@ -1,34 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-17
- *
- * */
-
-#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
-#include <ls-std/event/EventHandler.hpp>
-
-using ls::std::core::EmptyStringArgumentEvaluator;
-using ls::std::core::type::event_id;
-using ls::std::event::EventHandler;
-using ls::std::event::Narrator;
-
-EventHandler::EventHandler(const event_id &_id) : Narrator()
-{
-  this->_assignId(_id);
-}
-
-EventHandler::~EventHandler() noexcept = default;
-
-event_id EventHandler::getId() const
-{
-  return this->id;
-}
-
-void EventHandler::_assignId(const event_id &_id)
-{
-  EmptyStringArgumentEvaluator{_id, "event manager id is empty!"}.evaluate();
-  this->id = _id;
-}

+ 93 - 0
source/ls-std/event/EventListener.cpp

@@ -0,0 +1,93 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
+#include <ls-std/core/evaluator/NullPointerEvaluator.hpp>
+#include <ls-std/event/EventListener.hpp>
+#include <ls-std/event/EventManager.hpp>
+
+using ls::std::core::Class;
+using ls::std::core::NullPointerEvaluator;
+using ls::std::event::Event;
+using ls::std::event::EventListener;
+using ls::std::event::EventManager;
+using ls::std::event::EventParameter;
+using ls::std::event::type::event_action;
+using ls::std::event::type::listener_id;
+using ::std::dynamic_pointer_cast;
+using ::std::shared_ptr;
+
+EventListener::EventListener() : Class("EventListener")
+{}
+
+EventListener::~EventListener() noexcept = default;
+
+listener_id EventListener::getId() const
+{
+  return this->id;
+}
+
+void EventListener::setId(listener_id _id)
+{
+  this->id = _id;
+}
+
+void EventListener::setParameter(const EventParameter &_parameter)
+{
+  this->parameter = _parameter;
+}
+
+bool EventListener::subscribe(const Event &_event, const event_action &_action)
+{
+  NullPointerEvaluator(_event.getManager(), "no event manager is provided for " + _event.getClassName()).evaluate();
+  this->_requestListenerId(_event.getManager());
+
+  return this->_subscribe(_event, _action);
+}
+
+bool EventListener::unsubscribe(const Event &_event)
+{
+  NullPointerEvaluator(_event.getManager(), "no event manager is provided for " + _event.getClassName()).evaluate();
+  return this->_unsubscribe(_event);
+}
+
+void EventListener::_requestListenerId(const shared_ptr<Class> &_manager)
+{
+  shared_ptr<EventManager> manager = dynamic_pointer_cast<EventManager>(_manager);
+
+  if (this->id == 0)
+  {
+    this->setId(manager->requestListenerId());
+  }
+}
+
+bool EventListener::_subscribe(const Event &_event, const event_action &_action)
+{
+  bool subscribed{};
+
+  if (shared_ptr<EventManager> manager = dynamic_pointer_cast<EventManager>(_event.getManager()); !manager->holdsListenerForEvent(this->id, _event))
+  {
+    manager->subscribeListenerForEvent(shared_from_this(), _event, _action);
+    subscribed = manager->holdsListenerForEvent(this->id, _event);
+  }
+
+  return subscribed;
+}
+
+bool EventListener::_unsubscribe(const Event &_event)
+{
+  bool unsubscribed{};
+
+  if (shared_ptr<EventManager> manager = dynamic_pointer_cast<EventManager>(_event.getManager()); manager->holdsListenerForEvent(this->id, _event))
+  {
+    manager->unsubscribeListenerForEvent(shared_from_this(), _event);
+    unsubscribed = !manager->holdsListenerForEvent(this->id, _event);
+  }
+
+  return unsubscribed;
+}

+ 86 - 60
source/ls-std/event/EventManager.cpp

@@ -1,107 +1,133 @@
 /*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-17
- *
- * */
-
-#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
-#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
 #include <ls-std/core/exception/EventNotHandledException.hpp>
-#include <ls-std/core/exception/EventNotSubscribedException.hpp>
+#include <ls-std/event/EventListener.hpp>
 #include <ls-std/event/EventManager.hpp>
 
 using ls::std::core::Class;
-using ls::std::core::EmptyStringArgumentEvaluator;
 using ls::std::core::EventNotHandledException;
-using ls::std::core::EventNotSubscribedException;
-using ls::std::core::NullPointerArgumentEvaluator;
-using ls::std::core::interface_type::IListener;
-using ls::std::core::type::event_id;
 using ls::std::event::Event;
-using ls::std::event::EventHandler;
+using ls::std::event::EventListener;
 using ls::std::event::EventManager;
-using std::make_pair;
-using std::pair;
-using std::shared_ptr;
+using ls::std::event::EventParameter;
+using ls::std::event::type::event_action;
+using ls::std::event::type::event_listeners;
+using ls::std::event::type::listener_id;
+using ::std::make_pair;
+using ::std::move;
+using ::std::shared_ptr;
 
 EventManager::EventManager() : Class("EventManager")
 {}
 
 EventManager::~EventManager() noexcept = default;
 
-void EventManager::subscribe(const event_id &_id, const shared_ptr<IListener> &_listener)
+listener_id EventManager::getNextProvisionId() const
 {
-  EmptyStringArgumentEvaluator{_id, "event id is empty and can not be subscribed!"}.evaluate();
-  NullPointerArgumentEvaluator{_listener, "listener reference for subscribe attempt is null!"}.evaluate();
-
-  if (this->_hasEventHandler(_id))
-  {
-    this->eventHandlers.at(_id)->addListener(_listener);
-  }
-  else
-  {
-    throw EventNotSubscribedException{"id: " + _id};
-  }
+  return this->provisionId;
 }
 
-void EventManager::unsubscribe(const event_id &_id, const shared_ptr<IListener> &_listener)
+bool EventManager::holdsListenerForEvent(listener_id _id, const Event &_event)
 {
-  EmptyStringArgumentEvaluator{_id, "event id is empty and can not be unsubscribed!"}.evaluate();
-  NullPointerArgumentEvaluator{_listener, "listener reference for unsubscribe attempt is null!"}.evaluate();
+  bool holdsListener{};
 
-  if (this->_hasEventHandler(_id))
+  if (this->_observesEvent(_event))
   {
-    this->eventHandlers.at(_id)->removeListener(_listener);
+    for (const auto &[listener, eventAction] : this->inventory[_event.getClassName()])
+    {
+      holdsListener = listener->getId() == _id;
+
+      if (holdsListener)
+      {
+        break;
+      }
+    }
   }
+
+  return holdsListener;
 }
 
-bool EventManager::addEventHandler(const shared_ptr<EventHandler> &_eventHandler)
+void EventManager::invoke(const Event &_event)
 {
-  bool wasAdded{};
-  NullPointerArgumentEvaluator{_eventHandler, "event handler reference for add attempt is null!"}.evaluate();
-
-  if (!this->_hasEventHandler(_eventHandler->getId()))
+  if (!this->_observesEvent(_event))
   {
-    pair<event_id, shared_ptr<EventHandler>> element = make_pair(_eventHandler->getId(), _eventHandler);
-    wasAdded = this->eventHandlers.insert(element).second;
+    throw EventNotHandledException("event " + _event.getClassName() + " is not known by event manager");
   }
 
-  return wasAdded;
+  const auto &listeners = this->inventory[_event.getClassName()];
+  EventManager::_notifyListeners(listeners);
 }
 
-void EventManager::fire(const Event &_event)
+void EventManager::invoke(const Event &_event, const EventParameter &_parameter)
 {
-  if (this->_hasEventHandler(_event.getId()))
+  if (!this->_observesEvent(_event))
   {
-    this->eventHandlers.at(_event.getId())->tell(_event);
+    throw EventNotHandledException("event " + _event.getClassName() + " is not known by event manager");
   }
-  else
+
+  const auto &listeners = this->inventory[_event.getClassName()];
+  EventManager::_giveListenersParameter(listeners, _parameter);
+  EventManager::_notifyListeners(listeners);
+}
+
+listener_id EventManager::requestListenerId()
+{
+  listener_id providedId = this->provisionId;
+  ++this->provisionId;
+
+  return providedId;
+}
+
+void EventManager::subscribeListenerForEvent(shared_ptr<EventListener> _listener, const Event &_event, event_action _action)
+{
+  if (!this->_observesEvent(_event))
   {
-    throw EventNotHandledException{"id: " + _event.getId()};
+    this->inventory[_event.getClassName()] = {};
   }
+
+  auto inventoryEntry = make_pair<shared_ptr<EventListener>, event_action>(::move(_listener), ::move(_action));
+  this->inventory[_event.getClassName()].push_back(inventoryEntry);
 }
 
-bool EventManager::hasEventHandler(const event_id &_id)
+void EventManager::unsubscribeListenerForEvent(const shared_ptr<EventListener> &_listener, const Event &_event)
 {
-  EmptyStringArgumentEvaluator{_id, "event id is empty and can not be passed!"}.evaluate();
-  return this->_hasEventHandler(_id);
+  if (this->_observesEvent(_event))
+  {
+    for (auto iterator = this->inventory[_event.getClassName()].begin(); iterator != this->inventory[_event.getClassName()].end(); iterator++)
+    {
+      if (iterator->first->getId() == _listener->getId())
+      {
+        this->inventory[_event.getClassName()].erase(iterator);
+        break;
+      }
+    }
+  }
 }
 
-bool EventManager::removeEventHandler(const shared_ptr<EventHandler> &_eventHandler)
+void EventManager::_giveListenersParameter(const event_listeners &_listeners, const EventParameter &_parameter)
 {
-  NullPointerArgumentEvaluator{_eventHandler, "event handler reference for remove attempt is null!"}.evaluate();
-  return this->_removeEventHandler(_eventHandler);
+  for (const auto &[listener, action] : _listeners)
+  {
+    listener->setParameter(_parameter);
+  }
 }
 
-bool EventManager::_hasEventHandler(const event_id &_id)
+void EventManager::_notifyListeners(const event_listeners &_listeners)
 {
-  return this->eventHandlers.find(_id) != this->eventHandlers.end();
+  for (const auto &[listener, eventAction] : _listeners)
+  {
+    eventAction();
+  }
 }
 
-bool EventManager::_removeEventHandler(const shared_ptr<EventHandler> &_eventHandler)
+bool EventManager::_observesEvent(const Event &_event) const
 {
-  return this->eventHandlers.erase(_eventHandler->getId()) == 1;
+  return this->inventory.find(_event.getClassName()) != this->inventory.end();
 }

+ 28 - 0
source/ls-std/event/EventParameter.cpp

@@ -0,0 +1,28 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-30
+* Changed:         2024-05-30
+*
+* */
+
+#include <ls-std/event/EventParameter.hpp>
+
+using ls::std::event::EventParameter;
+using ::std::list;
+using ::std::string;
+
+EventParameter::EventParameter() = default;
+
+EventParameter::~EventParameter() = default;
+
+void EventParameter::addParameter(const string &_parameter)
+{
+  this->parameters.push_back(_parameter);
+}
+
+list<string> EventParameter::get() const
+{
+  return this->parameters;
+}

+ 0 - 76
source/ls-std/event/Narrator.cpp

@@ -1,76 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-05-16
- *
- * */
-
-#include <algorithm>
-#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
-#include <ls-std/event/Narrator.hpp>
-
-using ls::std::core::Class;
-using ls::std::core::NullPointerArgumentEvaluator;
-using ls::std::core::interface_type::IListener;
-using ls::std::event::Narrator;
-using std::find;
-using std::list;
-using std::shared_ptr;
-
-Narrator::Narrator() : Class("Narrator")
-{}
-
-Narrator::~Narrator() noexcept = default;
-
-bool Narrator::addListener(const shared_ptr<IListener> &_listener)
-{
-  bool wasAdded{};
-  NullPointerArgumentEvaluator{_listener, "listener reference for add attempt is null!"}.evaluate();
-
-  if (!this->_hasListener(_listener))
-  {
-    this->listeners.push_back(_listener);
-    wasAdded = true;
-  }
-
-  return wasAdded;
-}
-
-void Narrator::clear()
-{
-  this->listeners.clear();
-}
-
-list<shared_ptr<IListener>> Narrator::getListeners() const
-{
-  return this->listeners;
-}
-
-bool Narrator::removeListener(const shared_ptr<IListener> &_listener)
-{
-  bool wasRemoved{};
-  NullPointerArgumentEvaluator{_listener, "listener reference for remove attempt is null!"}.evaluate();
-
-  if (this->_hasListener(_listener))
-  {
-    this->listeners.remove(_listener);
-    wasRemoved = true;
-  }
-
-  return wasRemoved;
-}
-
-void Narrator::tell(const Class &_info) const
-{
-  for (const auto &listener : this->listeners)
-  {
-    listener->listen(_info);
-  }
-}
-
-bool Narrator::_hasListener(const shared_ptr<IListener> &_listener)
-{
-  return find(this->listeners.begin(), this->listeners.end(), _listener) != this->listeners.end();
-}

+ 0 - 87
source/ls-std/event/serialization/SerializableJsonEvent.cpp

@@ -1,87 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-12-07
- * Changed:         2023-05-19
- *
- * */
-
-#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
-#include <ls-std/event/serialization/SerializableJsonEvent.hpp>
-
-using ls::std::core::Class;
-using ls::std::core::NullPointerArgumentEvaluator;
-using ls::std::core::type::byte_field;
-using ls::std::core::type::event_parameter;
-using ls::std::core::type::json;
-using ls::std::event::Event;
-using ls::std::event::SerializableJsonEvent;
-using std::shared_ptr;
-using std::string;
-
-SerializableJsonEvent::SerializableJsonEvent(const shared_ptr<Event> &_value) : Class("SerializableJsonEvent")
-{
-  this->_assignValue(_value);
-}
-
-SerializableJsonEvent::~SerializableJsonEvent() noexcept = default;
-
-byte_field SerializableJsonEvent::marshal()
-{
-  this->_update();
-  return this->jsonObject.dump();
-}
-
-void SerializableJsonEvent::unmarshal(const byte_field &_data)
-{
-  this->jsonObject = json::parse(_data);
-
-  this->value->setId(this->jsonObject["id"]);
-  this->_unmarshalParameterList();
-}
-
-shared_ptr<Event> SerializableJsonEvent::getValue() const
-{
-  return this->value;
-}
-
-void SerializableJsonEvent::setValue(const shared_ptr<Event> &_value)
-{
-  this->_assignValue(_value);
-}
-
-void SerializableJsonEvent::_assignValue(const shared_ptr<Event> &_value)
-{
-  NullPointerArgumentEvaluator{_value, "event reference for serialization attempt is null!"}.evaluate();
-  this->value = _value;
-}
-
-void SerializableJsonEvent::_unmarshalParameterList()
-{
-  this->value->clearParameterList();
-
-  for (const auto &parameterJson : this->jsonObject["parameterList"])
-  {
-    event_parameter parameter = {parameterJson.at(0), parameterJson.at(1)};
-    this->value->addParameter(parameter);
-  }
-}
-
-void SerializableJsonEvent::_update()
-{
-  this->jsonObject = {{"id", this->value->getId()}};
-
-  this->_updateEventParameterList();
-}
-
-void SerializableJsonEvent::_updateEventParameterList()
-{
-  string jsonString{};
-
-  for (const auto &[eventParameterId, eventParameter] : this->value->getParameterList())
-  {
-    json parameterJson = {eventParameterId, eventParameter};
-    this->jsonObject["parameterList"][eventParameterId] = parameterJson;
-  }
-}

+ 0 - 72
test/cases/core/exception/EventNotSubscribedExceptionTest.cpp

@@ -1,72 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2021-05-27
- * Changed:         2023-03-25
- *
- * */
-
-#include <gtest/gtest.h>
-#include <ls-std/ls-std-core.hpp>
-#include <string>
-
-using ls::std::core::EventNotSubscribedException;
-using std::string;
-using testing::Test;
-
-namespace
-{
-  class EventNotSubscribedExceptionTest : public Test
-  {
-    public:
-
-      EventNotSubscribedExceptionTest() = default;
-      ~EventNotSubscribedExceptionTest() override = default;
-  };
-
-  TEST_F(EventNotSubscribedExceptionTest, constructor)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            throw EventNotSubscribedException{};
-          }
-          catch (const EventNotSubscribedException &_exception)
-          {
-            string actual = _exception.what();
-            string expected = _exception.getName() + " thrown - event was not subscribed!";
-
-            EXPECT_STREQ(expected.c_str(), actual.c_str());
-            throw;
-          }
-        },
-        EventNotSubscribedException);
-  }
-
-  TEST_F(EventNotSubscribedExceptionTest, constructor_dedicated_message)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            throw EventNotSubscribedException{"id: OPEN_DOOR"};
-          }
-          catch (const EventNotSubscribedException &_exception)
-          {
-            string actual = _exception.what();
-            string expected = _exception.getName() + " thrown - id: OPEN_DOOR";
-
-            EXPECT_STREQ(expected.c_str(), actual.c_str());
-            throw;
-          }
-        },
-        EventNotSubscribedException);
-  }
-
-  TEST_F(EventNotSubscribedExceptionTest, getName)
-  {
-    ASSERT_STREQ("EventNotSubscribedException", EventNotSubscribedException{}.getName().c_str());
-  }
-}

+ 0 - 49
test/cases/event/EventHandlerTest.cpp

@@ -1,49 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-03-25
- *
- * */
-
-#include <gtest/gtest.h>
-#include <ls-std/ls-std-core.hpp>
-#include <ls-std/ls-std-event.hpp>
-
-using ls::std::core::IllegalArgumentException;
-using ls::std::event::EventHandler;
-using testing::Test;
-
-namespace
-{
-  class EventHandlerTest : public Test
-  {
-    public:
-
-      EventHandlerTest() = default;
-      ~EventHandlerTest() override = default;
-  };
-
-  TEST_F(EventHandlerTest, constructor_empty_parameter)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventHandler eventHandler{""};
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
-
-  TEST_F(EventHandlerTest, getId)
-  {
-    EventHandler eventHandler{"EventId"};
-    ASSERT_STREQ("EventId", eventHandler.getId().c_str());
-  }
-}

+ 131 - 0
test/cases/event/EventListenerTest.cpp

@@ -0,0 +1,131 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std-event-test.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <ls-std/ls-std-event.hpp>
+#include <memory>
+
+using ls::std::core::NullPointerException;
+using ls::std::event::EventListener;
+using ls::std::event::EventManager;
+using ::std::make_shared;
+using ::std::string;
+using test::event::Button;
+using test::event::OnClickEvent;
+using testing::Test;
+
+namespace
+{
+  class EventListenerTest : public Test
+  {
+    public:
+
+      EventListenerTest() = default;
+      ~EventListenerTest() override = default;
+  };
+
+  TEST_F(EventListenerTest, getClassName)
+  {
+    ASSERT_STREQ("EventListener", EventListener().getClassName().c_str());
+  }
+
+  TEST_F(EventListenerTest, getId)
+  {
+    ASSERT_EQ(0, EventListener().getId());
+  }
+
+  TEST_F(EventListenerTest, setId)
+  {
+    auto listener = EventListener();
+
+    ASSERT_EQ(0, listener.getId());
+    listener.setId(17);
+    ASSERT_EQ(17, listener.getId());
+  }
+
+  TEST_F(EventListenerTest, subscribe_with_missing_event_manager)
+  {
+    auto myButton = make_shared<Button>();
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            myButton->subscribe(OnClickEvent(), [myButton]() mutable { myButton->onClickEvent(); });
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - no event manager is provided for OnClickEvent";
+
+            EXPECT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
+
+  TEST_F(EventListenerTest, subscribe)
+  {
+    auto myButton = make_shared<Button>();
+    ASSERT_TRUE(myButton->subscribe(OnClickEvent().supervisedBy(make_shared<EventManager>()), [myButton]() mutable { myButton->onClickEvent(); }));
+  }
+
+  TEST_F(EventListenerTest, subscribe_second_time)
+  {
+    auto myButton = make_shared<Button>();
+    auto eventManager = make_shared<EventManager>();
+
+    ASSERT_TRUE(myButton->subscribe(OnClickEvent().supervisedBy(eventManager), [myButton]() mutable { myButton->onClickEvent(); }));
+    ASSERT_FALSE(myButton->subscribe(OnClickEvent().supervisedBy(eventManager), [myButton]() mutable { myButton->onClickEvent(); }));
+  }
+
+  TEST_F(EventListenerTest, unsubscribe_with_missing_event_manager)
+  {
+    auto myButton = make_shared<Button>();
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            myButton->unsubscribe(OnClickEvent());
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - no event manager is provided for OnClickEvent";
+
+            EXPECT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
+
+  TEST_F(EventListenerTest, unsubscribe)
+  {
+    auto myButton = make_shared<Button>();
+    auto eventManager = make_shared<EventManager>();
+
+    ASSERT_TRUE(myButton->subscribe(OnClickEvent().supervisedBy(eventManager), [myButton]() mutable { myButton->onClickEvent(); }));
+    ASSERT_TRUE(myButton->unsubscribe(OnClickEvent().supervisedBy(eventManager)));
+  }
+
+  TEST_F(EventListenerTest, unsubscribe_second_time)
+  {
+    auto myButton = make_shared<Button>();
+    auto eventManager = make_shared<EventManager>();
+
+    ASSERT_TRUE(myButton->subscribe(OnClickEvent().supervisedBy(eventManager), [myButton]() mutable { myButton->onClickEvent(); }));
+    ASSERT_TRUE(myButton->unsubscribe(OnClickEvent().supervisedBy(eventManager)));
+    ASSERT_FALSE(myButton->unsubscribe(OnClickEvent().supervisedBy(eventManager)));
+  }
+}

+ 81 - 246
test/cases/event/EventManagerTest.cpp

@@ -1,30 +1,26 @@
 /*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-16
- *
- * */
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
 
 #include <gtest/gtest.h>
 #include <ls-std-event-test.hpp>
+#include <ls-std/ls-std-core.hpp>
 #include <ls-std/ls-std-event.hpp>
+#include <string>
 
 using ls::std::core::EventNotHandledException;
-using ls::std::core::EventNotSubscribedException;
-using ls::std::core::IllegalArgumentException;
-using ls::std::core::type::event_id;
-using ls::std::event::Event;
-using ls::std::event::EventHandler;
 using ls::std::event::EventManager;
-using std::make_shared;
-using std::shared_ptr;
-using std::string;
-using test::event::DailyNewsAgency;
-using test::event::GossipNewsAgency;
-using test::event::GossipNewsEvent;
-using test::event::SeriousNewsEvent;
+using ls::std::event::EventParameter;
+using ::std::make_shared;
+using ::std::string;
+using test::event::Button;
+using test::event::ChangeColorEvent;
+using test::event::OnClickEvent;
 using testing::Test;
 
 namespace
@@ -35,277 +31,116 @@ namespace
 
       EventManagerTest() = default;
       ~EventManagerTest() override = default;
+
+      static EventParameter generateParameter(const string &_color)
+      {
+        EventParameter parameter{};
+        parameter.addParameter(_color);
+
+        return parameter;
+      }
   };
 
   TEST_F(EventManagerTest, getClassName)
   {
-    EventManager eventManager{};
-    ASSERT_STREQ("EventManager", eventManager.getClassName().c_str());
+    ASSERT_STREQ("EventManager", EventManager().getClassName().c_str());
   }
 
-  TEST_F(EventManagerTest, subscribe_empty_id)
+  TEST_F(EventManagerTest, getNextProvisionId)
   {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.subscribe("", make_shared<DailyNewsAgency>());
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
+    auto eventManager = EventManager();
+    ASSERT_EQ(1, eventManager.getNextProvisionId());
+    ASSERT_EQ(1, eventManager.requestListenerId());
+    ASSERT_EQ(2, eventManager.getNextProvisionId());
   }
 
-  TEST_F(EventManagerTest, subscribe_no_listener)
+  TEST_F(EventManagerTest, holdsListenerForEvent)
   {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.subscribe("TMP_ID", nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
+    auto eventManager = make_shared<EventManager>();
+    ASSERT_FALSE(eventManager->holdsListenerForEvent(1, OnClickEvent()));
   }
 
-  TEST_F(EventManagerTest, subscribe_no_event_handler_available)
+  TEST_F(EventManagerTest, invoke)
   {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.subscribe("TMP_DIR", make_shared<DailyNewsAgency>());
-          }
-          catch (const EventNotSubscribedException &_exception)
-          {
-            throw;
-          }
-        },
-        EventNotSubscribedException);
-  }
+    auto eventManager = make_shared<EventManager>();
 
-  TEST_F(EventManagerTest, unsubscribe_empty_id)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.unsubscribe("", make_shared<DailyNewsAgency>());
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
+    auto myBlueButton = make_shared<Button>();
+    myBlueButton->subscribe(OnClickEvent().supervisedBy(eventManager), [myBlueButton]() mutable { myBlueButton->onClickEvent(); });
+    myBlueButton->subscribe(ChangeColorEvent().supervisedBy(eventManager), [myBlueButton]() mutable { myBlueButton->onChangeColorEvent(); });
+    auto myRedButton = make_shared<Button>();
+    auto myGreenButton = make_shared<Button>();
+    myGreenButton->subscribe(ChangeColorEvent().supervisedBy(eventManager), [myGreenButton]() mutable { myGreenButton->onChangeColorEvent(); });
 
-  TEST_F(EventManagerTest, unsubscribe_no_listener)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.unsubscribe("TMP_ID", nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
+    // status without any event invoked
 
-  TEST_F(EventManagerTest, addEventHandler)
-  {
-    EventManager eventManager{};
-    ASSERT_TRUE(eventManager.addEventHandler(make_shared<EventHandler>("TMP_ID")));
-  }
+    ASSERT_FALSE(myBlueButton->isClicked());
+    ASSERT_STREQ("black", myBlueButton->getColor().c_str());
+    ASSERT_FALSE(myRedButton->isClicked());
+    ASSERT_STREQ("black", myRedButton->getColor().c_str());
+    ASSERT_FALSE(myGreenButton->isClicked());
+    ASSERT_STREQ("black", myGreenButton->getColor().c_str());
 
-  TEST_F(EventManagerTest, addEventHandler_event_handler_already_exists)
-  {
-    EventManager eventManager{};
-    ASSERT_TRUE(eventManager.addEventHandler(make_shared<EventHandler>("TMP_ID")));
-    ASSERT_FALSE(eventManager.addEventHandler(make_shared<EventHandler>("TMP_ID")));
-  }
+    eventManager->invoke(OnClickEvent());
+    eventManager->invoke(ChangeColorEvent(), EventManagerTest::generateParameter("pink"));
 
-  TEST_F(EventManagerTest, addEventHandler_no_reference)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.addEventHandler(nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
-
-  TEST_F(EventManagerTest, fire_event_handler_not_available)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.fire(Event{"TMP_ID"});
-          }
-          catch (const EventNotHandledException &_exception)
-          {
-            throw;
-          }
-        },
-        EventNotHandledException);
-  }
+    // status with events invoked
 
-  TEST_F(EventManagerTest, hasEventHandler)
-  {
-    EventManager eventManager{};
-    eventManager.addEventHandler(make_shared<EventHandler>("TMP_ID"));
-    ASSERT_TRUE(eventManager.hasEventHandler("TMP_ID"));
+    ASSERT_TRUE(myBlueButton->isClicked());
+    ASSERT_STREQ("pink", myBlueButton->getColor().c_str());
+    ASSERT_FALSE(myRedButton->isClicked());
+    ASSERT_STREQ("black", myRedButton->getColor().c_str());
+    ASSERT_FALSE(myGreenButton->isClicked());
+    ASSERT_STREQ("pink", myGreenButton->getColor().c_str());
   }
 
-  TEST_F(EventManagerTest, hasEventHandler_no_event_handler_available)
+  TEST_F(EventManagerTest, invoke_event_not_known)
   {
-    EventManager eventManager{};
-    ASSERT_FALSE(eventManager.hasEventHandler("TMP_ID"));
-  }
+    auto eventManager = make_shared<EventManager>();
 
-  TEST_F(EventManagerTest, hasEventHandler_empty_id)
-  {
     EXPECT_THROW(
         {
           try
           {
-            EventManager eventManager{};
-            bool hasHandler = eventManager.hasEventHandler("");
+            eventManager->invoke(OnClickEvent());
           }
-          catch (const IllegalArgumentException &_exception)
+          catch (const EventNotHandledException &_exception)
           {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - event OnClickEvent is not known by event manager";
+
+            EXPECT_STREQ(expected.c_str(), actual.c_str());
             throw;
           }
         },
-        IllegalArgumentException);
+        EventNotHandledException);
   }
 
-  TEST_F(EventManagerTest, removeEventHandler)
+  TEST_F(EventManagerTest, requestListenerId)
   {
-    EventManager eventManager{};
-    auto eventHandler = make_shared<EventHandler>("TMP_ID");
-    eventManager.addEventHandler(eventHandler);
+    auto eventManager = EventManager();
 
-    ASSERT_TRUE(eventManager.removeEventHandler(eventHandler));
+    ASSERT_EQ(1, eventManager.getNextProvisionId());
+    ASSERT_EQ(1, eventManager.requestListenerId());
+    ASSERT_EQ(2, eventManager.getNextProvisionId());
   }
 
-  TEST_F(EventManagerTest, removeEventHandler_no_event_handler_available)
+  TEST_F(EventManagerTest, subscribeListenerForEvent)
   {
-    EventManager eventManager{};
-    ASSERT_FALSE(eventManager.removeEventHandler(make_shared<EventHandler>("TMP_ID")));
-  }
+    auto eventManager = make_shared<EventManager>();
+    auto myButton = make_shared<Button>();
 
-  TEST_F(EventManagerTest, removeEventHandler_no_reference)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            EventManager eventManager{};
-            eventManager.removeEventHandler(nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
+    eventManager->subscribeListenerForEvent(myButton, OnClickEvent(), [myButton]() mutable { myButton->onClickEvent(); });
+    ASSERT_TRUE(eventManager->holdsListenerForEvent(myButton->getId(), OnClickEvent()));
   }
 
-  TEST_F(EventManagerTest, production_example)
+  TEST_F(EventManagerTest, unsubscribeListenerForEvent)
   {
-    string news{};
-    string expectedNews{};
-    event_id seriousNewsEventId = SeriousNewsEvent{""}.getId();
-    event_id gossipNewsEventId = GossipNewsEvent{""}.getId();
-
-    // create event handler
-
-    auto seriousNewsEventHandler = make_shared<EventHandler>(seriousNewsEventId); // event id
-    auto gossipNewsEventHandler = make_shared<EventHandler>(gossipNewsEventId);   // event id
-
-    // create and fill event manager with handler
-
     auto eventManager = make_shared<EventManager>();
-    eventManager->addEventHandler(seriousNewsEventHandler);
-    eventManager->addEventHandler(gossipNewsEventHandler);
-
-    // create news agency (listener)
-
-    auto dailyNews = make_shared<DailyNewsAgency>();
-    auto gossipNews = make_shared<GossipNewsAgency>();
-
-    // fire SeriousNewsEvent event with no effect
-
-    eventManager->fire(SeriousNewsEvent(news)); // event call
-    ASSERT_TRUE(dailyNews->getNews().empty());
-    ASSERT_TRUE(gossipNews->getNews().empty());
-
-    // now subscribe to SeriousNewsEvent and fire SeriousNewsEvent event
-
-    eventManager->subscribe(seriousNewsEventId, dailyNews);
-    eventManager->subscribe(seriousNewsEventId, gossipNews);
-    news = "COVID-19 is still going on!";
-    eventManager->fire(SeriousNewsEvent(news)); // event call
-
-    expectedNews = "DailyNewsAgency: " + news;
-    ASSERT_STREQ(expectedNews.c_str(), dailyNews->getNews().c_str());
-    expectedNews = "GossipNewsAgency: " + news;
-    ASSERT_STREQ(expectedNews.c_str(), gossipNews->getNews().c_str());
-
-    dailyNews->clear();
-    gossipNews->clear();
-
-    // unsubscribe SeriousNewsEvent from GossipNewsAgency
-
-    eventManager->unsubscribe(seriousNewsEventId, gossipNews);
-    eventManager->fire(SeriousNewsEvent(news)); // event call
-
-    expectedNews = "DailyNewsAgency: " + news;
-    ASSERT_STREQ(expectedNews.c_str(), dailyNews->getNews().c_str());
-    ASSERT_TRUE(gossipNews->getNews().empty());
-
-    dailyNews->clear();
-    gossipNews->clear();
-
-    // now let GossipNewsAgency subscribe to SeriousNewsEvent + GossipNewsEvent and fire both of them
-
-    eventManager->subscribe(gossipNewsEventId, gossipNews);
-    eventManager->subscribe(seriousNewsEventId, gossipNews);
-
-    news = "COVID-19 is still going on!";
-    eventManager->fire(SeriousNewsEvent(news)); // event call
-    expectedNews = "GossipNewsAgency: " + news;
-    ASSERT_STREQ(expectedNews.c_str(), gossipNews->getNews().c_str());
+    auto myButton = make_shared<Button>();
 
-    news = "ape likes banana!";
-    eventManager->fire(GossipNewsEvent(news)); // event call
-    expectedNews = "GossipNewsAgency: " + news;
-    ASSERT_STREQ(expectedNews.c_str(), gossipNews->getNews().c_str());
+    eventManager->subscribeListenerForEvent(myButton, OnClickEvent(), [myButton]() mutable { myButton->onClickEvent(); });
+    ASSERT_TRUE(eventManager->holdsListenerForEvent(myButton->getId(), OnClickEvent()));
+    eventManager->unsubscribeListenerForEvent(myButton, OnClickEvent());
+    ASSERT_FALSE(eventManager->holdsListenerForEvent(myButton->getId(), OnClickEvent()));
   }
 }

+ 40 - 0
test/cases/event/EventParameterTest.cpp

@@ -0,0 +1,40 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-30
+* Changed:         2024-05-30
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-event.hpp>
+
+using ls::std::event::EventParameter;
+using testing::Test;
+
+namespace
+{
+  class EventParameterTest : public Test
+  {
+    public:
+
+      EventParameterTest() = default;
+      ~EventParameterTest() override = default;
+  };
+
+  TEST_F(EventParameterTest, addParameter)
+  {
+    auto parameter = EventParameter();
+    ASSERT_TRUE(parameter.get().empty());
+
+    parameter.addParameter("blue");
+    ASSERT_EQ(1, parameter.get().size());
+    ASSERT_STREQ("blue", parameter.get().front().c_str());
+  }
+
+  TEST_F(EventParameterTest, get)
+  {
+    ASSERT_TRUE(EventParameter().get().empty());
+  }
+}

+ 33 - 83
test/cases/event/EventTest.cpp

@@ -1,19 +1,20 @@
 /*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-26
- * Changed:         2023-03-25
- *
- * */
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
 
 #include <gtest/gtest.h>
 #include <ls-std/ls-std-core.hpp>
 #include <ls-std/ls-std-event.hpp>
 
 using ls::std::core::IllegalArgumentException;
-using ls::std::core::type::event_parameter;
 using ls::std::event::Event;
+using ls::std::event::EventManager;
+using ::std::make_shared;
 using testing::Test;
 
 namespace
@@ -26,21 +27,31 @@ namespace
       ~EventTest() override = default;
   };
 
-  // additional functionality
-
   TEST_F(EventTest, getClassName)
   {
-    Event event{"TMP_ID"};
-    ASSERT_STREQ("Event", event.getClassName().c_str());
+    ASSERT_STREQ("OnClickEvent", Event("OnClickEvent").getClassName().c_str());
   }
 
-  TEST_F(EventTest, constructor_empty_parameter)
+  TEST_F(EventTest, getManager)
+  {
+    ASSERT_TRUE(Event("TmpEvent").getManager() == nullptr);
+  }
+
+  TEST_F(EventTest, of)
+  {
+    auto event = Event("TmpEvent").supervisedBy(make_shared<EventManager>());
+
+    ASSERT_STREQ("TmpEvent", event.getClassName().c_str());
+    ASSERT_TRUE(event.getManager() != nullptr);
+  }
+
+  TEST_F(EventTest, of_with_no_reference)
   {
     EXPECT_THROW(
         {
           try
           {
-            Event event{""};
+            auto event = Event("TmpEvent").supervisedBy(nullptr);
           }
           catch (const IllegalArgumentException &_exception)
           {
@@ -50,85 +61,24 @@ namespace
         IllegalArgumentException);
   }
 
-  TEST_F(EventTest, addParameter)
-  {
-    Event event{"TMP_ID"};
-    ASSERT_TRUE(event.getParameterList().empty());
-
-    ASSERT_TRUE(event.addParameter(event_parameter("key", "yes")));
-    ASSERT_TRUE(event.addParameter(event_parameter("facing_door", "yes")));
-  }
-
-  TEST_F(EventTest, addParameter_element_already_exists)
-  {
-    Event event{"TMP_ID"};
-    ASSERT_TRUE(event.getParameterList().empty());
-
-    ASSERT_TRUE(event.addParameter(event_parameter("key", "yes")));
-    ASSERT_FALSE(event.addParameter(event_parameter("key", "yes")));
-  }
-
-  TEST_F(EventTest, clearParameterList)
-  {
-    Event event{"OPEN_DOOR_EVENT"};
-    event.addParameter(event_parameter("key", "yes"));
-    event.addParameter(event_parameter("facing_door", "yes"));
-    ASSERT_EQ(2, event.getParameterList().size());
-
-    event.clearParameterList();
-    ASSERT_TRUE(event.getParameterList().empty());
-    ASSERT_EQ(0, event.getParameterList().size());
-  }
-
-  TEST_F(EventTest, getId)
+  TEST_F(EventTest, setManager)
   {
-    Event event{"OPEN_DOOR_EVENT"};
-    ASSERT_STREQ("OPEN_DOOR_EVENT", event.getId().c_str());
-  }
+    auto event = Event("TmpEvent");
+    ASSERT_TRUE(event.getManager() == nullptr);
 
-  TEST_F(EventTest, getParameterList)
-  {
-    Event event{"OPEN_DOOR_EVENT"};
-    ASSERT_TRUE(event.getParameterList().empty());
+    event.setManager(make_shared<EventManager>());
+    ASSERT_FALSE(event.getManager() == nullptr);
   }
 
-  TEST_F(EventTest, removeParameter)
+  TEST_F(EventTest, setManager_with_no_reference)
   {
-    Event event{"OPEN_DOOR_EVENT"};
-    ASSERT_TRUE(event.getParameterList().empty());
+    auto event = Event("TmpEvent");
 
-    event.addParameter(event_parameter("key", "yes"));
-    event.addParameter(event_parameter("facing_door", "yes"));
-
-    ASSERT_TRUE(event.removeParameter("key"));
-    ASSERT_TRUE(event.removeParameter("facing_door"));
-  }
-
-  TEST_F(EventTest, removeParameter_elenent_does_not_exist)
-  {
-    Event event{"OPEN_DOOR_EVENT"};
-
-    ASSERT_FALSE(event.removeParameter("key"));
-    ASSERT_FALSE(event.removeParameter("facing_door"));
-  }
-
-  TEST_F(EventTest, setId)
-  {
-    Event event{"OPEN_DOOR_EVENT"};
-    ASSERT_STREQ("OPEN_DOOR_EVENT", event.getId().c_str());
-
-    event.setId("ANOTHER_EVENT");
-    ASSERT_STREQ("ANOTHER_EVENT", event.getId().c_str());
-  }
-
-  TEST_F(EventTest, setId_empty_parameter)
-  {
     EXPECT_THROW(
         {
           try
           {
-            Event event{"TMP_ID"};
-            event.setId("");
+            event.setManager(nullptr);
           }
           catch (const IllegalArgumentException &_exception)
           {

+ 0 - 161
test/cases/event/NarratorTest.cpp

@@ -1,161 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-05-16
- *
- * */
-
-#include <gtest/gtest.h>
-#include <ls-std-event-test.hpp>
-#include <ls-std/ls-std-core.hpp>
-#include <ls-std/ls-std-event.hpp>
-
-using ls::std::core::Class;
-using ls::std::core::IllegalArgumentException;
-using ls::std::core::interface_type::IListener;
-using ls::std::event::Narrator;
-using std::make_shared;
-using std::shared_ptr;
-using test::event::Colour;
-using test::event::TestDataMercedesCar;
-using testing::Test;
-
-namespace
-{
-  class NarratorTest : public Test
-  {
-    public:
-
-      NarratorTest() = default;
-      ~NarratorTest() override = default;
-
-      shared_ptr<TestDataMercedesCar> mercedes1{};
-      shared_ptr<TestDataMercedesCar> mercedes2{};
-      shared_ptr<TestDataMercedesCar> mercedes3{};
-
-      void createCars()
-      {
-        this->mercedes1 = make_shared<TestDataMercedesCar>();
-        this->mercedes1->setColor("pink");
-        this->mercedes2 = make_shared<TestDataMercedesCar>();
-        this->mercedes2->setColor("blue");
-        this->mercedes3 = make_shared<TestDataMercedesCar>();
-        this->mercedes3->setColor("red");
-      }
-  };
-
-  TEST_F(NarratorTest, addListener)
-  {
-    this->createCars();
-    Narrator paintingMachine{};
-
-    ASSERT_TRUE(paintingMachine.addListener(this->mercedes1));
-    ASSERT_TRUE(paintingMachine.addListener(this->mercedes2));
-    ASSERT_TRUE(paintingMachine.addListener(this->mercedes3));
-  }
-
-  TEST_F(NarratorTest, addListener_listener_already_exists)
-  {
-    this->createCars();
-    Narrator paintingMachine{};
-
-    ASSERT_TRUE(paintingMachine.addListener(this->mercedes1));
-    ASSERT_FALSE(paintingMachine.addListener(this->mercedes1));
-  }
-
-  TEST_F(NarratorTest, addListener_no_reference)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            Narrator paintingMachine{};
-            paintingMachine.addListener(nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
-
-  TEST_F(NarratorTest, clear)
-  {
-    this->createCars();
-    Narrator paintingMachine{};
-    paintingMachine.addListener(this->mercedes1);
-    paintingMachine.addListener(this->mercedes2);
-    paintingMachine.addListener(this->mercedes3);
-
-    ASSERT_FALSE(paintingMachine.getListeners().empty());
-    paintingMachine.clear();
-    ASSERT_TRUE(paintingMachine.getListeners().empty());
-  }
-
-  TEST_F(NarratorTest, getListeners)
-  {
-    Narrator narrator{};
-    ASSERT_TRUE(narrator.getListeners().empty());
-  }
-
-  TEST_F(NarratorTest, removeListener)
-  {
-    this->createCars();
-    Narrator paintingMachine{};
-    paintingMachine.addListener(this->mercedes1);
-    paintingMachine.addListener(this->mercedes2);
-    paintingMachine.addListener(this->mercedes3);
-
-    ASSERT_TRUE(paintingMachine.removeListener(this->mercedes2));
-    ASSERT_TRUE(paintingMachine.removeListener(this->mercedes1));
-    ASSERT_TRUE(paintingMachine.removeListener(this->mercedes3));
-    ASSERT_TRUE(paintingMachine.getListeners().empty());
-  }
-
-  TEST_F(NarratorTest, removeListener_no_listener_available)
-  {
-    this->createCars();
-    Narrator paintingMachine{};
-    ASSERT_FALSE(paintingMachine.removeListener(this->mercedes2));
-  }
-
-  TEST_F(NarratorTest, removeListener_no_reference)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            Narrator paintingMachine{};
-            paintingMachine.removeListener(nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
-
-  TEST_F(NarratorTest, tell)
-  {
-    this->createCars();
-    Narrator paintingMachine{};
-    paintingMachine.addListener(this->mercedes1);
-    paintingMachine.addListener(this->mercedes2);
-    paintingMachine.addListener(this->mercedes3);
-
-    ASSERT_STREQ("pink", this->mercedes1->getColor().data());
-    ASSERT_STREQ("blue", this->mercedes2->getColor().data());
-    ASSERT_STREQ("red", this->mercedes3->getColor().data());
-
-    auto newColor = Colour{"black"};
-    paintingMachine.tell(static_cast<const Class &>(newColor));
-
-    ASSERT_STREQ("black", this->mercedes1->getColor().data());
-    ASSERT_STREQ("black", this->mercedes2->getColor().data());
-    ASSERT_STREQ("black", this->mercedes3->getColor().data());
-  }
-}

+ 0 - 96
test/cases/event/serialization/SerializableJsonEventTest.cpp

@@ -1,96 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-12-20
- * Changed:         2023-05-19
- *
- * */
-
-#include <gtest/gtest.h>
-#include <ls-std/ls-std-core.hpp>
-#include <ls-std/ls-std-event.hpp>
-
-using ls::std::core::IllegalArgumentException;
-using ls::std::core::type::byte_field;
-using ls::std::core::type::event_parameter;
-using ls::std::core::type::event_parameter_list;
-using ls::std::event::Event;
-using ls::std::event::SerializableJsonEvent;
-using std::make_shared;
-using std::string;
-using testing::Test;
-
-namespace
-{
-  class SerializableJsonEventTest : public Test
-  {
-    public:
-
-      SerializableJsonEventTest() = default;
-      ~SerializableJsonEventTest() override = default;
-  };
-
-  TEST_F(SerializableJsonEventTest, constructor_parameter_not_set)
-  {
-    EXPECT_THROW(
-        {
-          try
-          {
-            SerializableJsonEvent serializable{nullptr};
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
-
-  TEST_F(SerializableJsonEventTest, marshal)
-  {
-    Event event{"OPEN_DOOR_EVENT"};
-    event.addParameter(event_parameter{"key_available", "true"});
-    event.addParameter(event_parameter{"door_id", "16675"});
-
-    SerializableJsonEvent serializable{make_shared<Event>(event)};
-
-    byte_field data = serializable.marshal();
-    ASSERT_FALSE(data.empty());
-    string expectedString = R"({"id":"OPEN_DOOR_EVENT","parameterList":{"door_id":["door_id","16675"],"key_available":["key_available","true"]}})";
-    ASSERT_STREQ(expectedString.c_str(), data.c_str());
-  }
-
-  TEST_F(SerializableJsonEventTest, unmarshal)
-  {
-    SerializableJsonEvent serializable{make_shared<Event>("TMP_EVENT")};
-    string jsonString = R"({"id":"OPEN_DOOR_EVENT","parameterList":{"door_id":["door_id","16675"],"key_available":["key_available","true"]}})";
-
-    serializable.unmarshal(jsonString);
-    ASSERT_STREQ("OPEN_DOOR_EVENT", serializable.getValue()->getId().c_str());
-    event_parameter_list parameterList = serializable.getValue()->getParameterList();
-
-    ASSERT_FALSE(parameterList.empty());
-    ASSERT_EQ(2, parameterList.size());
-    ASSERT_STREQ("16675", parameterList.at("door_id").c_str());
-    ASSERT_STREQ("true", parameterList.at("key_available").c_str());
-  }
-
-  TEST_F(SerializableJsonEventTest, setValue_parameter_not_set)
-  {
-    SerializableJsonEvent serializable{make_shared<Event>("TMP_EVENT")};
-
-    EXPECT_THROW(
-        {
-          try
-          {
-            serializable.setValue(nullptr);
-          }
-          catch (const IllegalArgumentException &_exception)
-          {
-            throw;
-          }
-        },
-        IllegalArgumentException);
-  }
-}

+ 39 - 0
test/classes/event/Button.cpp

@@ -0,0 +1,39 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
+#include "Button.hpp"
+
+using ls::std::event::EventListener;
+using ::std::string;
+using test::event::Button;
+
+Button::Button() : EventListener(), color("black")
+{}
+
+Button::~Button() noexcept = default;
+
+string Button::getColor() const
+{
+  return this->color;
+}
+
+bool Button::isClicked() const
+{
+  return this->clicked;
+}
+
+void Button::onChangeColorEvent()
+{
+  this->color = this->parameter.get().front();
+}
+
+void Button::onClickEvent()
+{
+  this->clicked = !this->clicked;
+}

+ 37 - 0
test/classes/event/Button.hpp

@@ -0,0 +1,37 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-30
+*
+* */
+
+#ifndef LS_STD_BUTTON_HPP
+#define LS_STD_BUTTON_HPP
+
+#include <ls-std/ls-std-event.hpp>
+#include <string>
+
+namespace test::event
+{
+  class Button : public ls::std::event::EventListener
+  {
+    public:
+
+      explicit Button();
+      ~Button() noexcept override;
+
+      [[nodiscard]] ::std::string getColor() const;
+      [[nodiscard]] bool isClicked() const;
+      void onChangeColorEvent();
+      void onClickEvent();
+
+    private:
+
+      bool clicked{};
+      ::std::string color{};
+  };
+}
+
+#endif

+ 18 - 0
test/classes/event/ChangeColorEvent.cpp

@@ -0,0 +1,18 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-30
+* Changed:         2024-05-30
+*
+* */
+
+#include "ChangeColorEvent.hpp"
+
+using ls::std::event::Event;
+using test::event::ChangeColorEvent;
+
+ChangeColorEvent::ChangeColorEvent() : Event("ChangeColorEvent")
+{}
+
+ChangeColorEvent::~ChangeColorEvent() noexcept = default;

+ 26 - 0
test/classes/event/ChangeColorEvent.hpp

@@ -0,0 +1,26 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-30
+* Changed:         2024-05-30
+*
+* */
+
+#ifndef LS_STD_CHANGE_COLOR_EVENT_HPP
+#define LS_STD_CHANGE_COLOR_EVENT_HPP
+
+#include <ls-std/event/Event.hpp>
+
+namespace test::event
+{
+  class ChangeColorEvent : public ls::std::event::Event
+  {
+    public:
+
+      explicit ChangeColorEvent();
+      ~ChangeColorEvent() noexcept override;
+  };
+}
+
+#endif

+ 0 - 25
test/classes/event/Colour.cpp

@@ -1,25 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2022-05-14
- * Changed:         2023-05-15
- *
- * */
-
-#include "Colour.hpp"
-
-using ls::std::core::Class;
-using std::string;
-using std::string_view;
-using test::event::Colour;
-
-Colour::Colour(string_view _value) : Class("Colour"), value(_value)
-{}
-
-Colour::~Colour() noexcept = default;
-
-string_view Colour::getValue() const
-{
-  return this->value;
-}

+ 0 - 33
test/classes/event/Colour.hpp

@@ -1,33 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2022-05-14
- * Changed:         2023-05-15
- *
- * */
-
-#ifndef LS_STD_COLOUR_HPP
-#define LS_STD_COLOUR_HPP
-
-#include <ls-std/ls-std-core.hpp>
-#include <string_view>
-
-namespace test::event
-{
-  class Colour : public ls::std::core::Class
-  {
-    public:
-
-      explicit Colour(::std::string_view _value);
-      ~Colour() noexcept override;
-
-      [[nodiscard]] ::std::string_view getValue() const;
-
-    private:
-
-      ::std::string_view value{};
-  };
-}
-
-#endif

+ 0 - 42
test/classes/event/DailyNewsAgency.cpp

@@ -1,42 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-15
- *
- * */
-
-#include "DailyNewsAgency.hpp"
-#include <ls-std/ls-std-event.hpp>
-
-using ls::std::core::Class;
-using ls::std::event::Event;
-using std::string;
-using test::event::DailyNewsAgency;
-using test::event::NewsAgency;
-
-DailyNewsAgency::DailyNewsAgency() : NewsAgency("DailyNewsAgency")
-{}
-
-DailyNewsAgency::~DailyNewsAgency() noexcept = default;
-
-void DailyNewsAgency::listen(const Class &_info)
-{
-  Event event = dynamic_cast<const Event &>(_info);
-
-  if (event.getId() == "SeriousNewsEvent")
-  {
-    this->news = this->getName() + ": " + event.getParameterList().at("news");
-  }
-}
-
-void DailyNewsAgency::clear()
-{
-  this->news.clear();
-}
-
-string DailyNewsAgency::getNews() const
-{
-  return this->news;
-}

+ 0 - 43
test/classes/event/DailyNewsAgency.hpp

@@ -1,43 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-15
- *
- * */
-
-#ifndef LS_STD_DAILY_NEWS_AGENCY_HPP
-#define LS_STD_DAILY_NEWS_AGENCY_HPP
-
-#include "NewsAgency.hpp"
-#include <ls-std/ls-std-core.hpp>
-#include <map>
-#include <memory>
-#include <string>
-
-namespace test::event
-{
-  class DailyNewsAgency : public test::event::NewsAgency, public ls::std::core::interface_type::IListener
-  {
-    public:
-
-      DailyNewsAgency();
-      ~DailyNewsAgency() noexcept override;
-
-      // implementation
-
-      void listen(const ls::std::core::Class &_info) override;
-
-      // additional functionality
-
-      void clear();
-      [[nodiscard]] ::std::string getNews() const;
-
-    private:
-
-      ::std::string news{};
-  };
-}
-
-#endif

+ 0 - 47
test/classes/event/GossipNewsAgency.cpp

@@ -1,47 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-16
- *
- * */
-
-#include "GossipNewsAgency.hpp"
-#include <ls-std/ls-std-event.hpp>
-
-using ls::std::core::Class;
-using ls::std::event::Event;
-using std::string;
-using test::event::GossipNewsAgency;
-using test::event::NewsAgency;
-
-GossipNewsAgency::GossipNewsAgency() : NewsAgency("GossipNewsAgency")
-{}
-
-GossipNewsAgency::~GossipNewsAgency() noexcept = default;
-
-void GossipNewsAgency::listen(const Class &_info)
-{
-  Event event = dynamic_cast<const Event &>(_info);
-
-  if (event.getId() == "SeriousNewsEvent")
-  {
-    this->news = this->getName() + ": " + event.getParameterList().at("news");
-  }
-
-  if (event.getId() == "GossipNewsEvent")
-  {
-    this->news = this->getName() + ": " + event.getParameterList().at("news");
-  }
-}
-
-void GossipNewsAgency::clear()
-{
-  this->news.clear();
-}
-
-string GossipNewsAgency::getNews() const
-{
-  return this->news;
-}

+ 0 - 43
test/classes/event/GossipNewsAgency.hpp

@@ -1,43 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-16
- *
- * */
-
-#ifndef LS_STD_GOSSIP_NEWS_AGENCY_HPP
-#define LS_STD_GOSSIP_NEWS_AGENCY_HPP
-
-#include "NewsAgency.hpp"
-#include <ls-std/ls-std-core.hpp>
-#include <map>
-#include <memory>
-#include <string>
-
-namespace test::event
-{
-  class GossipNewsAgency : public test::event::NewsAgency, public ls::std::core::interface_type::IListener
-  {
-    public:
-
-      GossipNewsAgency();
-      ~GossipNewsAgency() noexcept override;
-
-      // implementation
-
-      void listen(const ls::std::core::Class &_info) override;
-
-      // additional functionality
-
-      void clear();
-      [[nodiscard]] ::std::string getNews() const;
-
-    private:
-
-      ::std::string news{};
-  };
-}
-
-#endif

+ 0 - 24
test/classes/event/GossipNewsEvent.cpp

@@ -1,24 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-02-23
- *
- * */
-
-#include "GossipNewsEvent.hpp"
-
-using ls::std::core::type::event_parameter;
-using ls::std::event::Event;
-using std::make_pair;
-using std::string;
-using test::event::GossipNewsEvent;
-
-GossipNewsEvent::GossipNewsEvent(const string &_news) : Event("GossipNewsEvent")
-{
-  event_parameter newsParameter = make_pair("news", _news);
-  this->addParameter(newsParameter);
-}
-
-GossipNewsEvent::~GossipNewsEvent() noexcept = default;

+ 0 - 27
test/classes/event/GossipNewsEvent.hpp

@@ -1,27 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-02-23
- *
- * */
-
-#ifndef LS_STD_GOSSIP_NEWS_EVENT_HPP
-#define LS_STD_GOSSIP_NEWS_EVENT_HPP
-
-#include <ls-std/ls-std-event.hpp>
-#include <string>
-
-namespace test::event
-{
-  class GossipNewsEvent : public ls::std::event::Event
-  {
-    public:
-
-      explicit GossipNewsEvent(const ::std::string &_news);
-      ~GossipNewsEvent() noexcept override;
-  };
-}
-
-#endif

+ 0 - 24
test/classes/event/NewsAgency.cpp

@@ -1,24 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-19
- *
- * */
-
-#include "NewsAgency.hpp"
-
-using std::move;
-using std::string;
-using test::event::NewsAgency;
-
-NewsAgency::NewsAgency(string _agencyName) : agencyName(::move(_agencyName))
-{}
-
-NewsAgency::~NewsAgency() = default;
-
-string NewsAgency::getName() const
-{
-  return this->agencyName;
-}

+ 0 - 32
test/classes/event/NewsAgency.hpp

@@ -1,32 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-05-19
- *
- * */
-
-#ifndef LS_STD_NEWS_AGENCY_HPP
-#define LS_STD_NEWS_AGENCY_HPP
-
-#include <string>
-
-namespace test::event
-{
-  class NewsAgency
-  {
-    public:
-
-      explicit NewsAgency(::std::string _agencyName);
-      virtual ~NewsAgency();
-
-      [[nodiscard]] ::std::string getName() const;
-
-    private:
-
-      ::std::string agencyName{};
-  };
-}
-
-#endif

+ 18 - 0
test/classes/event/OnClickEvent.cpp

@@ -0,0 +1,18 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-17
+*
+* */
+
+#include "OnClickEvent.hpp"
+
+using ls::std::event::Event;
+using test::event::OnClickEvent;
+
+OnClickEvent::OnClickEvent() : Event("OnClickEvent")
+{}
+
+OnClickEvent::~OnClickEvent() noexcept = default;

+ 26 - 0
test/classes/event/OnClickEvent.hpp

@@ -0,0 +1,26 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2024-05-16
+* Changed:         2024-05-17
+*
+* */
+
+#ifndef LS_STD_ON_CLICK_EVENT_HPP
+#define LS_STD_ON_CLICK_EVENT_HPP
+
+#include <ls-std/event/Event.hpp>
+
+namespace test::event
+{
+  class OnClickEvent : public ls::std::event::Event
+  {
+    public:
+
+      explicit OnClickEvent();
+      ~OnClickEvent() noexcept override;
+  };
+}
+
+#endif

+ 0 - 24
test/classes/event/SeriousNewsEvent.cpp

@@ -1,24 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-02-23
- *
- * */
-
-#include "SeriousNewsEvent.hpp"
-
-using ls::std::core::type::event_parameter;
-using ls::std::event::Event;
-using std::make_pair;
-using std::string;
-using test::event::SeriousNewsEvent;
-
-SeriousNewsEvent::SeriousNewsEvent(const string &_news) : Event("SeriousNewsEvent")
-{
-  event_parameter newsParameter = make_pair("news", _news);
-  this->addParameter(newsParameter);
-}
-
-SeriousNewsEvent::~SeriousNewsEvent() noexcept = default;

+ 0 - 27
test/classes/event/SeriousNewsEvent.hpp

@@ -1,27 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-27
- * Changed:         2023-02-23
- *
- * */
-
-#ifndef LS_STD_SERIOUS_NEWS_EVENT_HPP
-#define LS_STD_SERIOUS_NEWS_EVENT_HPP
-
-#include <ls-std/ls-std-event.hpp>
-#include <string>
-
-namespace test::event
-{
-  class SeriousNewsEvent : public ls::std::event::Event
-  {
-    public:
-
-      explicit SeriousNewsEvent(const ::std::string &_news);
-      ~SeriousNewsEvent() noexcept override;
-  };
-}
-
-#endif

+ 0 - 28
test/classes/event/TestDataCar.cpp

@@ -1,28 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-05-18
- *
- * */
-
-#include "TestDataCar.hpp"
-
-using std::string_view;
-using test::event::TestDataCar;
-
-TestDataCar::TestDataCar() : color("white")
-{}
-
-TestDataCar::~TestDataCar() = default;
-
-string_view TestDataCar::getColor() const
-{
-  return this->color;
-}
-
-void TestDataCar::setColor(string_view _color)
-{
-  this->color = _color;
-}

+ 0 - 34
test/classes/event/TestDataCar.hpp

@@ -1,34 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-05-18
- *
- * */
-
-#ifndef LS_STD_TEST_DATA_CAR_HPP
-#define LS_STD_TEST_DATA_CAR_HPP
-
-#include <string>
-#include <string_view>
-
-namespace test::event
-{
-  class TestDataCar
-  {
-    public:
-
-      TestDataCar();
-      virtual ~TestDataCar();
-
-      [[nodiscard]] ::std::string_view getColor() const;
-      void setColor(::std::string_view _color);
-
-    private:
-
-      ::std::string_view color{};
-  };
-}
-
-#endif

+ 0 - 27
test/classes/event/TestDataMercedesCar.cpp

@@ -1,27 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-02-23
- *
- * */
-
-#include "TestDataMercedesCar.hpp"
-#include "Colour.hpp"
-
-using ls::std::core::Class;
-using test::event::Colour;
-using test::event::TestDataMercedesCar;
-
-TestDataMercedesCar::TestDataMercedesCar() : TestDataCar()
-{
-  this->setColor("blue");
-}
-
-TestDataMercedesCar::~TestDataMercedesCar() noexcept = default;
-
-void TestDataMercedesCar::listen(const Class &_info)
-{
-  this->setColor(dynamic_cast<const Colour &>(_info).getValue());
-}

+ 0 - 29
test/classes/event/TestDataMercedesCar.hpp

@@ -1,29 +0,0 @@
-/*
- * Author:          Patrick-Christopher Mattulat
- * Company:         Lynar Studios
- * E-Mail:          webmaster@lynarstudios.com
- * Created:         2020-11-14
- * Changed:         2023-02-23
- *
- * */
-
-#ifndef LS_STD_TEST_DATA_MERCEDES_CAR_HPP
-#define LS_STD_TEST_DATA_MERCEDES_CAR_HPP
-
-#include "TestDataCar.hpp"
-#include <ls-std/ls-std-core.hpp>
-
-namespace test::event
-{
-  class TestDataMercedesCar : public test::event::TestDataCar, public ls::std::core::interface_type::IListener
-  {
-    public:
-
-      TestDataMercedesCar();
-      ~TestDataMercedesCar() noexcept override;
-
-      void listen(const ls::std::core::Class &_info) override;
-  };
-}
-
-#endif

+ 4 - 9
test/ls-std-event-test.hpp

@@ -3,20 +3,15 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-14
- * Changed:         2023-02-03
+ * Changed:         2024-05-30
  *
  * */
 
 #ifndef LS_STD_LS_STD_EVENT_TEST_HPP
 #define LS_STD_LS_STD_EVENT_TEST_HPP
 
-#include <classes/event/Colour.hpp>
-#include <classes/event/DailyNewsAgency.hpp>
-#include <classes/event/GossipNewsAgency.hpp>
-#include <classes/event/GossipNewsEvent.hpp>
-#include <classes/event/NewsAgency.hpp>
-#include <classes/event/SeriousNewsEvent.hpp>
-#include <classes/event/TestDataCar.hpp>
-#include <classes/event/TestDataMercedesCar.hpp>
+#include <classes/event/Button.hpp>
+#include <classes/event/ChangeColorEvent.hpp>
+#include <classes/event/OnClickEvent.hpp>
 
 #endif