[Signals] trackable detection for user defined callabcks

Hi, Signals docs say: "Warning: User-defined function objects and function objects from other libraries (e.g., Boost.Function or Boost.Lambda) do not implement the required interfaces for trackable object detection, and will silently ignore any bound trackable objects. Future versions of the Boost libraries will address this limitation." My questions: 1) What is the required interface for user-defined callbacks? 2) Is it still true that it will be addressed in future versions of Boost.Function? Regards, Simon -- Szymon Gatner The Lordz Games Studio www.thelordzgamesstudio.com

"Warning: User-defined function objects and function objects from other libraries (e.g., Boost.Function or Boost.Lambda) do not implement the required interfaces for trackable object detection, and will silently ignore any bound trackable objects. Future versions of the Boost libraries will address this limitation."
My questions:
1) What is the required interface for user-defined callbacks?
Hehe it is: http://www.boost.org/doc/libs/1_47_0/doc/html/boost/signals/trackable.html
2) Is it still true that it will be addressed in future versions of Boost.Function?
You've got now Signals2, which allows using weak_ptr for tracking purposes.

1) What is the required interface for user-defined callbacks?
Hehe it is: http://www.boost.org/doc/libs/1_47_0/doc/html/boost/signals/trackable.html
Ah, so I should provide appropriate visit_each() overload for my callback type? Can't say I understand what it is suppose to do tho. Example for Boost.Function would be great ;)
2) Is it still true that it will be addressed in future versions of Boost.Function?
You've got now Signals2, which allows using weak_ptr for tracking purposes.
Signals2 requires objects to be managed by shared_ptr which imho is more
intrusive (in a sense of class design enforcement) than original Signals. My
objects are kept in ptr_ and intrusive containers and it is trivial to make
them trackable but impossible to make them being managed by shared_ptr.
Additionally, within specific sub-systems signal-slot connections are
single-threaded and using:
namespace bs2 = boost::signals2;
using bs2::keywords;
bs2::signal_type

Hehe it is: http://www.boost.org/doc/libs/1_47_0/doc/html/boost/signals/trackable.html
Ah, so I should provide appropriate visit_each() overload for my callback type? Can't say I understand what it is suppose to do tho. Example for Boost.Function would be great ;)
Signals2 requires objects to be managed by shared_ptr which imho is more intrusive (in a sense of class design enforcement) than original Signals. My objects are kept in ptr_ and intrusive containers and it is trivial to make
Sorry, I probably misunderstood you. I also don't quite understand what the documentation means by saying "User-defined function objects<...>do not implement the required interfaces for trackable object detection". Any user-defined object can inherit from signals::trackable and thus "implement the required interfaces". boost::function (and of course, std::function etc) really doesn't provide such a functionality as far as I know, and I'm not sure it's possible to add it externally. them trackable but impossible to make them being managed by shared_ptr. If your objects have to be managed by other types of smart-ptrs, you still can use weak_ptr for tracking: struct your_class { your_class() : track_(new int()) {} private: shared_ptr<void> track_; } ...now pass track_ for any tracking purposes. If you've got a single-threaded design it seems to be safe, doesn't it.
Additionally, within specific sub-systems signal-slot connections are single-threaded and using: namespace bs2 = boost::signals2; using bs2::keywords; bs2::signal_type
bs2::dummy_mutex >::type sig; instead of: signal sig; especially multiple times in single class definition is just horrible. Or am I missing some easy way to redefine default mutex?
Well... at least, you can typedef mutex_typebs2::dummy_mutex :).

Sorry, I probably misunderstood you. I also don't quite understand what the documentation means by saying "User-defined function objects<...>do not implement the required interfaces for trackable object detection". Any user-defined object can inherit from signals::trackable and thus "implement the required interfaces". boost::function (and of course, std::function etc) really doesn't provide such a functionality as far as I know, and I'm not sure it's possible to add it externally.
Yup, it is about something different. Mind that signal does not store
pointers to signalled objects directly. It stores slots which are bound
to such object. The way Signals are implemented this works correctly:
class Trackable : public signals::trackable
{
void foo() {}
}
signal
If your objects have to be managed by other types of smart-ptrs, you still can use weak_ptr for tracking: struct your_class { your_class() : track_(new int()) {} private: shared_ptr<void> track_; }
Yeah, that is what I just love about libraries designed in this way, to be able to use it, dummy shared_ptr member must be added to class definition even tho it does not actually share anything. Enforcing memory model is bad but what is worst in this design imho is that instead of just making new class trackable (implementation detail) with Signals2 tracking must be explicit at sig.connect() site, so what works with Signals1 is broken with Signals2: void Foo::func() { connectMe(bind(&Foo:func, this)); } void template <class Slot> void connectMe(Slot slot) { sig.connect(slot); // if sig is Signal1 signal automatic tracking will work if class Foo // is derived from trackable (as binders from bind() and recognized) // but there is no way of making original object trackable with Signals2 // as there is no shared_ptr to pass anymore }
Well... at least, you can typedef mutex_typebs2::dummy_mutex :).
And get 1 more line to write, no thanks ;) Cheers

On Friday, October 28, 2011, Szymon Gatner wrote:
Yeah, that is what I just love about libraries designed in this way, to be able to use it, dummy shared_ptr member must be added to class definition even tho it does not actually share anything. Enforcing memory model is bad but what is worst in this design imho is that instead of just making new class trackable (implementation detail) with Signals2 tracking must be explicit at sig.connect() site, so what works with Signals1 is broken with Signals2:
signals2 does provide a trackable base class that is used the same way as the trackable base class in the original library. Disconnection by base class cannot be made thread safe in the general case however, since the base class destructor does not run until after the derived class destructor has already run.

signals2 does provide a trackable base class that is used the same way as the trackable base class in the original library. Disconnection by base class cannot be made thread safe in the general case however, since the base class destructor does not run until after the derived class destructor has already run.
Then why would I use Signals2 in the first place? ;) I would just like to understand how to make custom callback type or just even Boost.Function in combination with trackable work with Signals. Cheers, Simon

On Friday, October 28, 2011, Szymon Gatner wrote:
Additionally, within specific sub-systems signal-slot connections are single-threaded and using:
namespace bs2 = boost::signals2; using bs2::keywords; bs2::signal_type
bs2::dummy_mutex >::type sig; instead of:
signal
sig; especially multiple times in single class definition is just horrible. Or am I missing some easy way to redefine default mutex?
Would it work to define your own signal metafunction, that sets the template parameters to defaults you like and only takes a Signature template? Example attached.
participants (3)
-
Frank Mori Hess
-
Igor R
-
Szymon Gatner