Skip to content

Instantly share code, notes, and snippets.

@HarryR
Created December 9, 2019 17:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarryR/e308f4a220350ed74780a6b3a5ace903 to your computer and use it in GitHub Desktop.
Save HarryR/e308f4a220350ed74780a6b3a5ace903 to your computer and use it in GitHub Desktop.
Tiny declarative signals / event hooks for C++11
#pragma once
#include <functional>
template<typename... ArgsT>
struct EventHook;
template<typename... ArgsT>
struct Signal
{
EventHook<ArgsT...> *head;
// Disable copy constructors...
Signal(const Signal& x) = delete;
Signal& operator=(const Signal& x) = delete;
void operator()(ArgsT&&... args) const
{
auto it = head;
while( it != nullptr )
{
it->cb(std::forward<ArgsT>(args)...);
it = it->next;
}
}
};
template<typename... ArgsT>
struct EventHook
{
EventHook **head_ptr;
std::function<void(ArgsT...)> cb;
EventHook *next;
EventHook *prev {nullptr};
// Disable copy constructors...
EventHook(const EventHook& x) = delete;
EventHook& operator=(const EventHook& x) = delete;
EventHook( Signal<ArgsT...> & sig, decltype(cb) && cb )
: head_ptr(&sig.head),
cb(std::move(cb)),
next(*head_ptr)
{
assert( next->prev == nullptr );
next->prev = this;
*head_ptr = this;
}
~EventHook()
{
if( this->prev != nullptr )
{
this->prev->next = this->next;
}
if( this->next != nullptr )
{
this->next->prev = this->prev;
}
if( head_ptr != nullptr )
{
if( *head_ptr == this )
{
assert( this->prev == nullptr );
this->next;
}
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment