On Tue, Sep 5, 2017 at 10:43 PM, Jean-Philippe André <j...@videolan.org> wrote:
> 2017-09-06 10:32 GMT+09:00 Gustavo Sverzut Barbieri <barbi...@gmail.com>:
>
>> On Tue, Sep 5, 2017 at 10:08 PM, Jean-Philippe André <j...@videolan.org>
>> wrote:
>> > Hi,
>> >
>> > 2017-09-05 21:57 GMT+09:00 Gustavo Sverzut Barbieri <barbi...@gmail.com
>> >:
>> >
>> >> With eolian one could declare a future using C++ template-like syntax:
>> >>
>> >>     future<int>
>> >>
>> >> That is, a future that provides (resolves to) an integer. With
>> >> Eina_Value, this will be an Eina_Value->type == EINA_VALUE_TYPE_INT.
>> >>
>> >> In some cases, when multiple values are needed, it would be written as:
>> >>
>> >>     future<int, string>
>> >>
>> >> That is, a future that provides both an integer and a string. In the
>> >> old representation one would only get a "void *value", and would need
>> >> to do its casts and hope for the best. With Eina_Value, this will be
>> >> an Eina_Value->type == EINA_VALUE_TYPE_STRUCT, with internal pointer
>> >> being an Eina_Value_Struct, that contains an Eina_Value_Struct_Desc
>> >> with the members, memory layout is like:
>> >>
>> >>     value = (Eina_Value) {
>> >>         .type = EINA_VALUE_TYPE_STRUCT,
>> >>         .value.ptr = &(Eina_Value_Struct){
>> >>            .desc = EINA_VALUE_STRUCT_DESC_MYSTRUCT,
>> >>            .memory = &mystruct,
>> >>         },
>> >>     };
>> >>
>> >> Easily accessible with:
>> >>
>> >>     eina_value_struct_get(value, "member_name", &ret);
>> >>
>> >> Or directly (check/get could be made single-line with a helper
>> function):
>> >>
>> >>    // safety first!
>> >>    if (eina_value_struct_desc_get(&value) ==  EINA_VALUE_STRUCT_DESC_
>> >> MYSTRUCT)
>> >>      {
>> >>         Eina_Value_Struct st;
>> >>         eina_value_get(&value, &st);
>> >>         My_Struct *mst = st.memory;
>> >>
>> >>         mst->member_name; // from here on, no more checks are required
>> >>      }
>> >>
>> >> My proposal is to extend eolian syntax to allow named parameters and
>> >> it would generate the structure, typedef and EINA_VALUE_STRUCT_DESC,
>> >> all exposed in .eo.h file. Example:
>> >>
>> >>     future<age: int, name: string>
>> >>
>> >> Generates: my_class.eo.h
>> >>
>> >>    typedef struct _My_Class_Future_Result_Age_Name {
>> >>        int age;
>> >>        char *name;
>> >>    } My_Class_Result_Age_Name;
>> >>
>> >>    EOAPI const Eina_Value_Struct_Desc
>> >> *EINA_VALUE_STRUCT_DESC_MY_CLASS_FUTURE_RESULT_AGE_NAME;
>> >>
>> >> Generates: my_class.eo.c
>> >>
>> >>    static /* not const! */ Eina_Value_Struct_Member
>> >> _EINA_VALUE_STRUCT_MEMBERS_MY_CLASS_FUTURE_RESULT_AGE_NAME[] = {
>> >>       {"age", NULL /* type placeholder */,
>> >> offsetof(My_Class_Result_Age_Name, age)},
>> >>       {"name", NULL /* type placeholder */,
>> >> offsetof(My_Class_Result_Age_Name, name)},
>> >>    };
>> >>
>> >>    static const Eina_Value_Struct_Desc
>> >> _EINA_VALUE_STRUCT_DESC_MY_CLASS_FUTURE_RESULT_AGE_NAME = {
>> >>       EINA_VALUE_STRUCT_DESC_VERSION,
>> >>       NULL, /* ops */
>> >>       _EINA_VALUE_STRUCT_DESC_MEMBERS_MY_CLASS_FUTURE_RESULT_AGE_NAME,
>> >>      EINA_C_ARRAY_LENGTH(_EINA_VALUE_STRUCT_MEMBERS_MY_CLASS_
>> >> FUTURE_RESULT_AGE_NAME),
>> >>       sizeof(My_Class_Result_Age_Name),
>> >>    };
>> >>
>> >>    EOAPI const Eina_Value_Struct_Desc
>> >> *EINA_VALUE_STRUCT_DESC_MY_CLASS_FUTURE_RESULT_AGE_NAME;
>> >>
>> >>    // inside class constructor using it:
>> >>    _class_constructor(...) {
>> >>       if (_EINA_VALUE_STRUCT_MEMBERS_MY_CLASS_FUTURE_RESULT_AGE_
>> >> NAME[0].type
>> >> == NULL)
>> >>         {
>> >>            _EINA_VALUE_STRUCT_MEMBERS_MY_CLASS_FUTURE_RESULT_AGE_NAME[
>> >> 0].type
>> >> = EINA_VALUE_TYPE_INT;
>> >>            _EINA_VALUE_STRUCT_MEMBERS_MY_CLASS_FUTURE_RESULT_AGE_NAME[
>> >> 1].type
>> >> = EINA_VALUE_TYPE_STRING;
>> >>        }
>> >>    }
>> >>
>> >> The constructor thing is because EINA_VALUE_TYPE_INT and
>> >> EINA_VALUE_TYPE_STRING are declared in other libraries, thus cannot be
>> >> resolved at compile-time.
>> >>
>> >> Another option is to ignore that from Eolian signature, not allowing
>> >> structs there -- one could use future<generic_value>. But as you can
>> >> see, to make proper use of structures one need to type a lot, which
>> >> could be easily automated by Eolian.
>> >>
>> >>
>> > Can't we just declare the struct in EO and use it inside the future<> ?
>> > Like:
>> >
>> > struct Future_Struct_Value {
>> >   age: int;
>> >   sex: bool;
>> > }
>> >
>> > class Abc {
>> >   methods {
>> >     future_do {
>> >       return: future<Future_Struct_Value>;
>> >     }
>> >   }
>> > }
>>
>> Could... everything else would be the same, except the name would be
>> explicitly defined. works for me.
>> <https://lists.sourceforge.net/lists/listinfo/enlightenment-devel>
>>
>
> Cool :)
> This even works today (to a certain extent, at least... no idea how much
> info the Eina_Value has about the struct).

you can define all structs composed of basic C types, Eina_List,
Eina_Inarray, Eina_Hash (with subtypes) and of course, recursive
structures.

Basically for a struct type you define "ops" (operations) on how to
create/release its backing memory, how to copy etc... and each member
as an array of name/offset/Eina_Value_Type. If no "ops" are provided,
malloc/free are used and each member's type->copy is called (ie: the
traditional copy of each member).

Eo provides EINA_VALUE_TYPE_OBJECT, which will do
efl_ref()/efl_unref()... and people can extend by creating their own
types, operations, etc.



-- 
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
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to