Connecting signal to destruction of an object - or - self-destructing handlers

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Connecting signal to destruction of an object - or - self-destructing handlers

Daniel Boles
How/can I receive an event when some object of my choice is destroyed, so that I can take appropriate action?

Here's an example I came up against lately. I should probably refactor the code so I don't need to do things this way... but it illustrates the question quite well. I have a ComboBox where, via some boring exposition, I want to put a signal_changed() handler on its StyleContext. However, that handler holds a reference to a row in the ComboBox's model. Therefore, I need to receive notification when that model dies (i.e. when all holders of RefPtrs release them), so that I can disconnect that signal_changed() handler and therefore stop it from trying to access a dead row.

Is sigc::trackable::add_destroy_notify_cb() an option here, or perhaps the only one? I didn't try it yet because it looks quite low-level and I thought I would check whether there's anything better higher up in the stack. I didn't find anything on a quick skim, though.

Alternatively, is there any way to have signal handlers disconnect themselves? This is something I have wanted several times but have had to resort to ugly hacks. (We obviously can't say 'assign this sigc::connection from this lambda, but also refer to the post-assignment connection in the lambda.)

Thanks in advance for any thoughts.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Connecting signal to destruction of an object - or - self-destructing handlers

Murray Cumming-5
On Tue, 2017-07-04 at 09:44 +0100, Daniel Boles wrote:

> How/can I receive an event when some object of my choice is
> destroyed, so that I can take appropriate action?
>
> Here's an example I came up against lately. I should probably
> refactor the code so I don't need to do things this way... but it
> illustrates the question quite well. I have a ComboBox where, via
> some boring exposition, I want to put a signal_changed() handler on
> its StyleContext. However, that handler holds a reference to a row in
> the ComboBox's model. Therefore, I need to receive notification when
> that model dies (i.e. when all holders of RefPtrs release them), so
> that I can disconnect that signal_changed() handler and therefore
> stop it from trying to access a dead row.
[snip]

This shouldn't generally happen. The sigc::trackable base class should
take care of this. Maybe it would be best to try to reduce this to a
simple test case.

--
Murray Cumming
[hidden email]
www.murrayc.com

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Fwd: Connecting signal to destruction of an object - or - self-destructing handlers

Daniel Boles

On 5 July 2017 at 12:49, Murray Cumming <[hidden email]> wrote:
On Tue, 2017-07-04 at 09:44 +0100, Daniel Boles wrote:
> How/can I receive an event when some object of my choice is
> destroyed, so that I can take appropriate action?
>
> Here's an example I came up against lately. I should probably
> refactor the code so I don't need to do things this way... but it
> illustrates the question quite well. I have a ComboBox where, via
> some boring exposition, I want to put a signal_changed() handler on
> its StyleContext. However, that handler holds a reference to a row in
> the ComboBox's model. Therefore, I need to receive notification when
> that model dies (i.e. when all holders of RefPtrs release them), so
> that I can disconnect that signal_changed() handler and therefore
> stop it from trying to access a dead row.
[snip]

This shouldn't generally happen. The sigc::trackable base class should
take care of this. Maybe it would be best to try to reduce this to a
simple test case.

From my limited understanding of trackable, the issue is probably that my handler was a lambda, not a sigc::mem_fun. I would prefer not to have to set the handler on an object, and be required to derive that object from sigc::trackable, but it sounds like there's not another way.

Anyway, I rewrote the whole thing so that it works differently, and now I don't really need this handler... I was just curious how it might be done. Still interested if you have any suggestions!




_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Fwd: Connecting signal to destruction of an object - or - self-destructing handlers

Kjell Ahlstedt-2
Den 2017-07-06 kl. 10:34, skrev Daniel Boles:

