https://github.com/stypox/event-notifier
Connect events to functions with an intuitive C++ interface
https://github.com/stypox/event-notifier
event event-driven event-handler event-management event-notification events header-only simple
Last synced: 8 months ago
JSON representation
Connect events to functions with an intuitive C++ interface
- Host: GitHub
- URL: https://github.com/stypox/event-notifier
- Owner: Stypox
- Created: 2019-02-20T13:11:53.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-03-12T14:22:21.000Z (about 7 years ago)
- Last Synced: 2024-10-28T19:55:22.820Z (over 1 year ago)
- Topics: event, event-driven, event-handler, event-management, event-notification, events, header-only, simple
- Language: C++
- Homepage:
- Size: 38.1 KB
- Stars: 3
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Event notifier
A **C++ header-only** library that lets you **connect events to functions** with a **small** and **intuitive** interface. When an event occours, all the functions connected to it are called. **Member functions** (like `game.pause()`) are supported, too!
# Connect events to functions
When connecting some events to a function, you can choose whether to **connect all events** of that type to the function **or only some** (based on `std::hash`) [``en`` is an EventNotifier]:
- `en.connect(function)`: connects every event of type `Event` to `function`. E.g. `en.connect(function)` would connect every event of type `Click` to the function.
- `en.connect(function, events...)`: connects every event in `events...` to `function`. `std::hash` is used to compare for equality. E.g. `en.connect(function, Click{right})` would connect every event that has the same hash as `Click{right}` to the function.
`function` can be any function convertible to `std::function` (normal functions and lambdas are ok). It must take either 0 arguments or 1 argument (the event).
If you need to connect to a member function, you can use `en.connect_member()` [in the examples `game` is of type `Game`]:
- `en.connect_member(object, &object_type::member_function)`: connects every event of type `Event` to `(object.*member_function)()`. E.g. `en.connect_member(game, &Game::pause)`
- `en.connect_member(object, &object_type::member_function, events...)`: connects every event in `events...` to `(object.*member_function)()`. E.g. `en.connect_member(game, &Game::pause, Click{right})`
Every connect\[_member\]() call returns a `EventNotifier::Handler`, that can be used to **disconnect the function** when it is not needed / it can not be used anymore. It uses **RAII**, so its destructor takes care of disconnecting the function it handles, even though the disconnection can be done manually using ``handler.disconnect()``. If you do not need this kind of handling (because the connected function will always be valid) you can do `handler.keep()`, that will transfer the ownership to the EventNotifier. For example: `en.connect(closeGame, WindowButton{X}).keep()`. The compiler will warn you if you do nothing with the returned Handler.
# Event notification
When you want an event to occour, you have to **pass it to the EventNotifier** through the `en.notify(event)` function.
For example: `en.notify(Click{right})`
# Installation
To use this library just download the header file `event_notifier.hpp` and `#include` it in your project! If you want to `#include` it as `` you need to add `-IPATH/TO/event-notifier/include` to your compiler options. Note: it requires C++17, so add to your compiler options `-std=c++17`.
# Example
```cpp
#include
#include
using stypox::EventNotifier;
enum Click { right, left };
struct MouseScroll { int deltaPixels; };
class Game {
EventNotifier::Handler m_rightClickHandler;
// ^ will automatically be disconnected when Game is destructed.
public:
Game(EventNotifier& en) :
m_rightClickHandler{en.connect_member(*this, &Game::onRightClick, Click::right)} {}
void onRightClick() { std::cout << "Game received a right click!\n"; }
};
int main() {
EventNotifier en;
en.connect([](MouseScroll ms){ std::cout << "Scrolled by " << ms.deltaPixels << " pixels\n"; }).keep();
// ^ here `.keep()` is used since the lambda will always be available: it does not depend on any object that may be destructed before `en` is.
en.notify(MouseScroll{17}); // prints "Scrolled by 17 pixels"
{
Game game{en};
en.notify(Click::right); // prints "Game received a right click!"
en.notify(Click::left); // does nothing
}
en.notify(Click::right); // does nothing since `game` has already been destructed
en.notify(MouseScroll{23}); // prints "Scrolled by 23 pixels"
// no leaks: when `en` is destructed all functions are disconnected.
}
```
The complete output will be:
```
Scrolled by 17 pixels
Game received a right click!
Scrolled by 23 pixels
```