Hi all,

q66 did a nice work to implement function pointers in Eolian, when you
write this:

   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?


-- 
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