WLink: implement the basic tracking functionality

This commit is contained in:
Fischlurch 2018-08-15 17:02:39 +02:00
parent c47e3d0210
commit 0c29bd7c92

View file

@ -27,6 +27,9 @@
** The is statefull, can be reconnected, and automatically transitions into disconnected ** The is statefull, can be reconnected, and automatically transitions into disconnected
** state when the target dies. ** state when the target dies.
** **
** @warning this class is not threadsafe, because lib SigC++ is not either,
** and it can only be used reliably from within the GUI thread.
**
** @see \ref WLink_test ** @see \ref WLink_test
** @see \ref NotificationHub (usage example) ** @see \ref NotificationHub (usage example)
** **
@ -56,6 +59,7 @@ namespace model {
/** /**
* Managed link to a `sigc::trackable` UI widget, without taking ownership. * Managed link to a `sigc::trackable` UI widget, without taking ownership.
* @warning _not_ threadsafe
*/ */
template<class TAR> template<class TAR>
class WLink class WLink
@ -70,16 +74,21 @@ namespace model {
public: public:
~WLink() ~WLink()
{ {
if (widget_)
disconnect (*widget_);
} }
WLink() WLink()
{ : widget_{nullptr}
{ }
}
explicit explicit
WLink(TAR& targetWidget) WLink(TAR& targetWidget)
: widget_{&targetWidget} : widget_{&targetWidget}
{ } {
connect (targetWidget);
}
////////////////////////////TODO copy operations
explicit explicit
operator bool() const operator bool() const
@ -110,6 +119,25 @@ namespace model {
throw lumiera::error::State ("zombie widget encountered" throw lumiera::error::State ("zombie widget encountered"
, LERR_(BOTTOM_VALUE)); , LERR_(BOTTOM_VALUE));
} }
void
connect (sigc::trackable& target)
{
target.add_destroy_notify_callback (&widget_
,[](void* p)
{
TAR* & widgetPtr = *static_cast<TAR**>(p);
ASSERT (widgetPtr);
widgetPtr = nullptr;
return p;
});
}
void
disconnect (sigc::trackable& target)
{
target.remove_destroy_notify_callback (&widget_);
}
}; };