This library provides a generic Observer pattern implementation with value push mechanism.
In this library, the subject (the class that dispatches the value changes) is called the Source, the observer (the class that receives said value changes from the subject) is called the Listener and the value changes dispatched from the subject to all of it's observers are called Events.
This library provides various thread-safety features for the Observer pattern. For example, automatic connection management between the Source and it's registered Listeners, exception handling for Listener callback execution, asynchronous Event processing.
The main design goal of this project is to provide a simple and a thread-safe way to dispatch Events without blocking the Source for a long time in multithreaded applications. In other words, the Source should be able to dispatch a new Event even if some (or all) Listeners are still processing the previous events. This makes the Source a lot more responsive than the simple, wait until all Listeners are finished processing the last event, before dispatching a new Event, implementation. At the same time, this allows the Listeners to process different Events concurrently. This is achieved by each Listener dispatching Event processing tasks to a shared thread-pool when the Source triggers the Listeners Event handling mechanism.
This library also provides a way of letting you know, when to start and stop your notification dispatch process with the help of the FirstConnection and the LastDisconnection callbacks. This way, you don't need to dispatch notifications when no one is listening to them.
Furthermore, this library provides a way of creating Listeners with different Event processing priorities in multi-threaded operation mode. This operation mode is enabled by compiling the library with the cmake PRIORITY_LISTENERS option set to ON and is disabled by default. With this setting on, users can create Listeners that have different Event execution priorities in the internal thread pool.
If multi-threaded Event processing functionality is not required (for example, when developing single-threaded applications), users may use the simpler, yet lighter Listener implementation by setting the cmake MULTITHREADING option to OFF. In this operation mode, enabling the cmake PRIORITY_LISTENERS option as well as using the priority setting in code, has no effect.
This project uses Pierre-Antoine Lacaze's Sigslot library to implement the observer functionality and Barak Shoshany's BS::thread_pool library to process events asynchronicity as well as Google's GTest framework for unit test implementation.## Configuring
By default, this library is build with Barak Shoshany's BS::thread_pool dependency. If you do not need multi-threaded Event processing capabilities, or can not use the std::threads library, disable this capability via conan in conanfile.txt in [options] section:
[options]
event_model:multithreading=False
This project uses git submodules, please initialize them when creating a fresh repository clone. To initialize all of the submodule run the following command:
git submodule update --init --recursive
If you want to have the latest documentation with your changes locally, you can generate it with Doxygen from sources by running the following:
doxygen DoxyfileThis will generate html like documentation at [PROJECT_ROOT]/docs/html. To use it open the [PROJECT_ROOT]/docs/html/index.html file with your browser.
- compiler with C++17 support
- cmake 3.24.0 >= - build system generator, used by package generator as well
- python3 - used by utilities and package generator
- conan 2.4.0 >= - dependency handler/package generator
- ninja - build system (alternative to
make) - clang-format 15.0.7 - to use formatting tools
- clang-tidy 15.0.7 - to use static code analysis
- lcov - to generate code coverage reports
- valgrind - to run memory analysis
- doxygen 1.9.8 >= - to generate documentation from code
- plantuml 1.2023.10 >= - to generate UML diagrams in doxygen
- C/C++ - provides linking to inellisense and code debuggers
- CMake Tools - provides CMake highlighting, configuring, building
- C++ TestMate - C++ Unit Test Explorer integration for Test Explorer UI
- Clang-Format - provides code formatting
- Doxygen Documentation Generator - provides autogenerated doxygen documentation stubs
- Code Spell Checker - provides english text spellchecker functionality
A CMake variant file is provided with this repository for easy cmake configuration setup. This functionality requires CMake Tools plugin to be installed. After Visual Code has been started Open Control Panel with Cntrl + Shift + P and type in CMake: Select Variant to start configuring your cmake project configuration.
To build the project CMake project makefile generation as well as integrated testing and linting tools.
We recommend to create a directory for project makefiles and binaries:
mkdir build && cd buildOnce in this new build directory, generate the project makefiles for Debug configuration (you can change Debug for Release if debugging information is not needed):
cmake .. -DCMAKE_BUILD_TYPE=DebugOnce makefiles have been generated, build the project either in Debug configuration:
cmake --build . --target all --config Debug --or Release configuration, if previous cmake configuration was set for Release:
cmake --build . --target all --config Release --Once the project is built, it is also possible to use the integrated tests runner to run the provided tests:
ctest --verboseTo create a custom local package first define VERSION, USER and CHANEL environmental variables. These variables will tell conan how to name the package.
VERSIONvariable specifies package version number in the following format${MAJOR}.${MINOR}.${PATCH}. For more information see Release versioning schemaUSERvariable specifies the name of release community (for examplehahn-schickard,bincrafters, etc.), it is used to showcase that this package is outside of conan-center-index repositoryCHANELvariable specifies the package type, i.e. if it is a stable, development or nightly release, defaults to empty
To create local conan packages run the following command in project root directory:
conan create . ${VERSION}@${USER}/${CHANEL} --build=missingTo create local conan packages run the following command in project root directory:
conan create . --version=${VERSION} --user=${USER} --channel=${CHANEL} --build=missingIn case you need to change default recipe options
conan create . --version=${VERSION} --user=${USER} --channel=${CHANEL} --build=missing -o ${OPTION_PAIR}Where ${OPTION_PAIR} is option_name=value. To add multiple options, continue to add -o ${OPTION_PAIR} as required.