KyrietS / tinyevents

TinyEvents is a C++ header-only library for a generic Event-Dispatch System
MIT License
2 stars 1 forks source link
cpp17 event-dispatcher events header-only message-system

TinyEvents - A Simple Event-Dispatcher System for C++

Tests Lincense

TinyEvents is a simple header-only library for C++ that provides a basic, yet powerfull, event-dispatcher system. It is designed to be easy to use and to have minimal dependencies. It is written in C++17 and has no dependencies other than the standard library.

In TinyEvents any type can be used as an event. The events are dispatched to listeners that are registered for a specific event type. Asynchronous (deferred) dispatching using a queue is also supported. With the tinyevents::Token helper class you can get RAII-style automatic listener removal.

Basic Usage

#include <tinyevents/tinyevents.hpp>
#include <iostream>

struct MyEvent {
    int value;
};

int main() {
    tinyevents::Dispatcher dispatcher;

    // Register a listener for MyEvent
    auto handle = dispatcher.listen<MyEvent>([](const auto& event) {
        std::cout << "Received MyEvent: " << event.value << std::endl;
    });

    // Dispatch an event
    dispatcher.dispatch(MyEvent{11});  // Prints "Received MyEvent: 11"

    // Queue events
    dispatcher.queue(MyEvent{22});
    dispatcher.queue(MyEvent{33});
    dispatcher.process();              // Prints "Received MyEvent: 22"
                                       //        "Received MyEvent: 33"

    dispatcher.remove(handle);         // Remove the listener
    dispatcher.dispatch(MyEvent{44});  // No listener, so nothing happens

    return 0;
}

Getting Started

Manual Installation

Just copy the include/tinyevents folder to your project and add the include folder to your include path. The library is header-only, so no compilation is needed.

CMake

If you use CMake, you can use the FetchContent module to download the library and add it to your project. For example:

include(FetchContent)
FetchContent_Declare(
  tinyevents
  GIT_REPOSITORY https://github.com/KyrietS/tinyevents.git
  GIT_TAG        master
)
FetchContent_MakeAvailable(tinyevents)
target_link_libraries(${TARGET} PRIVATE tinyevents)

Or you can just clone this repository manually and add it as a subdirectory to your CMake project.

add_subdirectory(tinyevents)
target_link_libraries(${TARGET} PRIVATE tinyevents)

Don't forget to change the ${TARGET} to the name of your target.

Documentation

Listening to Events

Register a listener for a specific event type. The listener will be called when an event of the specified type is dispatched.

template<typename Event>
std::uint64_t listen(const std::function<void(const Event&)>& listener)

Returns a handle that can be used to remove the listener.

Listening to Events Once

Same as listen(), but the listener will be removed after it is called once.

template<typename Event>
std::uint64_t listenOnce(const std::function<void(const Event&)>& listener)

Returns a handle that can be used to remove the listener.

Removing Listeners

Remove a listener that was previously registered using listen().

void remove(std::uint64_t handle)

Checking Listeners

Check if a listener is registered in the dispatcher.

bool hasListener(std::uint64_t handle)

Dispatching Events

Immediately dispatch an event to all the listeners that are registered for the event type.

template<typename Event>
void dispatch(const Event& event)

Queueing Events

Add an event to the queue. The event will be dispatched once process() is called.

template<typename Event>
void queue(const Event& event)

Processing the Queue

Processing the queue will dispatch all the events that were queued using queue(). The events will be dispatched in the order they were queued.

void process()

Some notes about callback safety

Token - helper RAII class


tinevents::Dispatcher dispatcher;
std::uint64_t handle = dispatcher.listen<MyEvent>(myCallback);

// RAII token
tinyevents::Token token(dispatcher, handle); // When this token goes out of scope the listener
                                             // will be automatically removed from dispatcher.

Make sure that the dispatcher is still alive when the token is destroyed.

Tests

Tests are written using Google Test. The library is fetched automatically by CMake during the configuration step of the tests.

In order to run the tests with CMake, you can use the following commands:

cmake -S tests -B tests/build
cmake --build tests/build
ctest --test-dir tests/build

License

Copyright © 2023-2024 KyrietS\ Use of this software is granted under the terms of the MIT License.

See the LICENSE file for more details.