True, templatizing the entire Widget class would cause code bloat which is why 
one would be mad to do it.  It is possible to implement the template m/f I 
suggested without templatizing the whole widget class.  For example:

class Widget
{
..
    struct BaseData {
        virtual void call(Widget*) = 0;
    };

    template <class F>
    struct CbData : BaseData {
        F& f_;
        CbData(F& f) : f_(f) {}
        void call(Fl_Widget* w) {f_(w);}
    };

    BaseData* cb_functor;

public:
    template<class F>
    void callback(F& f) {
        cb_functor = new CbData<F>(f);
    }
};

To call the users function, Widget would use cb_functor->call(this).  Only the 
template code above would get instantiated if the user called the template 
callback m/f and I think you can see that this template code is tiny.

As I said, once you have this single m/f for setting up a callback to a functor 
you can then effectively call any function or m/f with any signature using 
binding.  Simple.

Mike.

>
> Other unrelated option:
> "bloated" widget class with templated calback functions.
>
> This obviously should not be a part of the fltk library but I leave this
> template as an example for the "reach callback" possibility with
> templated widget and special My_Callback functor class:
>
>
> ------------------------------------------------------
>
> template <typename WIDGET>
> class Fl_Callback_Widget: public WIDGET{
>
>   bool is_my_callback;
>
>   void delete_previous_callback(){
>     if(is_my_callback){
>        delete ((My_Callback *)user_data());
>        is_my_callback = 0;
>     }
>   }
>
> public:
>   template <typename T1, ....>
>   void callback(T1 t1, ...){
>     delete_previous_callback()
>     Fl_Widget::callback(&my_special_callback_function,
>                         new My_Callback(t1, ....));
>
>    ~Fl_Callback_Widget(){
>         delete_previous_callback();
>    }
>
>   // other temples for callback functions
>   // ie with different numbers of parameters
>   ...
>
>
>
>  // All possible constructors with all possible number of parameters:
>
>   Fl_Callback_Widget():WIDGET(), is_my_callback(0){}
>
>   template <typename T1>
>   Fl_Callback_Widget(T1 t1):WIDGET(t1), is_my_callback(0){}
>
>   template <typename T1, typename T2>
>   Fl_Callback_Widget(T1 t1, T2 t2):WIDGET(t1, t2), is_my_callback(0){}
>
>   template <typename T1, typename T2, typemname T3>
>   Fl_Callback_Widget(T1 t1,T2 t2,T3 t3):
>           WIDGET(t1,t2,t2), is_my_callback(0){}
>
>  // ... and so on to - say 7 parameters
>  //  to accomodate for all possible widget constructors
>
>
> }
>
> // Single special callback for My_Callback functors:
>
> void my_callback(Fl_Widget * w, void * data){
>   (My_Callback *)
> }
>
> --------------------------------------------------------------
>
> The advantage of this solution is tat it is an add-on (no changes to the
> library) and you can use this template like ANY other widget but you
> have this extra reach callback system:
>
> Fl_Callback_Widget<Fl_Browser> browser(x, y, w, h, "My browser");
> browser.callback(some_class,&Some_Class::method,argument_value_pointer);
>
> The disadvantage is bloat -  for each used widget class there is new
> specialization of the template class.
>
> R.

_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to