Last active
August 29, 2015 14:03
-
-
Save cjxgm/2bca34030ea9ecdd1054 to your computer and use it in GitHub Desktop.
a simple and clean implementation of a signal system in C++11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <functional> | |
#include <list> | |
// tue == std + 1 | |
namespace tue | |
{ | |
template <class ...Args> | |
struct Signal | |
{ | |
using Result = bool; | |
using Signature = Result(Args...); | |
using Callback = std::function<Signature>; | |
using Unlisten = std::function<void()>; | |
using List = std::list<Callback>; | |
Unlisten listen(Callback&& cb) | |
{ | |
auto it = callbacks.insert(callbacks.end(), std::move(cb)); | |
return [this, it]() { callbacks.erase(it); }; | |
} | |
void emit(Args ...args) | |
{ | |
for (auto& cb: callbacks) | |
if (cb(args...)) | |
break; | |
} | |
void operator()(Args ...args) { emit(args...); } | |
private: | |
List callbacks; | |
}; | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "signal.hh" | |
#include <iostream> | |
using namespace std; | |
tue::Signal<int> hello; // the callback/listener takes 1 int as argument and returns bool. | |
bool d_cb(int x) | |
{ | |
cerr << "called D " << x << endl; | |
return false; | |
} | |
struct E | |
{ | |
E(int id) : id{id} { cerr << "E{" << id << "}@" << this << "::(ctor)" << endl; } | |
~E() { cerr << "E{" << id << "}@" << this << "::(dtor)" << endl; } | |
E(const E& e) { id = e.id; cerr << "E{" << id << "}@" << this << "::(copy)" << endl; } | |
E( E&& e) { id = e.id; e.id = 0; cerr << "E{" << id << "}@" << this << "::(move)" << endl; } | |
bool operator()(int x) | |
{ | |
cerr << "called E " << x << endl; | |
return false; | |
} | |
private: | |
int id; | |
}; | |
int main() | |
{ | |
hello.listen([](int x) { | |
cerr << "called A " << x << endl; | |
return false; | |
}); | |
auto unlisten_b = hello.listen([](int x) { | |
cerr << "called B " << x << endl; | |
return true; | |
}); | |
hello.listen([](int x) { | |
cerr << "called C " << x << endl; | |
return false; | |
}); | |
hello(1); | |
cerr << endl; | |
unlisten_b(); | |
hello(2); | |
cerr << endl; | |
hello.listen(d_cb); | |
hello(3); | |
cerr << endl; | |
{ | |
E e_cb{1}; | |
hello.listen(std::move(e_cb)); | |
} | |
hello(4); | |
cerr << endl; | |
hello = decltype(hello){}; // reset the signal | |
hello(5); | |
cerr << endl; | |
hello.listen(d_cb); | |
hello(6); | |
cerr << endl; | |
hello.listen(E{2}); | |
hello(7); | |
cerr << endl; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
called A 1 | |
called B 1 | |
called A 2 | |
called C 2 | |
called A 3 | |
called C 3 | |
called D 3 | |
E{1}@0x7fff3a1f0218::(ctor) | |
E{1}@0x7fff3a1f01e8::(move) | |
E{1}@0x1105070::(move) | |
E{0}@0x7fff3a1f01e8::(dtor) | |
E{0}@0x7fff3a1f0218::(dtor) | |
called A 4 | |
called C 4 | |
called D 4 | |
called E 4 | |
E{1}@0x1105070::(dtor) | |
called D 6 | |
E{2}@0x7fff3a1f0188::(ctor) | |
E{2}@0x1105070::(move) | |
E{0}@0x7fff3a1f0188::(dtor) | |
called D 7 | |
called E 7 | |
E{2}@0x1105070::(dtor) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment