
On Feb 6, 2007, at 1:49 PM, Timmo Stange wrote:
I have a few questions about your Signals implementation, which you could perhaps answer best:
The templated signalN::disconnect allows disconnection by "slot", which the docs say elsewhere is difficult to achieve, because of the problem to compare the target function objects. The Boost Function agrees with this, but mentions that Signals knows "a way around it". Now what the implementation seems to do is to simply call operator== on the target function objects. That frankly leaves me somewhat confused. I understand that it should work when the functions are reference wrapped (which will be always the case when the slot target is a signal itself). We could simply mimic the original implementation, but I sure would feel better if I understood what it is going on.
So, the issue with Function's operator== is that it isn't possible to compare two instances of boost::function via the operator==. However, one can compare a boost::function object with a different function object (say, std::plus<int>) using operator==. Signals only relies on the latter behavior, e.g., sig.disconnect(my_func_object); will compare the boost::function stored in each slot against my_func_object using operator==, and remove those that match.
Does storing the combiner in Any really help fighting code bloat as mentioned under "Type Erasure" in the docs? It is only used in the signal template. It's copied and invoked, the former by utilizing the any copy constructor which is templated (resulting in more code for the heap storage, not in less) and the latter by using unsafe_any_cast, which effectively gives you a pointer to the original type and the actual invocation should therefor result in the same code. I would prefer storing the combiner directly to avoid the any-related heap allocations, but I don't have access to a large variety of compilers to check the code size differences.
Storing the combining in an Any was a dumb idea :) Still, you will probably need to keep the combiner on the heap somehow, because if a slot deletes the signal object, you don't want to crash. This could happen in a GUI system, for example, in a "button pressed" event on a "cancel" button, which deletes the dialog holding the "cancel" button.
As a more general question, do you think that declaring trackable deprecated and only providing it for backwards-compatibility is a good solution?
If trackable is the wrong thing to do in an MT-context, then by all means go ahead and deprecate it. Cheers, Doug