On 5 July 2017 at 12:49, Murray Cumming <[hidden email]> wrote:
On Tue, 2017-07-04 at 09:44 +0100, Daniel Boles wrote:
> How/can I receive an event when some object of my choice is
> destroyed, so that I can take appropriate action?
>
> Here's an example I came up against lately. I should probably
> refactor the code so I don't need to do things this way... but it
> illustrates the question quite well. I have a ComboBox where, via
> some boring exposition, I want to put a signal_changed() handler on
> its StyleContext. However, that handler holds a reference to a row in
> the ComboBox's model. Therefore, I need to receive notification when
> that model dies (i.e. when all holders of RefPtrs release them), so
> that I can disconnect that signal_changed() handler and therefore
> stop it from trying to access a dead row.
[snip]

This shouldn't generally happen. The sigc::trackable base class should
take care of this. Maybe it would be best to try to reduce this to a
simple test case.

From my limited understanding of trackable, the issue is probably that my handler was a lambda, not a sigc::mem_fun. I would prefer not to have to set the handler on an object, and be required to derive that object from sigc::trackable, but it sounds like there's not another way.

Anyway, I rewrote the whole thing so that it works differently, and now I don't really need this handler... I was just curious how it might be done. Still interested if you have any suggestions!


A weak pointer to the TreeModel could be an alternative. It would not call a function to inform you when the TreeModel is being deleted, but you can check if the TreeModel still exists before you access its row.
In gtkmm-3, use Glib::WeakRef, in gtkmm-4, where Glib::RefPtr is a std::shared_ptr, use std::weak_ptr.

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Fwd: Connecting signal to destruction of an object - or - self-destructing handlers

Kjell Ahlstedt-2
Den 2017-07-06 kl. 11:06, skrev Kjell Ahlstedt:
Den 2017-07-06 kl. 10:34, skrev Daniel Boles:

On 5 July 2017 at 12:49, Murray Cumming <[hidden email]> wrote:
On Tue, 2017-07-04 at 09:44 +0100, Daniel Boles wrote:
> How/can I receive an event when some object of my choice is
> destroyed, so that I can take appropriate action?
>
> Here's an example I came up against lately. I should probably
> refactor the code so I don't need to do things this way... but it
> illustrates the question quite well. I have a ComboBox where, via
> some boring exposition, I want to put a signal_changed() handler on
> its StyleContext. However, that handler holds a reference to a row in
> the ComboBox's model. Therefore, I need to receive notification when
> that model dies (i.e. when all holders of RefPtrs release them), so
> that I can disconnect that signal_changed() handler and therefore
> stop it from trying to access a dead row.
[snip]

This shouldn't generally happen. The sigc::trackable base class should
take care of this. Maybe it would be best to try to reduce this to a
simple test case.

From my limited understanding of trackable, the issue is probably that my handler was a lambda, not a sigc::mem_fun. I would prefer not to have to set the handler on an object, and be required to derive that object from sigc::trackable, but it sounds like there's not another way.

Anyway, I rewrote the whole thing so that it works differently, and now I don't really need this handler... I was just curious how it might be done. Still interested if you have any suggestions!


A weak pointer to the TreeModel could be an alternative. It would not call a function to inform you when the TreeModel is being deleted, but you can check if the TreeModel still exists before you access its row.
In gtkmm-3, use Glib::WeakRef, in gtkmm-4, where Glib::RefPtr is a std::shared_ptr, use std::weak_ptr.
I didn't think twice here. I should have.

Glib::WeakRef can be useful, but std::weak_ptr can't. And Glib::WeakRef has been removed from glibmm-2.54 (gtkmm-4). std::weak_ptr informs you if a Glib::RefPtr still exists, but a TreeModel can outlive all RefPtrs, pointing to it. The ComboBox (actually the underlying GtkComboBox) keeps a reference to the GtkTreeModel. That reference will keep both the GtkTreeModel and the wrapping Gtk::TreeModel alive until the ComboBox dies.

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Fwd: Connecting signal to destruction of an object - or - self-destructing handlers

Daniel Boles
Thanks for pondering anyway! I'm glad I came up with a better way to do this. :D It's more complex on the (S)CSS side, but avoids shenanigans with StyleContext in widget code.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Loading...