On 12/05/2015 14:25, Emil Dotchevski wrote:
I realize that Boost has Signals library already, but I've implemented a non-intrusive one which approaches the problem differently, and I'm pretty sure that there is no overlap between the two. It turned out more generic than I originally anticipated, so I thought I'd ask if others would find it useful as well.
Specifically I was motivated by wanting to use Qt without MOCing. I asked the Qt community if that was possible which generated several rather annoyed negative responses. :) The issue is that while in Qt it's possible to use any function as a Slot, to define a new Qt signal for an existing Qt type one needs to derive from the Qt type, define the signal (as a member function) and do the MOC dance -- which I wanted to avoid.
The result is a small, non-intrusive signals/slots library that allows objects of any type to be used as signal emitters, e.g. one of the included examples shows how signals can be emitted by a Windows HWND object.
Documentation and source code released under the Boost license can be found here: http://www.revergestudios.com/boost-synapse/.
This looks interesting, though I've only looked at the docs so far. The incomplete struct return type seems a bit peculiar. I assume it was required for some implementation-based reason? It might be a blocker if you later do want to add support for signals with return values. The docs for connect seem to state that when either weak_ptr expires it is considered a disconnection but meta::disconnected is not called. If this is intended it seems a little confusing. Perhaps a different word should be used ("inactive", maybe?). It seems like a non-uniformity to have connect() and other methods take a weak_ptr<emitter> while emit() and emitter_connection_count() take a bare pointer. Looking at the header docs you do have an emit_weak() as well but maybe these should be the other way around? (I assume current emit() is a convenience so that you can emit(this, ...) without needing shared_from_this() or similar.) In the docs for translate(), I assume the Effects code: connect<OriginalSignal>(original_emitter,bind(&emit<TranslatedSignal>,_1,_2,...)) was intended to be this instead: connect<OriginalSignal>(original_emitter,bind(&emit<TranslatedSignal>,translated_emitter,_1,_2,...)) The logging system example doesn't seem to include a way to actually generate log messages, unless you're expecting callers to just emit(severity(n), string) directly, which seems like a leaking abstraction.