I actually like the recent simple system - otherwise the hunger always
grows and at some point somebody will want multiple callback, subcalls
etc. The system actually allows to build powerful "external" callback
system (see Fl_Signal extension in the baasar - shameless plug).

That said you have a valid point that widget class could be more
flexible. One thing I am missing in the widget class is possibility to
destruct user_data()  - ie by a simple "plugin" system which would
control lifespan of other objects. Two possible solution come to my mind:

1) An extra pointer to some plugin list within the widget.

2) Possibility to "destruct" user_data() when widget is destructed by an
extra call during destruction

I do not like the first solution too much (an extra data within widget,
existence of a special "plugin" class, ...) so lets elaborate on the
second possibility.

Lets have an extra bit like FL_DESTRUCTION_CALLBACK among the flags()
and two functions to assign callback:


1) Old-style callback:
----------------------
void Fl_Widget::callback(Fl_Callback * c, void *user_data = 0){
  destruct_user_data(); // check for the special user data dest.
  callback_ = c; user_data = user_data;
  clear_flag(FL_DESTRUCTION_CALLBACK);
}

2) New user_data-destructed callback:
------------------------------------
void Fl_Widget::destructed_callback(Fl_Callback* c, void* user_data=0){
  destruct_user_data();
  callback_ = c; user_data = user_data;
  set_flag(FL_DESTRUCTION_CALLBACK);
}

and within Fl_Widget destructor:

Fl_Widget::~Fl_Widget(){
    ...
    destruct_user_data()
}

// protected or private:
void Fl_Widget::destruct_user_data(){
  if(flags()&FL_DESTRUCTION_CALLBACK && callback_)
     callback_(0, user_data());
}




Now you see  that destruct_user_data(), called during widget
destruction, there is one last call to the callback function but -
unlike during normal call - this time with "null" as the widget
argument. This is logical because the widget can already be partially
destructed so there is not much use of it. It also allows callback
function to recognize that this is NOT normal call but the "destruction"
 and it should do something with the user data. Your callback can be then:

void my_callback(Fl_Widget * w, void * data){
  if(w){ // do normal call
      ...
      ...
  }else{ // last call during widget destruction, destructing user data!
     delete ((My_Callback_Structure *)data);
  }
}

The advantage of above solution is that it is simple, backward
compatible, does nor use any extra data within the widget but allows to
build powerful system above the existing callbacks and control the
destruction of user_data() by the widget.

R.







Mike wrote:
> Hi all,
> 
> I've just started looking at FLTK (like it lots already) and I have been 
> reading through the forums.
> Four years ago there was discussion about updating the callback mechanism to 
> use functors.  It seems to have died off because, obviously, it used 
> templates whose support was patchy in places at the time.  I think it is fair 
> to say this is no longer true.
> Are there any plans to replace the several overloaded "callback" methods with 
> a single:
> 
> template <typename F> void callback(F& f);
> 
> This single m/f could handle being passed pointer to function taking Widget* 
> (so is backwards compatible that far) as well as functors.  Using binding it 
> also handles calling functions and m/fs with any signature, which makes this 
> interface cleaner as well as more powerful.
> 
> Just thought it might be worth reigniting this discussion, now that templates 
> are widely supported.
> 
> Mike.
_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to