Skip to content

Instantly share code, notes, and snippets.

@conradjones
Created July 1, 2019 19:19
Show Gist options
  • Save conradjones/d4be9e415d61c6ee1a181e2816d07684 to your computer and use it in GitHub Desktop.
Save conradjones/d4be9e415d61c6ee1a181e2816d07684 to your computer and use it in GitHub Desktop.
#ifndef __AUDIOLIB_SIGNALS_SIGNAL_H
#define __AUDIOLIB_SIGNALS_SIGNAL_H
#include "audiolib/types/maps/vectormap.h"
#include <functional>
#include <iostream>
#include <vector>
namespace sig {
template <class Rp, class... ArgTypes>
class signal {
};
/********************************************************************************************/
// signal Class //
/********************************************************************************************/
template <class Rp, class... ArgTypes>
class signal<Rp(ArgTypes...)> {
/********************************************************************************************/
// CTOR / DTOR //
/********************************************************************************************/
public:
signal() = default;
signal(const signal&) = delete;
/********************************************************************************************/
// Public (Alias) Types //
/********************************************************************************************/
public:
using Handler = std::function<Rp(ArgTypes...)>;
/********************************************************************************************/
// Data //
/********************************************************************************************/
private:
audio::AutoVectorMap<size_t, Handler, signal<Rp(ArgTypes...)>> _handlers;
/********************************************************************************************/
// connection //
/********************************************************************************************/
public:
template <typename F>
size_t connect(F f)
{
return this->_handlers.add(Handler(f));
}
template <typename __THIS, typename __FUNC>
size_t connect(__THIS* pThis, __FUNC func)
{
return this->_handlers.add([pThis, func](ArgTypes... args) {
std::invoke(func, pThis, args...);
});
}
size_t connect(Handler func)
{
return this->_handlers.add(func);
}
void unConnect(size_t id)
{
this->_handlers.remove(id);
}
void operator()(ArgTypes... args)
{
for (auto& handler : this->_handlers) {
handler.second(args...);
}
}
void propagate(signal<Rp(ArgTypes...)>& receiver)
{
this->_handlers.add([&receiver](auto&&... args) { receiver(args...); });
}
template <typename T, typename Arg, typename... Args>
static void doPropagateValue(T& val, Arg&& arg, Args&&... args)
{
val = arg;
}
template <typename T>
void propagateValue(T& val)
{
this->_handlers.add([&val](auto&&... args) {
doPropagateValue(val, args...);
});
}
struct bind_obj {
private:
signal<Rp(ArgTypes...)>& _sig;
public:
bind_obj(signal<Rp(ArgTypes...)>& sig_)
: _sig(sig_)
{
}
void operator()(ArgTypes... args)
{
this->_sig(args...);
}
};
bind_obj bind()
{
return bind_obj(*this);
}
};
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment