[gtkada] GtkAda signal handlers interface proposal

Dmitry A. Kazakov mailbox at dmitry-kazakov.de
Thu Apr 28 12:24:41 CEST 2016


On 28/04/2016 11:37, Emmanuel Briot wrote:
> Actually I considered means to prevent this sort of misuse. E.g. by having the handler object as a plain parameter rather than access-to-object. This construct does not make sense in my view, because the purpose is to have some existing (visible elsewhere) object passed to the handler callback. If the handler object can be that sort anonymous, the existing callback procedures do the job nicely
> Whether to pass an existing object or a new object is left to the user (the proposal does not force
> either), so we need to handle that properly.
We should not encourage memory leaks.
>> The handler interfaces will then be
>>
>>     type Clicked_Handler is interface and GObject_Interface;
>>
>> This will allow calling Ref/Unref or even conversion to GObject_Record (risking Constraint_Error at run-time). The user will not be able to use an arbitrary type as a handler's base. Only descendants of GObject_Record will be eligible or else he will be forced to implement reference counting operations.
> Right, that's forcing all handlers to be GObject compatible, which is not so attractive (there are
> other pure-Ada ways to have refcounted types, for instance using controlled types).
But this is compatible with GtkAda design. If you wanted controlled 
objects, then the first candidates would be GObject, Gtk_Widget and all 
other GtkAda's access types. They must have been controlled doing 
Ref/Unref in the first place. I understand that GtkAda started as rather 
thin bindings which made Gtk_Widget etc plain access type. It is 
probably much too late to fix. But then there is no need to worry about 
new types to be controlled either.
> Personally not a big fan of having all handlers be descendants of GObject (although admittedly this
> is fully compatible with having the widget themselves be the handlers. But then when a dialog contains
> multiple checkboxes, for instance, the handler indeed would have to be a big list of "if .. elsif" statements,
> which I don't like because that's not quite "object-oriented" enough.
>> The purpose is to have My_Widget_Record as a parameter. Handling automatic disconnection is not so interesting, however, having *_Handler a descendant of GObject_Interface will allow transparent disconnection handling if the handler gets prematurely destroyed.
> Can you explain "handling automatic disconnection" is not so interesting ?
Because widgets practically never handle signals outside the containment 
hierarchy and otherwise than child to parent. I had only 2-3 cases 
overall where widgets were unrelated. And this is easily handled using 
either explicit Ref/Unref or else a controlled reference-holder object, 
or in even more rare cases by a weak reference controlled object.
> To me, it is important that handlers be disconnected when the object is destroyed, and then memory freed
> appropriately.
And this is never an issue in my case. If there is a remote possibility 
that a signal will be delivered to a prematurely destroyed object, I see 
no way how something may get leaked. All objects are put into some 
containers which deal with their referencing/unreferencing. Anything 
else is bad design, in my view, it should be prevented from happening 
rather than dealt with at run time.
>>> I would have:
>>>
>>>       type My_Widget_Record is new Gtk_Button_Record with ...
>>>
>>>       type My_Click_Handler is new Clicked_Handler with null record;
>>>       overriding procedure On_Click (...)
>>>
>>>       Widget.Button1.On_Click (new My_Click_Handler)
>>>
>> This is a very specific case, which better be:
>>     type My_Widget_Record is new Gtk_Button_Record with private;
>>         
>>     type My_Click_Handler is new Clicked_Handler with null record;
>>     overriding procedure On_Click (...)
>>
>>     Handler : My_Click_Handler; -- Or placed in My_Widget_Record
>>
>>     Widget.Button1.On_Click (My_Click_Handler);
>>
>> Existing callback procedures do this better.
> To me, existing callbacks do all the examples that have been discussed so far better. If all we want
> is to pass a parent widget, this is already fully handled by the Slot argument, with no additional
> instances needed, and are not worth the extra development or the increase in size of libgtkada.
Not really, we don't want to be forced to type conversions when using 
public interfaces. Especially the conversions that may fail at run-time 
and crash whole application.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/gtkada/attachments/20160428/2527d983/attachment.html>


More information about the gtkada mailing list