summaryrefslogtreecommitdiff
path: root/src/lib/eo
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2019-07-11 14:53:19 -0700
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-07-17 21:57:53 +0200
commit9e6d3b44e62c341bda6a7f226b589673fcc9cc98 (patch)
treecdebedb508bb2488b1842f7b9e1f9a6e856fba11 /src/lib/eo
parentc0e7b1343c6407b040b2d137a675f91ff7574b8d (diff)
eo: add ability to register provider on the Eo object directly.
This should reduce the need for custom implementation of efl_object_provider_bind. It also enable the ability to register provider from user code on any Efl_Object. Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de> Differential Revision: https://phab.enlightenment.org/D9292
Diffstat (limited to 'src/lib/eo')
-rw-r--r--src/lib/eo/efl_object.eo16
-rw-r--r--src/lib/eo/eo_base_class.c104
2 files changed, 93 insertions, 27 deletions
diff --git a/src/lib/eo/efl_object.eo b/src/lib/eo/efl_object.eo
index 85cb664958..0b3c403a20 100644
--- a/src/lib/eo/efl_object.eo
+++ b/src/lib/eo/efl_object.eo
@@ -402,6 +402,22 @@ abstract Efl.Object
402 even if @.parent is not $null.]] 402 even if @.parent is not $null.]]
403 } 403 }
404 } 404 }
405 provider_register {
406 [[Will register a manager of a specific class to be answered by eo.provider_find.]]
407 params {
408 @in klass: const(Efl.Class); [[The class provided by the registered provider.]]
409 @in provider: const(Efl.Object); [[The provider for the newly registered class that has to provide that said Efl.Class.]]
410 }
411 return: bool; [[$true if successfully register, $false otherwise.]]
412 }
413 provider_unregister {
414 [[Will unregister a manager of a specific class that was previously registered and answered by eo.provider_find.]]
415 params {
416 @in klass: const(Efl.Class); [[The class provided by the provider to unregister for.]]
417 @in provider: const(Efl.Object); [[The provider for the registered class to unregister.]]
418 }
419 return: bool; [[$true if successfully unregistered, $false otherwise.]]
420 }
405 } 421 }
406 implements { 422 implements {
407 class.constructor; 423 class.constructor;
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index 62a1caf9a2..d9edf15a90 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -39,6 +39,7 @@ typedef struct
39 Eo *composite_parent; 39 Eo *composite_parent;
40 Eina_Inlist *generic_data; 40 Eina_Inlist *generic_data;
41 Eo ***wrefs; 41 Eo ***wrefs;
42 Eina_Hash *providers;
42} Efl_Object_Extension; 43} Efl_Object_Extension;
43 44
44struct _Efl_Object_Data 45struct _Efl_Object_Data
@@ -125,11 +126,46 @@ _efl_pending_futures_clear(Efl_Object_Data *pd)
125 } 126 }
126} 127}
127 128
129static inline void
130_efl_object_extension_free(Efl_Object_Extension *ext)
131{
132 eina_freeq_ptr_main_add(ext, free, sizeof(*ext));
133}
134
135static inline Efl_Object_Extension *
136_efl_object_extension_need(Efl_Object_Data *pd)
137{
138 if (!pd->ext) pd->ext = calloc(1, sizeof(Efl_Object_Extension));
139 return pd->ext;
140}
141
142static inline void
143_efl_object_extension_noneed(Efl_Object_Data *pd)
144{
145 Efl_Object_Extension *ext = pd->ext;
146 if ((!ext) ||
147 (ext->name) ||
148 (ext->comment) ||
149 (ext->generic_data) ||
150 (ext->wrefs) ||
151 (ext->composite_parent) ||
152 (ext->providers)) return;
153 _efl_object_extension_free(pd->ext);
154 pd->ext = NULL;
155}
156
128static void 157static void
129_efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd) 158_efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
130{ 159{
131 _efl_pending_futures_clear(pd); 160 _efl_pending_futures_clear(pd);
132 161
162 if (pd->ext && pd->ext->providers)
163 {
164 eina_hash_free(pd->ext->providers);
165 pd->ext->providers = NULL;
166 _efl_object_extension_noneed(pd);
167 }
168
133 EO_OBJ_POINTER_RETURN(obj_id, obj); 169 EO_OBJ_POINTER_RETURN(obj_id, obj);
134 170
135 // Finally invalidate itself if it wasn't done already 171 // Finally invalidate itself if it wasn't done already
@@ -185,33 +221,6 @@ _efl_invalidate(_Eo_Object *obj)
185 obj->invalidate = EINA_TRUE; 221 obj->invalidate = EINA_TRUE;
186} 222}
187 223
188static inline void
189_efl_object_extension_free(Efl_Object_Extension *ext)
190{
191 eina_freeq_ptr_main_add(ext, free, sizeof(*ext));
192}
193
194static inline Efl_Object_Extension *
195_efl_object_extension_need(Efl_Object_Data *pd)
196{
197 if (!pd->ext) pd->ext = calloc(1, sizeof(Efl_Object_Extension));
198 return pd->ext;
199}
200
201static inline void
202_efl_object_extension_noneed(Efl_Object_Data *pd)
203{
204 Efl_Object_Extension *ext = pd->ext;
205 if ((!ext) ||
206 (ext->name) ||
207 (ext->comment) ||
208 (ext->generic_data) ||
209 (ext->wrefs) ||
210 (ext->composite_parent)) return;
211 _efl_object_extension_free(pd->ext);
212 pd->ext = NULL;
213}
214
215static void _key_generic_cb_del(void *data, const Efl_Event *event); 224static void _key_generic_cb_del(void *data, const Efl_Event *event);
216 225
217static void 226static void
@@ -832,6 +841,7 @@ EOLIAN static Efl_Object *
832_efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *klass) 841_efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *klass)
833{ 842{
834 Eina_Bool invalidate; 843 Eina_Bool invalidate;
844 Efl_Object *r = NULL;
835 845
836 invalidate = _efl_object_invalidated_get((Eo*) obj, NULL); 846 invalidate = _efl_object_invalidated_get((Eo*) obj, NULL);
837 if (invalidate) 847 if (invalidate)
@@ -839,10 +849,50 @@ _efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *
839 ERR("Calling efl_provider_find(%p) after the object was invalidated.", obj); 849 ERR("Calling efl_provider_find(%p) after the object was invalidated.", obj);
840 return NULL; 850 return NULL;
841 } 851 }
852
853 if (efl_isa(obj, klass)) return (Eo *) obj;
854
855 if (pd->ext) r = eina_hash_find(pd->ext->providers, &klass);
856 if (r) return r;
857
842 if (pd->parent) return efl_provider_find(pd->parent, klass); 858 if (pd->parent) return efl_provider_find(pd->parent, klass);
843 return NULL; 859 return NULL;
844} 860}
845 861
862static Eina_Bool
863_efl_object_provider_register(Eo *obj EINA_UNUSED, Efl_Object_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
864{
865 // The passed object does not provide that said class.
866 if (!efl_isa(provider, klass)) return EINA_FALSE;
867
868 _efl_object_extension_need(pd);
869 if (!pd->ext) return EINA_FALSE;
870 if (!pd->ext->providers) pd->ext->providers = eina_hash_pointer_new(EINA_FREE_CB(efl_unref));
871
872 // Prevent double insertion for the same class
873 if (eina_hash_find(pd->ext->providers, &klass)) return EINA_FALSE;
874
875 // Note: I would prefer to use efl_xref here, but I can't figure a nice way to
876 // call efl_xunref on hash destruction.
877 return eina_hash_add(pd->ext->providers, &klass, efl_ref(provider));
878}
879
880static Eina_Bool
881_efl_object_provider_unregister(Eo *obj EINA_UNUSED, Efl_Object_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
882{
883 Eina_Bool r;
884
885 if (!pd->ext) return EINA_FALSE;
886 r = eina_hash_del(pd->ext->providers, &klass, provider);
887
888 if (eina_hash_population(pd->ext->providers) != 0) return r;
889 eina_hash_free(pd->ext->providers);
890 pd->ext->providers = NULL;
891 _efl_object_extension_noneed(pd);
892
893 return r;
894}
895
846/* Children accessor */ 896/* Children accessor */
847typedef struct _Eo_Children_Iterator Eo_Children_Iterator; 897typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
848struct _Eo_Children_Iterator 898struct _Eo_Children_Iterator