summaryrefslogtreecommitdiff
path: root/src/lib/eo
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-02-05 15:40:41 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-02-07 14:43:25 +0100
commit0f32bb90476703f81fd08800eda0a0d89321f80f (patch)
tree97f71bd6fedc72e0609e0e807527de0da4a54072 /src/lib/eo
parent0709bdea6f94149b6b319461edd27b7a0035552d (diff)
eo: here comes reflection API
this adds support in eo to generate a reflection API. To get the actaul reflection to the klass, the API efl_class_reflection_table_set needs to be called, the table in the end can be generated by eolian. Reflection API is inherited by the extended class. This means, if you have two reflection tables, first, the most upperst is called, then the next lower one is called. For now this API accepts NULL setter or getter, and will ignore them silently when they are called. fix T7681 Differential Revision: https://phab.enlightenment.org/D7879
Diffstat (limited to 'src/lib/eo')
-rw-r--r--src/lib/eo/Eo.h58
-rw-r--r--src/lib/eo/eo.c64
-rw-r--r--src/lib/eo/eo_private.h2
3 files changed, 121 insertions, 3 deletions
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 1406984964..d258a47df4 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -826,6 +826,40 @@ struct _Efl_Class_Description
826 void (*class_constructor)(Efl_Class *klass); /**< The constructor of the class. */ 826 void (*class_constructor)(Efl_Class *klass); /**< The constructor of the class. */
827 void (*class_destructor)(Efl_Class *klass); /**< The destructor of the class. */ 827 void (*class_destructor)(Efl_Class *klass); /**< The destructor of the class. */
828}; 828};
829/**
830 * Setter type which is used to set an #Eina_Value, this function should access one particular property field
831 */
832typedef void (*Efl_Object_Property_Reflection_Setter)(Eo *obj, Eina_Value value);
833
834/**
835 * Getter type which is used to get an #Eina_Value, this function should access one particular property field
836 */
837typedef Eina_Value (*Efl_Object_Property_Reflection_Getter)(Eo *obj);
838
839/**
840 * @struct _Efl_Object_Property_Reflection
841 *
842 * This structure holds one line of the reflection table.
843 * The two fields get and set might be NULL,
844 * the property_name is a normal c string containing the name of the property
845 * that the get and set function changes.
846 */
847typedef struct _Efl_Object_Property_Reflection{
848 const char *property_name; /**< The name of the property */
849 Efl_Object_Property_Reflection_Setter set; /**< The function used to set a generic #Eina_Value on this property of the object. */
850 Efl_Object_Property_Reflection_Getter get; /**< The function used to retrieve a generic #Eina_Value from this property of the object. */
851} Efl_Object_Property_Reflection;
852
853/**
854 * @struct _Efl_Object_Property_Reflection_Ops
855 *
856 * This structure holds the reflection table and the size of this table.
857 */
858typedef struct _Efl_Object_Property_Reflection_Ops
859{
860 const Efl_Object_Property_Reflection *table; /**< The reflection table. */
861 size_t count; /**< Number of table lines descriptions. */
862} Efl_Object_Property_Reflection_Ops;
829 863
830/** 864/**
831 * @typedef Efl_Class_Description 865 * @typedef Efl_Class_Description
@@ -860,10 +894,11 @@ EAPI const Efl_Class *efl_class_new(const Efl_Class_Description *desc, const Efl
860 * @return True on success, False otherwise. 894 * @return True on success, False otherwise.
861 * 895 *
862 * This should only be called from within the initializer function. 896 * This should only be called from within the initializer function.
863 * 897 * The reflection_table contains a getter and setter per property name. Which are called when either
898 * efl_property_reflection_set() or efl_property_reflection_get() is called.
864 * @see #EFL_DEFINE_CLASS 899 * @see #EFL_DEFINE_CLASS
865 */ 900 */
866EAPI Eina_Bool efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_ops, const Efl_Object_Ops *class_ops, const void *reflection_table); 901EAPI Eina_Bool efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_ops, const Efl_Object_Ops *class_ops, const Efl_Object_Property_Reflection_Ops *reflection_table);
867 902
868/** 903/**
869 * @brief Override Eo functions of this object. 904 * @brief Override Eo functions of this object.
@@ -1946,6 +1981,25 @@ EAPI Eina_Bool efl_manual_free(Eo *obj);
1946EAPI Eina_Bool efl_destructed_is(const Eo *obj); 1981EAPI Eina_Bool efl_destructed_is(const Eo *obj);
1947 1982
1948/** 1983/**
1984 * @brief Set the given #Eina_Value to the property with the specified \c property_name.
1985 * @param obj The object to set the property on
1986 * @param property_name The name of the property to modify.
1987 * @param value The value to set, the value passed here will be flushed by the function
1988 *
1989 */
1990EAPI void efl_property_reflection_set(Eo *obj, const char *property_name, Eina_Value value);
1991
1992/**
1993 * @brief Retrieve an #Eina_Value containing the current value of the property specified with \c property_name.
1994 * @param obj The object to set the property on
1995 * @param property_name The name of the property to get.
1996 *
1997 * @return The value that got returned by the actual property in form of a generic Eina_Value. The user of this API is owning the returned Value.
1998 */
1999EAPI Eina_Value efl_property_reflection_get(Eo *obj, const char *property_name);
2000
2001
2002/**
1949 * @addtogroup Efl_Class_Class Eo's Class class. 2003 * @addtogroup Efl_Class_Class Eo's Class class.
1950 * @{ 2004 * @{
1951 */ 2005 */
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 0d1ae5b64c..beed05914d 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -819,7 +819,7 @@ _eo_class_funcs_set(Eo_Vtable *vtable, const Efl_Object_Ops *ops, const _Efl_Cla
819} 819}
820 820
821EAPI Eina_Bool 821EAPI Eina_Bool
822efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_ops, const Efl_Object_Ops *class_ops, const void *reflection_table) 822efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_ops, const Efl_Object_Ops *class_ops, const Efl_Object_Property_Reflection_Ops *reflection_table)
823{ 823{
824 EO_CLASS_POINTER_GOTO(klass_id, klass, err_klass); 824 EO_CLASS_POINTER_GOTO(klass_id, klass, err_klass);
825 Efl_Object_Ops empty_ops = { 0 }; 825 Efl_Object_Ops empty_ops = { 0 };
@@ -832,6 +832,8 @@ efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_
832 832
833 if (!class_ops) class_ops = &empty_ops; 833 if (!class_ops) class_ops = &empty_ops;
834 834
835 klass->reflection = reflection_table;
836
835 klass->ops_count = object_ops->count + class_ops->count; 837 klass->ops_count = object_ops->count + class_ops->count;
836 838
837 klass->base_id = _eo_ops_last_id; 839 klass->base_id = _eo_ops_last_id;
@@ -3597,3 +3599,63 @@ static const Eina_Value_Type _EINA_VALUE_TYPE_OBJECT = {
3597}; 3599};
3598 3600
3599EOAPI const Eina_Value_Type *EINA_VALUE_TYPE_OBJECT = &_EINA_VALUE_TYPE_OBJECT; 3601EOAPI const Eina_Value_Type *EINA_VALUE_TYPE_OBJECT = &_EINA_VALUE_TYPE_OBJECT;
3602
3603static const Efl_Object_Property_Reflection*
3604_efl_class_reflection_find(const _Efl_Class *klass, const char *property_name)
3605{
3606 const _Efl_Class **klass_iter = klass->extensions;
3607 const Efl_Object_Property_Reflection_Ops *ref = klass->reflection;
3608 unsigned int i;
3609
3610 for (i = 0; ref && i < ref->count; ++i)
3611 {
3612 if (eina_streq(property_name, ref->table[i].property_name))
3613 return &ref->table[i];
3614 }
3615
3616 if (klass->parent)
3617 {
3618 const Efl_Object_Property_Reflection *ref;
3619
3620 ref = _efl_class_reflection_find(klass->parent, property_name);
3621 if (ref) return ref;
3622 }
3623
3624 for (; *klass_iter; klass_iter++)
3625 {
3626 return _efl_class_reflection_find(*klass_iter, property_name);
3627 }
3628
3629 return NULL;
3630}
3631
3632EAPI void
3633efl_property_reflection_set(Eo *obj_id, const char *property_name, Eina_Value value)
3634{
3635 EO_OBJ_POINTER_GOTO(obj_id, obj, end);
3636 const Efl_Object_Property_Reflection *reflection = _efl_class_reflection_find(obj->klass, property_name);
3637
3638 if (!reflection || !reflection->set) goto end;
3639
3640 reflection->set(obj_id, value);
3641 EO_OBJ_DONE(obj_id);
3642 return;
3643end:
3644 eina_value_flush(&value);
3645 EO_OBJ_DONE(obj_id);
3646}
3647
3648EAPI Eina_Value
3649efl_property_reflection_get(Eo *obj_id, const char *property_name)
3650{
3651 EO_OBJ_POINTER(obj_id, obj);
3652 const Efl_Object_Property_Reflection *reflection = _efl_class_reflection_find(obj->klass, property_name);
3653
3654 if (!reflection || !reflection->get) goto end;
3655
3656 return reflection->get(obj_id);
3657end:
3658 EO_OBJ_DONE(obj_id);
3659
3660 return EINA_VALUE_EMPTY;
3661}
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index 7145faaea2..7c7ae9e4a8 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -185,6 +185,8 @@ struct _Efl_Class
185 185
186 const _Efl_Class **mro; 186 const _Efl_Class **mro;
187 187
188 const Efl_Object_Property_Reflection_Ops *reflection;
189
188 /* cached object for faster allocation */ 190 /* cached object for faster allocation */
189 struct { 191 struct {
190 Eina_Trash *trash; 192 Eina_Trash *trash;