Em dom, 27 de ago de 2017 às 23:20, Jean-Philippe André <[email protected]>
escreveu:

> Hi Gustavo,
>
> 2017-08-28 0:18 GMT+09:00 Gustavo Sverzut Barbieri <[email protected]>:
>
> > Hi all,
> >
> > q66 did a nice work to implement function pointers in Eolian, when you
> > write this:
> >
>
> (Wasn't it Lauro Maura?)



Could be, assumed to be Daniel :-)

So thanks Lauro!



>
>    function Function_Name {
> >        params {
> >           a: int;
> >        }
> >        return: bool;
> >    }
> >
> > you can then use your method as:
> >
> >    method_name {
> >       params {
> >          cb: Function_Name
> >       }
> >    }
> >
> > Which results in:
> >
> >    my_class_method(o, func_data, func, free_func);
> >
> > Basically enforces the pattern we always use, which is good. But
> > keeping them explicitly as 3 pointers is a bit cumbersome.
> >
> > So my suggestion is to pack them in a structure, so it will become a
> > single parameter (as would be exposed in higher level languages):
> >
> >    typedef struct _Function_Name_Desc {
> >       Function_Name func;
> >       const void *data;
> >       Eina_Free_Cb free;
> >    } Function_Name_Desc;
> >
> >    my_class_method(o, func_desc);
> >
> > A simple macro can make it more usable:
> >
> >     #define FUNCTION_NAME(...) (Function_Name_Desc){__VA_ARGS}
> >
> >    my_class_method(o, FUNCTION_NAME(func));
> >    my_class_method(o, FUNCTION_NAME(func, func_data));
> >    my_class_method(o, FUNCTION_NAME(func, func_data, free));
> >
> > and also named parameters:
> >
> >    my_class_method(o, FUNCTION_NAME(.func = cb, .free = data_free));
> >
> > For method implementors it will be also simple, since we always have
> > to do something like:
> >
> >    struct _My_Class_Data {
> >       ...
> >       Function_Name func;
> >       const void *func_data;
> >       Eina_Free_Cb func_free;
> >       ...
> >    };
> >
> >    pd->func = func;
> >    pd->func_data = func_data;
> >    pd->func_free = func_free;
> >
> > would become a simple entry:
> >
> >    struct _My_Class_Data {
> >       ...
> >       Function_Name_Desc cb;
> >       ...
> >    };
> >
> >    pd->cb = func_desc;
> >
> >
> > And we could generate a caller macro:
> >
> >    #define FUNCTION_NAME_CALL(desc, ...) \
> >       do { \
> >          if ((desc)->func) (desc)->func((void *)(desc)->data, ##
> > __VA_ARGS); \
> >       } while (0)
> >
> >    #define FUNCTION_NAME_CALL_RET(desc, ret_storage ...) \
> >       do { \
> >          if ((desc)->func) ret_storage = (desc)->func((void
> > *)(desc)->data, ## __VA_ARGS); \
> >       } while (0)
> >
> >    #define FUNCTION_NAME_FREE(desc) \
> >       do { \
> >          if ((desc)->free) (desc)->free((void *)(desc)->data); \
> >          (desc)->func = NULL; \
> >          (desc)->data = NULL; \
> >          (desc)->free = NULL; \
> >       } while (0)
> >
> > Then I could use in my object code:
> >
> >
> >      _my_class_func_caller(Eo *o, _My_Class_Data *pd, int a) {
> >          Eina_Bool r;
> >
> >          FUNCTION_NAME_CALL_RET(&pd->cb, r, a);
> >          FUNCTION_NAME_FREE(&pd->cb); // won't be used anymore
> >      }
> >
> > What do you think?
> >
> >
> As I've introduced the first usage of function pointers in EO I kept
> thinking this needs to be standardized in a structure with proper macros.
> Otherwise I'm sure we will end up with too many places that forget to free
> the user data.


That's for sure


>
> In fact we need a macro like stringshare_replace, which frees the previous
> data.
>
> I am not a fan of the call macros though, very ugly (their only value is
> the NULL check).


Actually they keep the type name, so it's easy to grep/read

Something else we could look is at "bound method", something like when you
pass a method as callback in Python or use JavaScript bind(). Instead of
data and free function it's an object and efl_unref() and ref when it's
created.  I'm not sure if data would still be passed, when we did
efl_future_cb() to link newer future with objects we provide 3 functions
that do not use data as Eo*o is the first argument and it would be weird to
put it elsewhere.




>
> --
> Jean-Philippe André
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> enlightenment-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
>
-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to