Introduction
For any C++ developer who's used Qt, we've grown to love the Signals/Slots idiom it presents
for creating clean Observer code. However, it relied on the Qt Moc pre-compiler tool, which meant
any project that wanted to use this feature had to use follow along with the Qt idiom, which really
made Qt applications look potentially foreign despite being written in C++. In addition to this the
implementation wasn't type-safe (a.k.a. no compile-time type checking), and doesn't generalize to
any callable target (you have to extend QtObject and declare a slot using Qt's syntax, can only
return void).
Since then, there have been multiple implementations of Signals/Slots. Some notable ones are
listed below:
- Boost Signals.
Not thread safe, performance wasn't great, now deprecated in favor of Boost Signals2. Licensed
under the Boost Liscense.
- Boost Signals2.
Thread safe upgrade of Boost Signals. Others have complained about its performance, but my tests
seem to show it's at least decent.. Licensed under the Boost Liscense.
- Libsigc++. Supposedly
decently quick, but not thread safe. I think this is also a near-fully featured implementation
like Boost Signals/Signals2. Also licensed under LGPL, making use somewhat restricted.
- libtscb. A
thread safe fairly quick quick implementation. However, it skimps on features (I think it offers
similar features to Qt's implementation). Also licensed under LGPL.
- C++11-based Implementation. This is actually another blog which sought to
implement Signals/Slots using new features brought by C++11, namely variadic templates,
std::function, and possibly more. This is CC0 licensed (public domain). Probably one of the
fastest implementations I have seen, but is not thread-safe.
I was wondering if I could implement a more feature-full implementation like Boost Signals2
bet with better performance like libtscb. I'll be using some C++11 features like the last
implementation, notably atomics, std::function, and variadic templates. I'm also using Boost
shared_ptr/weak_ptr, Boost mutex, and Boost shared_ptr atomics. These libraries are being used
because currently the compiler I'm using doesn't have the standard variants implemented (Mingw w64
gcc-4.8.1).
For the most part, I was able to implement (or actually, can see a straight-forward implementation)
nearly all of the features provided by Boost Signals2. There are some semantic changes (notably the
interface for combiners is different), and I was unable to capture the O(log(n))
performance of inserting group-ordered slots. My implementation likely will have O(n) group insertion.