4.4 KiB
eventpp -- C++ library for event dispatcher and callback list
eventpp provides tools that allow your application components to communicate with each other by dispatching events and listening to them. With eventpp you can implement signal/slot mechanism, or observer pattern, very easily.
Facts and features
- Support both synchronous event dispatching (EventDispatcher) and asynchronous event queue (EventQueue).
- Supports nested event. A listener can dispatch event, append/prepend/insert/remove other listeners during capturing an event safely.
- Support event filter.
- Template based, less runtime overhead, unlimited possibilities. The event and callback can be almost any C++ types meeting minimum requirements.
- Thread safe.
- Requires C++ 11 (tested with MSVC 2017, MSVC 2015, MinGW (Msys) gcc 7.2, and Ubuntu gcc 5.4).
- Backed by unit tests.
- Written in portable and standard C++. (I'm not a C++ standard expert so if you find any non-standard code or undefined behavior please let me know.)
- Doesn't depend on any other libraries.
- Header only, no source file, no need to build.
License
Apache License, Version 2.0
Source code
https://github.com/wqking/eventpp
Quick start
Namespace
eventpp
Using CallbackList
#include "eventpp/callbacklist.h"
eventpp::CallbackList<void (const std::string &, const bool)> callbackList;
callbackList.append([](const std::string & s, const bool b) {
std::cout << std::boolalpha << "Got callback 1, s is " << s << " b is " << b << std::endl;
});
callbackList.append([](std::string s, int b) {
std::cout << std::boolalpha << "Got callback 2, s is " << s << " b is " << b << std::endl;
});
callbackList("Hello world", true);
Using EventDispatcher
#include "eventpp/eventdispatcher.h"
eventpp::EventDispatcher<int, void ()> dispatcher;
dispatcher.appendListener(3, []() {
std::cout << "Got event 3." << std::endl;
});
dispatcher.appendListener(5, []() {
std::cout << "Got event 5." << std::endl;
});
dispatcher.appendListener(5, []() {
std::cout << "Got another event 5." << std::endl;
});
// dispatch event 3
dispatcher.dispatch(3);
// dispatch event 5
dispatcher.dispatch(5);
Using EventQueue
eventpp::EventQueue<int, void (const std::string &, const bool)> queue;
dispatcher.appendListener(3, [](const std::string s, bool b) {
std::cout << std::boolalpha << "Got event 3, s is " << s << " b is " << b << std::endl;
});
dispatcher.appendListener(5, [](const std::string s, bool b) {
std::cout << std::boolalpha << "Got event 5, s is " << s << " b is " << b << std::endl;
});
// The listeners are not triggered during enqueue.
queue.enqueue(3, "Hello", true);
queue.enqueue(5, "World", false);
// Process the event queue, dispatch all queued events.
queue.process();
Documentations
- An overview introduction
- Tutorials of CallbackList
- Tutorials of EventDispatcher
- Tutorials of EventQueue
- Document of CallbackList
- Document of EventDispatcher
- Document of EventQueue
- Frequently Asked Questions
- There are compilable tutorials in the unit tests.
Build the unit tests
The library itself is header only and doesn't need building.
The unit test requires CMake to build, and there is a makefile to ease the building.
Go to folder tests/build
, then run make
with different target.
make vc17
#generate solution files for Microsoft Visual Studio 2017, then open eventpptest.sln in folder project_vc17make vc15
#generate solution files for Microsoft Visual Studio 2015, then open eventpptest.sln in folder project_vc15make mingw
#build using MinGWmake linux
#build on Linux
Motivations
I (wqking) am a big fan of observer pattern (publish/subscribe pattern), I used such pattern a lot in my code. I either used GCallbackList in my cpgf library which is too simple and not safe, or repeated coding event dispatching mechanism such as I did in my Gincu game engine. Both approaches are neither fun nor robust.
Thanking to C++11, now it's quite easy to write a reusable event library with beautiful syntax (it's a nightmare to simulate the variadic template in C++03), so here comes eventpp
.