|
|
Ah, sorry, my message were coincidendtal, but this has nothing to
do with Groups. This is purely a callback thing that is meant to
give callback users a chance to deallocate user data that they may
have allocated for just this widget.
Yes, I understood. That's why I concluded that we may want to have
both.
The Group thing is quite easy to resolve: we just need to make
Fl_Group::insert(), remove(), and clear() virtual.
Unfortunately not. Been there, "tried" that, but it can't work
because we have too many overloaded add(), remove() and clear() and
maybe also insert() methods with entirely unrelated semantics.
Making the existing Fl_Group:: methods virtual doesn't play together
with these conflicting methods. I thought about adding new virtual
methods with non-conflicting names instead but this looked too
convoluted. Maybe it could work somehow but I stopped investigating
and this is OT here anyway.
But now to explain this case. Assuming your app allocates and
deletes widgets dynamically, let's say you need more data in a
callback than just a single pointer. So you allocate a dataset
when allocating the widget, but you can't make sure that the
dataset is deleted whenever the widget is deleted by the system.
For example (not compilable code, grossly simplified):
struct
{
int x;
int y;
} CallbackData;
void button_cb(Fl_Button *w, void *u) {
CallbackData *d = (CallbackData*)u;
if (Fl::event()==FL_DELETING)
delete d;
else
printf("I got %d and %d\n", d->x, d->y);
}
myButton = new Fl_Button(...)
myButton->callback(button_cb, new CallbackData(42, 128) );
myButton->when(FL_WHEN_CHANGED|FL_WHEN_DELETING);
Good example. Thanks.
This needs just a few lines of code to be implemented:
in Fl_Widget at the top:
if (when() &
FL_WHEN_DELETING) {
int old_event = Fl::event();
Fl::event(FL_DELETING);
do_callback();
Fl::event(old_event);
}
plus the declaration of those constants and some Fluid
changes.
Where "in Fl_Widget" would this be implemented? I assume you mean in
~Fl_Widget(), i.e. in the destructor. Or did you mean the handle()
method? Anyway, assuming correct implementation:
+1
There's one remaining problem though, if I'm not missing anything.
Your example seems perfect, but I believe at the time the destructor
of Fl_Widget is called, the derived class would already be partially
destroyed. Hence we need to document clearly that the callback would
only be allowed to deallocate the related (user) data but not access
the widget, i.e. any parts of the derived class. Or whatever.
There is an alternative: just as in
Fl_Widget::label_copy(char*), we could add Fl_Widget::callback_data_copy(void*),
set a flag, and call free(_user_data)
when deleting, or call delete
_user_data, so it would be a set-and-forget with less
flexibility.
Fl_Widget::copy_label() does indeed make a copy of a string and the
previous owner of the string can free it immediately. Hence the name
`copy...`.
Fl_Widget::callback_data_copy(void*) can't make a copy of the data
(because we don't know its size). The only thing we can do is to
"transfer ownership" of existing data (and set a flag). Hence `callback_data_copy` would be a misnomer,
and the lack of flexibility makes me vote -1 for this in favor of
the original proposal above.
--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/b5cff114-7abf-7b93-0144-e4f478928151%40online.de.
[ Direct Link to Message ] | |
|
| |