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
