summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO-eo232
-rw-r--r--src/Makefile_Eo.am6
-rw-r--r--src/benchmarks/eo/class_simple.c2
-rw-r--r--src/bin/eolian/common_funcs.h2
-rw-r--r--src/bin/eolian/eo1_generator.c2
-rw-r--r--src/examples/ecore/ecore_audio_playback.c2
-rw-r--r--src/examples/eo/evas/evas_evas_obj.c2
-rw-r--r--src/examples/eo/evas/evas_evas_obj.h4
-rw-r--r--src/examples/eo/isa/eo_isa_simple.c2
-rw-r--r--src/examples/eo/simple/simple_simple.c2
-rw-r--r--src/lib/ecore/ecore_timer.c2
-rw-r--r--src/lib/ecore_audio/ecore_audio.eo2
-rw-r--r--src/lib/ecore_audio/ecore_audio_in_tone.eo6
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj.h2
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_in.c22
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c2
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_in_tone.c8
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_in_tone.h2
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out.c10
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_pulse.c54
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c16
-rw-r--r--src/lib/ecore_audio/ecore_audio_private.h2
-rw-r--r--src/lib/edje/edje_edit.c2
-rw-r--r--src/lib/edje/edje_multisense.c2
-rw-r--r--src/lib/edje/edje_program.c4
-rw-r--r--src/lib/edje/edje_smart.c6
-rw-r--r--src/lib/eo/Eo.h553
-rw-r--r--src/lib/eo/eo.c935
-rw-r--r--src/lib/eo/eo_base.eo10
-rw-r--r--src/lib/eo/eo_base_class.c412
-rw-r--r--src/lib/eo/eo_class_class.c4
-rw-r--r--src/lib/eo/eo_private.h15
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c4
-rw-r--r--src/lib/evas/canvas/evas_data.c6
-rw-r--r--src/lib/evas/canvas/evas_events.c7
-rw-r--r--src/lib/evas/canvas/evas_object_box.c26
-rw-r--r--src/lib/evas/canvas/evas_object_image.c14
-rw-r--r--src/lib/evas/canvas/evas_object_line.c4
-rw-r--r--src/lib/evas/canvas/evas_object_main.c28
-rw-r--r--src/lib/evas/canvas/evas_object_polygon.c4
-rw-r--r--src/lib/evas/canvas/evas_object_rectangle.c4
-rw-r--r--src/lib/evas/canvas/evas_object_smart.c6
-rw-r--r--src/lib/evas/canvas/evas_object_text.c8
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c16
-rw-r--r--src/lib/evas/canvas/evas_object_textgrid.c6
-rw-r--r--src/lib/evas/canvas/evas_out.c8
-rw-r--r--src/lib/evas/canvas/evas_render.c2
-rw-r--r--src/lib/evas/canvas/evas_render2.c2
-rw-r--r--src/lib/evas/filters/evas_filter.c2
-rw-r--r--src/tests/ecore/ecore_test_ecore_audio.c196
-rw-r--r--src/tests/eo/access/access_inherit.c26
-rw-r--r--src/tests/eo/access/access_inherit.h11
-rw-r--r--src/tests/eo/access/access_simple.c31
-rw-r--r--src/tests/eo/access/access_simple.h11
-rw-r--r--src/tests/eo/composite_objects/composite_objects_comp.c39
-rw-r--r--src/tests/eo/composite_objects/composite_objects_main.c8
-rw-r--r--src/tests/eo/composite_objects/composite_objects_simple.c43
-rw-r--r--src/tests/eo/composite_objects/composite_objects_simple.h14
-rw-r--r--src/tests/eo/constructors/constructors_main.c8
-rw-r--r--src/tests/eo/constructors/constructors_mixin.c40
-rw-r--r--src/tests/eo/constructors/constructors_mixin.h11
-rw-r--r--src/tests/eo/constructors/constructors_simple.c63
-rw-r--r--src/tests/eo/constructors/constructors_simple.h23
-rw-r--r--src/tests/eo/constructors/constructors_simple2.c22
-rw-r--r--src/tests/eo/constructors/constructors_simple3.c20
-rw-r--r--src/tests/eo/constructors/constructors_simple4.c2
-rw-r--r--src/tests/eo/constructors/constructors_simple5.c20
-rw-r--r--src/tests/eo/constructors/constructors_simple6.c22
-rw-r--r--src/tests/eo/constructors/constructors_simple7.c21
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit.c2
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit2.c70
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit2.h14
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit3.c22
-rw-r--r--src/tests/eo/function_overrides/function_overrides_main.c31
-rw-r--r--src/tests/eo/function_overrides/function_overrides_simple.c75
-rw-r--r--src/tests/eo/function_overrides/function_overrides_simple.h20
-rw-r--r--src/tests/eo/interface/interface_interface.c12
-rw-r--r--src/tests/eo/interface/interface_interface.h17
-rw-r--r--src/tests/eo/interface/interface_interface2.c12
-rw-r--r--src/tests/eo/interface/interface_interface2.h17
-rw-r--r--src/tests/eo/interface/interface_main.c8
-rw-r--r--src/tests/eo/interface/interface_simple.c78
-rw-r--r--src/tests/eo/interface/interface_simple.h43
-rw-r--r--src/tests/eo/mixin/mixin_inherit.c30
-rw-r--r--src/tests/eo/mixin/mixin_main.c9
-rw-r--r--src/tests/eo/mixin/mixin_mixin.c46
-rw-r--r--src/tests/eo/mixin/mixin_mixin.h17
-rw-r--r--src/tests/eo/mixin/mixin_mixin2.c40
-rw-r--r--src/tests/eo/mixin/mixin_mixin3.c40
-rw-r--r--src/tests/eo/mixin/mixin_mixin4.c2
-rw-r--r--src/tests/eo/mixin/mixin_simple.c52
-rw-r--r--src/tests/eo/mixin/mixin_simple.h43
-rw-r--r--src/tests/eo/signals/signals_main.c46
-rw-r--r--src/tests/eo/signals/signals_simple.c38
-rw-r--r--src/tests/eo/signals/signals_simple.h16
-rw-r--r--src/tests/eo/suite/eo_error_msgs.c53
-rw-r--r--src/tests/eo/suite/eo_error_msgs.h30
-rw-r--r--src/tests/eo/suite/eo_suite.c2
-rw-r--r--src/tests/eo/suite/eo_suite.h2
-rw-r--r--src/tests/eo/suite/eo_test_call_errors.c73
-rw-r--r--src/tests/eo/suite/eo_test_class_errors.c353
-rw-r--r--src/tests/eo/suite/eo_test_class_simple.c88
-rw-r--r--src/tests/eo/suite/eo_test_class_simple.h21
-rw-r--r--src/tests/eo/suite/eo_test_general.c299
-rw-r--r--src/tests/eo/suite/eo_test_threaded_calls.c130
-rw-r--r--src/tests/eo/suite/eo_test_value.c2
106 files changed, 2300 insertions, 2458 deletions
diff --git a/TODO-eo2 b/TODO-eo2
new file mode 100644
index 0000000000..8c62c83d4e
--- /dev/null
+++ b/TODO-eo2
@@ -0,0 +1,32 @@
1
2- eo_composite_attach
3 maybe check that the class of comp_obj is part of parent extensions
4
5- Eo2_Call_Stack
6 grow/shrink
7 stack push and pop functions
8 per thread stack
9
10- Remove the memset in do_end? Waste of cpu...
11
12- cleanup EO2_VERSION specific code in eo.c and eo_private.c
13
14- Move the Op_Descs to be set using a function inside the class_constructor
15 check if it works ASIS on windows
16 if it does, do nothing
17
18- Rediscuss the whole attribute cleanup thing. I'm not sure we want that as everything breaks if that isn't there. Embedded old gcc?
19
20- function name from pointer
21 dladdr backtrace ??
22
23- Get rid of some of the EO2_VOID_FUNC_BODY?
24
25- Add line number to errors (like in eo1...)
26
27- A bit annoying that we don't get type checks on the callbacks, fix that? That's really dangerous!
28
29- Get all the optimisations cedric has been doing to Eo1? I think that's where the children thing got lost...
30 - Make sure all the improvements have been migrated...
31
32- Fix all the FIXME
diff --git a/src/Makefile_Eo.am b/src/Makefile_Eo.am
index 230ff9e794..7c2b093b38 100644
--- a/src/Makefile_Eo.am
+++ b/src/Makefile_Eo.am
@@ -10,8 +10,8 @@ lib_eo_libeo_la_SOURCES = \
10lib/eo/eo.c \ 10lib/eo/eo.c \
11lib/eo/eo_ptr_indirection.c \ 11lib/eo/eo_ptr_indirection.c \
12lib/eo/eo_ptr_indirection.h \ 12lib/eo/eo_ptr_indirection.h \
13lib/eo/eo_class_class.c \
14lib/eo/eo_base_class.c \ 13lib/eo/eo_base_class.c \
14lib/eo/eo_class_class.c \
15lib/eo/eo_private.h 15lib/eo/eo_private.h
16 16
17lib_eo_libeo_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EO_CFLAGS@ 17lib_eo_libeo_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EO_CFLAGS@
@@ -91,9 +91,13 @@ tests/eo/suite/eo_test_class_simple.c \
91tests/eo/suite/eo_test_class_simple.h \ 91tests/eo/suite/eo_test_class_simple.h \
92tests/eo/suite/eo_suite.c \ 92tests/eo/suite/eo_suite.c \
93tests/eo/suite/eo_suite.h \ 93tests/eo/suite/eo_suite.h \
94tests/eo/suite/eo_error_msgs.h \
95tests/eo/suite/eo_error_msgs.c \
94tests/eo/suite/eo_test_class_errors.c \ 96tests/eo/suite/eo_test_class_errors.c \
97tests/eo/suite/eo_test_call_errors.c \
95tests/eo/suite/eo_test_general.c \ 98tests/eo/suite/eo_test_general.c \
96tests/eo/suite/eo_test_value.c \ 99tests/eo/suite/eo_test_value.c \
100tests/eo/suite/eo_test_threaded_calls.c \
97tests/eo/suite/eo_test_init.c 101tests/eo/suite/eo_test_init.c
98tests_eo_eo_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ 102tests_eo_eo_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
99-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eo\" \ 103-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eo\" \
diff --git a/src/benchmarks/eo/class_simple.c b/src/benchmarks/eo/class_simple.c
index 2e8dc3f621..05d025ec97 100644
--- a/src/benchmarks/eo/class_simple.c
+++ b/src/benchmarks/eo/class_simple.c
@@ -46,5 +46,5 @@ static const Eo_Class_Description class_desc = {
46 NULL 46 NULL
47}; 47};
48 48
49EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL) 49EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_CLASS, NULL)
50 50
diff --git a/src/bin/eolian/common_funcs.h b/src/bin/eolian/common_funcs.h
index c8a800eefb..ace92e6fca 100644
--- a/src/bin/eolian/common_funcs.h
+++ b/src/bin/eolian/common_funcs.h
@@ -3,7 +3,7 @@
3 3
4#include <Eina.h> 4#include <Eina.h>
5 5
6//#define EO 6#define EO
7 7
8extern int _eolian_gen_log_dom; 8extern int _eolian_gen_log_dom;
9 9
diff --git a/src/bin/eolian/eo1_generator.c b/src/bin/eolian/eo1_generator.c
index 669125b1cf..ce4ffd6f37 100644
--- a/src/bin/eolian/eo1_generator.c
+++ b/src/bin/eolian/eo1_generator.c
@@ -167,7 +167,6 @@ eo1_fundef_generate(const char *classname, Eolian_Function func, Eolian_Function
167 167
168 char *fsuffix = ""; 168 char *fsuffix = "";
169 rettype = eolian_function_return_type_get(func, ftype); 169 rettype = eolian_function_return_type_get(func, ftype);
170 if (rettype && !strcmp(rettype, "void")) rettype = NULL;
171 if (ftype == EOLIAN_PROP_GET) 170 if (ftype == EOLIAN_PROP_GET)
172 { 171 {
173 fsuffix = "_get"; 172 fsuffix = "_get";
@@ -468,7 +467,6 @@ eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Fun
468 Eina_Strbuf *full_params = eina_strbuf_new(); /* variables types + names */ 467 Eina_Strbuf *full_params = eina_strbuf_new(); /* variables types + names */
469 468
470 rettype = eolian_function_return_type_get(funcid, ftype); 469 rettype = eolian_function_return_type_get(funcid, ftype);
471 if (rettype && !strcmp(rettype, "void")) rettype = NULL;
472 retname = "ret"; 470 retname = "ret";
473 if (ftype == EOLIAN_PROP_GET) 471 if (ftype == EOLIAN_PROP_GET)
474 { 472 {
diff --git a/src/examples/ecore/ecore_audio_playback.c b/src/examples/ecore/ecore_audio_playback.c
index 6c93fd565a..56bfa070f9 100644
--- a/src/examples/ecore/ecore_audio_playback.c
+++ b/src/examples/ecore/ecore_audio_playback.c
@@ -266,7 +266,7 @@ main(int argc, const char *argv[])
266 { 266 {
267 if (!strncmp(val, "freq=", 5)) { 267 if (!strncmp(val, "freq=", 5)) {
268 freq = atoi(&val[5]); 268 freq = atoi(&val[5]);
269 eo_do(in, eo_base_data_set(ECORE_AUDIO_ATTR_TONE_FREQ, &freq, NULL)); 269 eo_do(in, eo_key_data_set(ECORE_AUDIO_ATTR_TONE_FREQ, &freq, NULL));
270 } else if (!strncmp(val, "duration=", 9)) { 270 } else if (!strncmp(val, "duration=", 9)) {
271 eo_do(in, ecore_audio_obj_in_length_set(atof(&val[9]))); 271 eo_do(in, ecore_audio_obj_in_length_set(atof(&val[9])));
272 } 272 }
diff --git a/src/examples/eo/evas/evas_evas_obj.c b/src/examples/eo/evas/evas_evas_obj.c
index 01f48a544b..768d3d4ea6 100644
--- a/src/examples/eo/evas/evas_evas_obj.c
+++ b/src/examples/eo/evas/evas_evas_obj.c
@@ -143,4 +143,4 @@ static const Eo_Class_Description class_desc = {
143 NULL 143 NULL
144}; 144};
145 145
146EO_DEFINE_CLASS(evas_object_class_get, &class_desc, EO_BASE_CLASS, NULL) 146EO_DEFINE_CLASS(evas_object_class_get, &class_desc, EO_CLASS, NULL)
diff --git a/src/examples/eo/evas/evas_evas_obj.h b/src/examples/eo/evas/evas_evas_obj.h
index 7aa761c648..cda796023d 100644
--- a/src/examples/eo/evas/evas_evas_obj.h
+++ b/src/examples/eo/evas/evas_evas_obj.h
@@ -76,7 +76,7 @@ static inline Evas_Object *
76eo_evas_object_get(const Eo *obj) 76eo_evas_object_get(const Eo *obj)
77{ 77{
78 void *data; 78 void *data;
79 eo_do((Eo *) obj, eo_base_data_get(EXEVAS_OBJ_STR, &data)); 79 eo_do((Eo *) obj, eo_key_data_get(EXEVAS_OBJ_STR, &data));
80 return data; 80 return data;
81} 81}
82 82
@@ -84,7 +84,7 @@ eo_evas_object_get(const Eo *obj)
84static inline void 84static inline void
85eo_evas_object_set(Eo *obj, Evas_Object *evas_obj) 85eo_evas_object_set(Eo *obj, Evas_Object *evas_obj)
86{ 86{
87 eo_do(obj, eo_base_data_set(EXEVAS_OBJ_STR, evas_obj, NULL)); 87 eo_do(obj, eo_key_data_set(EXEVAS_OBJ_STR, evas_obj, NULL));
88} 88}
89 89
90#endif 90#endif
diff --git a/src/examples/eo/isa/eo_isa_simple.c b/src/examples/eo/isa/eo_isa_simple.c
index 789c5f4711..67f47fd5f9 100644
--- a/src/examples/eo/isa/eo_isa_simple.c
+++ b/src/examples/eo/isa/eo_isa_simple.c
@@ -75,4 +75,4 @@ static const Eo_Class_Description class_desc = {
75 NULL 75 NULL
76}; 76};
77 77
78EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, INTERFACE_CLASS, MIXIN_CLASS, NULL); 78EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_CLASS, INTERFACE_CLASS, MIXIN_CLASS, NULL);
diff --git a/src/examples/eo/simple/simple_simple.c b/src/examples/eo/simple/simple_simple.c
index a172bce3fc..42eb1f75b2 100644
--- a/src/examples/eo/simple/simple_simple.c
+++ b/src/examples/eo/simple/simple_simple.c
@@ -75,4 +75,4 @@ static const Eo_Class_Description class_desc = {
75 NULL 75 NULL
76}; 76};
77 77
78EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, INTERFACE_CLASS, MIXIN_CLASS, NULL); 78EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_CLASS, INTERFACE_CLASS, MIXIN_CLASS, NULL);
diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c
index cbd87eae1a..2de040edd0 100644
--- a/src/lib/ecore/ecore_timer.c
+++ b/src/lib/ecore/ecore_timer.c
@@ -431,7 +431,7 @@ ecore_timer_freeze_get(Ecore_Timer *timer)
431{ 431{
432 int r = 0; 432 int r = 0;
433 433
434 eo_do(timer, eo_event_freeze_get(&r)); 434 eo_do(timer, r = eo_event_freeze_get());
435 return !!r; 435 return !!r;
436} 436}
437 437
diff --git a/src/lib/ecore_audio/ecore_audio.eo b/src/lib/ecore_audio/ecore_audio.eo
index b5dcf99b33..ace7e801b6 100644
--- a/src/lib/ecore_audio/ecore_audio.eo
+++ b/src/lib/ecore_audio/ecore_audio.eo
@@ -110,7 +110,7 @@ class Ecore_Audio (Eo_Base)
110 params { 110 params {
111 Ecore_Audio_Vio *vio; /*The @ref Ecore_Audio_Vio struct with the function callbacks*/ 111 Ecore_Audio_Vio *vio; /*The @ref Ecore_Audio_Vio struct with the function callbacks*/
112 void *data; /*User data to pass to the VIO functions*/ 112 void *data; /*User data to pass to the VIO functions*/
113 eo_base_data_free_func free_func; /*This function takes care to clean up @ref data when he VIO is destroyed. NULL means do nothing.*/ 113 eo_key_data_free_func free_func; /*This function takes care to clean up @ref data when he VIO is destroyed. NULL means do nothing.*/
114 } 114 }
115 } 115 }
116 } 116 }
diff --git a/src/lib/ecore_audio/ecore_audio_in_tone.eo b/src/lib/ecore_audio/ecore_audio_in_tone.eo
index 6b3e489368..d0970519b8 100644
--- a/src/lib/ecore_audio/ecore_audio_in_tone.eo
+++ b/src/lib/ecore_audio/ecore_audio_in_tone.eo
@@ -3,10 +3,10 @@ class Ecore_Audio_In_Tone (Ecore_Audio_In)
3 eo_prefix: ecore_audio_obj_in_tone; 3 eo_prefix: ecore_audio_obj_in_tone;
4 implements { 4 implements {
5 Eo_Base::constructor; 5 Eo_Base::constructor;
6 Eo_Base::data_set; 6 Eo_Base::key_data_set;
7 Eo_Base::data_get; 7 Eo_Base::key_data_get;
8 Ecore_Audio_In::length::set; 8 Ecore_Audio_In::length::set;
9 Ecore_Audio_In::seek; 9 Ecore_Audio_In::seek;
10 Ecore_Audio_In::read_internal; 10 Ecore_Audio_In::read_internal;
11 } 11 }
12} \ No newline at end of file 12}
diff --git a/src/lib/ecore_audio/ecore_audio_obj.h b/src/lib/ecore_audio/ecore_audio_obj.h
index b473a55f11..153a638292 100644
--- a/src/lib/ecore_audio/ecore_audio_obj.h
+++ b/src/lib/ecore_audio/ecore_audio_obj.h
@@ -175,7 +175,7 @@ enum Ecore_Audio_Obj_Sub_Ids
175 * @param[in] free_func This function takes care to clean up @ref data when 175 * @param[in] free_func This function takes care to clean up @ref data when
176 * the VIO is destroyed. NULL means do nothing. 176 * the VIO is destroyed. NULL means do nothing.
177 */ 177 */
178#define ecore_audio_obj_vio_set(vio, data, free_func) ECORE_AUDIO_OBJ_ID(ECORE_AUDIO_OBJ_SUB_ID_VIO_SET), EO_TYPECHECK(Ecore_Audio_Vio *, vio), EO_TYPECHECK(void *, data), EO_TYPECHECK(eo_base_data_free_func, free_func) 178#define ecore_audio_obj_vio_set(vio, data, free_func) ECORE_AUDIO_OBJ_ID(ECORE_AUDIO_OBJ_SUB_ID_VIO_SET), EO_TYPECHECK(Ecore_Audio_Vio *, vio), EO_TYPECHECK(void *, data), EO_TYPECHECK(eo_key_data_free_func, free_func)
179 179
180#endif 180#endif
181/** 181/**
diff --git a/src/lib/ecore_audio/ecore_audio_obj_in.c b/src/lib/ecore_audio/ecore_audio_obj_in.c
index f77374f551..970e2adba3 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_in.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_in.c
@@ -27,7 +27,7 @@ _ecore_audio_in_speed_set(Eo *eo_obj EINA_UNUSED, Ecore_Audio_Input *obj, double
27 27
28 obj->speed = speed; 28 obj->speed = speed;
29 29
30 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_SAMPLERATE_CHANGED, NULL, NULL)); 30 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_SAMPLERATE_CHANGED, NULL));
31} 31}
32 32
33EOLIAN static double 33EOLIAN static double
@@ -41,7 +41,7 @@ _ecore_audio_in_samplerate_set(Eo *eo_obj EINA_UNUSED, Ecore_Audio_Input *obj, i
41{ 41{
42 obj->samplerate = samplerate; 42 obj->samplerate = samplerate;
43 43
44 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_SAMPLERATE_CHANGED, NULL, NULL)); 44 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_SAMPLERATE_CHANGED, NULL));
45} 45}
46 46
47EOLIAN static int 47EOLIAN static int
@@ -88,8 +88,8 @@ _ecore_audio_in_remaining_get(Eo *eo_obj, Ecore_Audio_Input *obj)
88{ 88{
89 if (!obj->seekable) return -1; 89 if (!obj->seekable) return -1;
90 else { 90 else {
91 double ret; 91 double ret = 0.0;
92 eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_CUR, &ret)); 92 eo_do(eo_obj, ret = ecore_audio_obj_in_seek(0, SEEK_CUR));
93 return obj->length - ret; 93 return obj->length - ret;
94 } 94 }
95} 95}
@@ -104,14 +104,14 @@ _ecore_audio_in_read(Eo *eo_obj, Ecore_Audio_Input *obj, void *buf, size_t len)
104 memset(buf, 0, len); 104 memset(buf, 0, len);
105 len_read = len; 105 len_read = len;
106 } else { 106 } else {
107 eo_do(eo_obj, ecore_audio_obj_in_read_internal(buf, len, &len_read)); 107 eo_do(eo_obj, len_read = ecore_audio_obj_in_read_internal(buf, len));
108 if (len_read == 0) { 108 if (len_read == 0) {
109 if (!obj->looped || !obj->seekable) { 109 if (!obj->looped || !obj->seekable) {
110 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_STOPPED, NULL, NULL)); 110 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_STOPPED, NULL));
111 } else { 111 } else {
112 eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_SET, NULL)); 112 eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_SET));
113 eo_do(eo_obj, ecore_audio_obj_in_read_internal(buf, len, &len_read)); 113 eo_do(eo_obj, len_read = ecore_audio_obj_in_read_internal(buf, len));
114 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_LOOPED, NULL, NULL)); 114 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_IN_EVENT_IN_LOOPED, NULL));
115 } 115 }
116 } 116 }
117 117
@@ -149,7 +149,7 @@ static void _free_vio(Ecore_Audio_Object *ea_obj)
149} 149}
150 150
151EOLIAN static void 151EOLIAN static void
152_ecore_audio_in_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_Input *obj, Ecore_Audio_Vio *vio, void *data, eo_base_data_free_func free_func) 152_ecore_audio_in_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_Input *obj, Ecore_Audio_Vio *vio, void *data, eo_key_data_free_func free_func)
153{ 153{
154 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 154 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
155 155
@@ -182,7 +182,7 @@ EOLIAN static void
182_ecore_audio_in_eo_base_destructor(Eo *eo_obj, Ecore_Audio_Input *obj) 182_ecore_audio_in_eo_base_destructor(Eo *eo_obj, Ecore_Audio_Input *obj)
183{ 183{
184 if(obj->output) 184 if(obj->output)
185 eo_do(obj->output, ecore_audio_obj_out_input_detach(eo_obj, NULL)); 185 eo_do(obj->output, ecore_audio_obj_out_input_detach(eo_obj));
186 186
187 eo_do_super(eo_obj, MY_CLASS, eo_destructor()); 187 eo_do_super(eo_obj, MY_CLASS, eo_destructor());
188} 188}
diff --git a/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c b/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c
index d18908da79..6860f9dd5a 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c
@@ -142,7 +142,7 @@ static void _free_vio(Ecore_Audio_Object *ea_obj)
142} 142}
143 143
144EOLIAN static void 144EOLIAN static void
145_ecore_audio_in_sndfile_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_In_Sndfile_Data *obj, Ecore_Audio_Vio *vio, void *data, eo_base_data_free_func free_func) 145_ecore_audio_in_sndfile_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_In_Sndfile_Data *obj, Ecore_Audio_Vio *vio, void *data, eo_key_data_free_func free_func)
146{ 146{
147 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 147 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
148 Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_IN_CLASS); 148 Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_IN_CLASS);
diff --git a/src/lib/ecore_audio/ecore_audio_obj_in_tone.c b/src/lib/ecore_audio/ecore_audio_obj_in_tone.c
index 60f634881f..749772f401 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_in_tone.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_in_tone.c
@@ -83,26 +83,26 @@ _ecore_audio_in_tone_ecore_audio_in_length_set(Eo *eo_obj, Ecore_Audio_In_Tone_D
83} 83}
84 84
85EOLIAN static void 85EOLIAN static void
86_ecore_audio_in_tone_eo_base_data_set(Eo *eo_obj, Ecore_Audio_In_Tone_Data *obj, const char *key, const void *val, eo_base_data_free_func func) 86_ecore_audio_in_tone_eo_base_key_data_set(Eo *eo_obj, Ecore_Audio_In_Tone_Data *obj, const char *key, const void *val, eo_key_data_free_func func)
87{ 87{
88 if (!key) return; 88 if (!key) return;
89 89
90 if (!strcmp(key, ECORE_AUDIO_ATTR_TONE_FREQ)) { 90 if (!strcmp(key, ECORE_AUDIO_ATTR_TONE_FREQ)) {
91 obj->freq = *(int *)val; 91 obj->freq = *(int *)val;
92 } else { 92 } else {
93 eo_do_super(eo_obj, MY_CLASS, eo_base_data_set(key, val, func)); 93 eo_do_super(eo_obj, MY_CLASS, eo_key_data_set(key, val, func));
94 } 94 }
95 95
96} 96}
97 97
98EOLIAN static void* 98EOLIAN static void*
99_ecore_audio_in_tone_eo_base_data_get(Eo *eo_obj, Ecore_Audio_In_Tone_Data *obj, const char *key) 99_ecore_audio_in_tone_eo_base_key_data_get(Eo *eo_obj, Ecore_Audio_In_Tone_Data *obj, const char *key)
100{ 100{
101 if (!strcmp(key, ECORE_AUDIO_ATTR_TONE_FREQ)) { 101 if (!strcmp(key, ECORE_AUDIO_ATTR_TONE_FREQ)) {
102 return (void *) (intptr_t) obj->freq; 102 return (void *) (intptr_t) obj->freq;
103 } else { 103 } else {
104 void *ret = NULL; 104 void *ret = NULL;
105 eo_do_super(eo_obj, MY_CLASS, eo_base_data_get(key, &ret)); 105 eo_do_super(eo_obj, MY_CLASS, ret = eo_key_data_get(key));
106 return ret; 106 return ret;
107 } 107 }
108} 108}
diff --git a/src/lib/ecore_audio/ecore_audio_obj_in_tone.h b/src/lib/ecore_audio/ecore_audio_obj_in_tone.h
index 6bfd505a28..738f49a55a 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_in_tone.h
+++ b/src/lib/ecore_audio/ecore_audio_obj_in_tone.h
@@ -37,7 +37,7 @@ extern "C"
37/** 37/**
38 * @brief The frequency of the tone in Hz 38 * @brief The frequency of the tone in Hz
39 * 39 *
40 * Set with @ref eo_base_data_set() 40 * Set with @ref eo_key_data_set()
41 */ 41 */
42#define ECORE_AUDIO_ATTR_TONE_FREQ "ecore_audio_freq" 42#define ECORE_AUDIO_ATTR_TONE_FREQ "ecore_audio_freq"
43 43
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out.c b/src/lib/ecore_audio/ecore_audio_obj_out.c
index 40d16004e9..495e05c701 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out.c
@@ -25,7 +25,7 @@ static Eina_Bool _write_cb(void *data)
25 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_OUT_CLASS); 25 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_OUT_CLASS);
26 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 26 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
27 27
28 ssize_t written, bread; 28 ssize_t written, bread = 0;
29 float buf[1024]; 29 float buf[1024];
30 30
31 if (!ea_obj->vio || !ea_obj->vio->vio->write) 31 if (!ea_obj->vio || !ea_obj->vio->vio->write)
@@ -34,7 +34,7 @@ static Eina_Bool _write_cb(void *data)
34 /* FIXME: Multiple inputs */ 34 /* FIXME: Multiple inputs */
35 in = eina_list_data_get(out_obj->inputs); 35 in = eina_list_data_get(out_obj->inputs);
36 36
37 eo_do(in, ecore_audio_obj_in_read(buf, 4*1024, &bread)); 37 eo_do(in, bread = ecore_audio_obj_in_read(buf, 4*1024));
38 38
39 if (bread == 0) { 39 if (bread == 0) {
40 ea_obj->paused = EINA_TRUE; 40 ea_obj->paused = EINA_TRUE;
@@ -61,7 +61,7 @@ _ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Output *obj, Eo *input)
61 if (in->output == eo_obj) 61 if (in->output == eo_obj)
62 return EINA_FALSE; 62 return EINA_FALSE;
63 63
64 if (in->output) eo_do(in->output, ecore_audio_obj_out_input_detach(input, NULL)); 64 if (in->output) eo_do(in->output, ecore_audio_obj_out_input_detach(input));
65 in->output = eo_obj; 65 in->output = eo_obj;
66 66
67 /* TODO: Send event */ 67 /* TODO: Send event */
@@ -113,7 +113,7 @@ static void _free_vio(Ecore_Audio_Object *ea_obj)
113} 113}
114 114
115EOLIAN static void 115EOLIAN static void
116_ecore_audio_out_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_Output *_pd EINA_UNUSED, Ecore_Audio_Vio *vio, void *data, eo_base_data_free_func free_func) 116_ecore_audio_out_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_Output *_pd EINA_UNUSED, Ecore_Audio_Vio *vio, void *data, eo_key_data_free_func free_func)
117{ 117{
118 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 118 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
119 119
@@ -144,7 +144,7 @@ _ecore_audio_out_eo_base_destructor(Eo *eo_obj, Ecore_Audio_Output *obj)
144 Eo *in; 144 Eo *in;
145 145
146 EINA_LIST_FOREACH_SAFE(obj->inputs, cur, tmp, in) { 146 EINA_LIST_FOREACH_SAFE(obj->inputs, cur, tmp, in) {
147 eo_do(eo_obj, ecore_audio_obj_out_input_detach(in, NULL)); 147 eo_do(eo_obj, ecore_audio_obj_out_input_detach(in));
148 } 148 }
149 149
150 eo_do_super(eo_obj, MY_CLASS, eo_destructor()); 150 eo_do_super(eo_obj, MY_CLASS, eo_destructor());
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
index 8e7fc6d900..d958d2153b 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
@@ -46,7 +46,7 @@ EOLIAN static void
46_ecore_audio_out_pulse_ecore_audio_volume_set(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED, double volume) 46_ecore_audio_out_pulse_ecore_audio_volume_set(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED, double volume)
47{ 47{
48 Eo *in; 48 Eo *in;
49 pa_stream *stream; 49 pa_stream *stream = NULL;
50 Eina_List *input; 50 Eina_List *input;
51 uint32_t idx; 51 uint32_t idx;
52 pa_cvolume pa_volume; 52 pa_cvolume pa_volume;
@@ -60,7 +60,7 @@ _ecore_audio_out_pulse_ecore_audio_volume_set(Eo *eo_obj, Ecore_Audio_Out_Pulse_
60 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_volume_set(volume)); 60 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_volume_set(volume));
61 61
62 EINA_LIST_FOREACH(out_obj->inputs, input, in) { 62 EINA_LIST_FOREACH(out_obj->inputs, input, in) {
63 eo_do(in, eo_base_data_get("pulse_data", (void **)&stream)); 63 eo_do(in, stream = eo_key_data_get("pulse_data"));
64 idx = pa_stream_get_index(stream); 64 idx = pa_stream_get_index(stream);
65 pa_operation_unref(pa_context_set_sink_input_volume(class_vars.context, idx, &pa_volume, NULL, NULL)); 65 pa_operation_unref(pa_context_set_sink_input_volume(class_vars.context, idx, &pa_volume, NULL, NULL));
66 } 66 }
@@ -72,12 +72,12 @@ static void _write_cb(pa_stream *stream, size_t len, void *data)
72 Eo *in = data; 72 Eo *in = data;
73 73
74 void *buf; 74 void *buf;
75 ssize_t bread; 75 ssize_t bread = 0;
76 size_t wlen = len; 76 size_t wlen = len;
77 77
78 pa_stream_begin_write(stream, &buf, &wlen); 78 pa_stream_begin_write(stream, &buf, &wlen);
79 79
80 eo_do(in, ecore_audio_obj_in_read(buf, wlen, &bread)); 80 eo_do(in, bread = ecore_audio_obj_in_read(buf, wlen));
81 81
82 pa_stream_write(stream, buf, bread, NULL, 0, PA_SEEK_RELATIVE); 82 pa_stream_write(stream, buf, bread, NULL, 0, PA_SEEK_RELATIVE);
83 if (bread < (int)len) 83 if (bread < (int)len)
@@ -88,14 +88,14 @@ static void _write_cb(pa_stream *stream, size_t len, void *data)
88 88
89static Eina_Bool _update_samplerate_cb(void *data EINA_UNUSED, Eo *eo_obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) 89static Eina_Bool _update_samplerate_cb(void *data EINA_UNUSED, Eo *eo_obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
90{ 90{
91 pa_stream *stream; 91 pa_stream *stream = NULL;
92 int samplerate; 92 int samplerate = 0;
93 double speed; 93 double speed = 0;
94 94
95 eo_do(eo_obj, ecore_audio_obj_in_samplerate_get(&samplerate)); 95 eo_do(eo_obj, samplerate = ecore_audio_obj_in_samplerate_get());
96 eo_do(eo_obj, ecore_audio_obj_in_speed_get(&speed)); 96 eo_do(eo_obj, speed = ecore_audio_obj_in_speed_get());
97 97
98 eo_do(eo_obj, eo_base_data_get("pulse_data", (void **)&stream)); 98 eo_do(eo_obj, stream = eo_key_data_get("pulse_data"));
99 99
100 pa_operation_unref(pa_stream_update_sample_rate(stream, samplerate * speed, NULL, NULL)); 100 pa_operation_unref(pa_stream_update_sample_rate(stream, samplerate * speed, NULL, NULL));
101 101
@@ -104,35 +104,35 @@ static Eina_Bool _update_samplerate_cb(void *data EINA_UNUSED, Eo *eo_obj, const
104 104
105static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in) 105static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
106{ 106{
107 const char *name; 107 const char *name = NULL;
108 pa_sample_spec ss; 108 pa_sample_spec ss;
109 double speed; 109 double speed = 0;
110 pa_stream *stream; 110 pa_stream *stream;
111 Eina_Bool ret; 111 Eina_Bool ret = EINA_FALSE;
112 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 112 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
113 113
114 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_attach(in, &ret)); 114 eo_do_super(eo_obj, MY_CLASS, ret = ecore_audio_obj_out_input_attach(in));
115 if (!ret) 115 if (!ret)
116 return EINA_FALSE; 116 return EINA_FALSE;
117 117
118 ss.format = PA_SAMPLE_FLOAT32LE; 118 ss.format = PA_SAMPLE_FLOAT32LE;
119 eo_do(in, ecore_audio_obj_in_samplerate_get((int *)&ss.rate)); 119 eo_do(in, ss.rate = ecore_audio_obj_in_samplerate_get());
120 eo_do(in, ecore_audio_obj_in_speed_get(&speed)); 120 eo_do(in, speed = ecore_audio_obj_in_speed_get());
121 eo_do(in, ecore_audio_obj_in_channels_get((int *)&ss.channels)); 121 eo_do(in, ss.channels = ecore_audio_obj_in_channels_get());
122 eo_do(in, ecore_audio_obj_name_get(&name)); 122 eo_do(in, name = ecore_audio_obj_name_get());
123 123
124 ss.rate = ss.rate * speed; 124 ss.rate = ss.rate * speed;
125 125
126 stream = pa_stream_new(class_vars.context, name, &ss, NULL); 126 stream = pa_stream_new(class_vars.context, name, &ss, NULL);
127 if (!stream) { 127 if (!stream) {
128 ERR("Could not create stream"); 128 ERR("Could not create stream");
129 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in, NULL)); 129 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in));
130 return EINA_FALSE; 130 return EINA_FALSE;
131 } 131 }
132 132
133 eo_do(in, eo_event_callback_add(ECORE_AUDIO_IN_EVENT_IN_SAMPLERATE_CHANGED, _update_samplerate_cb, eo_obj)); 133 eo_do(in, eo_event_callback_add(ECORE_AUDIO_IN_EVENT_IN_SAMPLERATE_CHANGED, _update_samplerate_cb, eo_obj));
134 134
135 eo_do(in, eo_base_data_set("pulse_data", stream, NULL)); 135 eo_do(in, eo_key_data_set("pulse_data", stream, NULL));
136 136
137 137
138 pa_stream_set_write_callback(stream, _write_cb, in); 138 pa_stream_set_write_callback(stream, _write_cb, in);
@@ -178,14 +178,14 @@ static void _drain_cb(pa_stream *stream, int success EINA_UNUSED, void *data EIN
178EOLIAN static Eina_Bool 178EOLIAN static Eina_Bool
179_ecore_audio_out_pulse_ecore_audio_out_input_detach(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED, Eo *in) 179_ecore_audio_out_pulse_ecore_audio_out_input_detach(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED, Eo *in)
180{ 180{
181 pa_stream *stream; 181 pa_stream *stream = NULL;
182 Eina_Bool ret2; 182 Eina_Bool ret2 = EINA_FALSE;
183 183
184 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in, &ret2)); 184 eo_do_super(eo_obj, MY_CLASS, ret2 = ecore_audio_obj_out_input_detach(in));
185 if (!ret2) 185 if (!ret2)
186 return EINA_FALSE; 186 return EINA_FALSE;
187 187
188 eo_do(in, eo_base_data_get("pulse_data", (void **)&stream)); 188 eo_do(in, stream = eo_key_data_get("pulse_data"));
189 189
190 pa_stream_set_write_callback(stream, NULL, NULL); 190 pa_stream_set_write_callback(stream, NULL, NULL);
191 pa_operation_unref(pa_stream_drain(stream, _drain_cb, NULL)); 191 pa_operation_unref(pa_stream_drain(stream, _drain_cb, NULL));
@@ -210,12 +210,12 @@ static void _state_cb(pa_context *context, void *data EINA_UNUSED)
210 if (state == PA_CONTEXT_READY) { 210 if (state == PA_CONTEXT_READY) {
211 DBG("PA context ready."); 211 DBG("PA context ready.");
212 EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { 212 EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) {
213 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_READY, NULL, NULL)); 213 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_READY, NULL));
214 } 214 }
215 } else if ((state == PA_CONTEXT_FAILED) || (state == PA_CONTEXT_TERMINATED)) { 215 } else if ((state == PA_CONTEXT_FAILED) || (state == PA_CONTEXT_TERMINATED)) {
216 DBG("PA context fail."); 216 DBG("PA context fail.");
217 EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { 217 EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) {
218 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_FAIL, NULL, NULL)); 218 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_FAIL, NULL));
219 } 219 }
220 } else { 220 } else {
221 DBG("Connection state %i", state); 221 DBG("Connection state %i", state);
@@ -241,7 +241,7 @@ static void _state_job(void *data EINA_UNUSED)
241 } 241 }
242 // the callback here can delete things in the list.. 242 // the callback here can delete things in the list..
243 EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { 243 EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) {
244 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_FAIL, NULL, NULL)); 244 eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_FAIL, NULL));
245 } 245 }
246 // now unref everything safely 246 // now unref everything safely
247 EINA_LIST_FOREACH_SAFE(class_vars.outputs, out, tmp, eo_obj) { 247 EINA_LIST_FOREACH_SAFE(class_vars.outputs, out, tmp, eo_obj) {
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c b/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c
index d1ca3b5263..5e0e02f061 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c
@@ -37,13 +37,13 @@ static Eina_Bool _write_cb(void *data)
37 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_OUT_CLASS); 37 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_OUT_CLASS);
38 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 38 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
39 39
40 ssize_t written, bread; 40 ssize_t written, bread = 0;
41 float buf[1024]; 41 float buf[1024];
42 42
43 /* TODO: Support mixing of multiple inputs */ 43 /* TODO: Support mixing of multiple inputs */
44 in = eina_list_data_get(out_obj->inputs); 44 in = eina_list_data_get(out_obj->inputs);
45 45
46 eo_do(in, ecore_audio_obj_in_read(buf, 4*1024, &bread)); 46 eo_do(in, bread = ecore_audio_obj_in_read(buf, 4*1024));
47 47
48 if (bread == 0) { 48 if (bread == 0) {
49 sf_write_sync(obj->handle); 49 sf_write_sync(obj->handle);
@@ -64,21 +64,21 @@ _ecore_audio_out_sndfile_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Ou
64{ 64{
65 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS); 65 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
66 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_OUT_CLASS); 66 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OBJ_OUT_CLASS);
67 Eina_Bool ret2; 67 Eina_Bool ret2 = EINA_FALSE;
68 68
69 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_attach(in, &ret2)); 69 eo_do_super(eo_obj, MY_CLASS, ret2 = ecore_audio_obj_out_input_attach(in));
70 if (!ret2) 70 if (!ret2)
71 return EINA_FALSE; 71 return EINA_FALSE;
72 72
73 eo_do(in, ecore_audio_obj_in_samplerate_get(&obj->sfinfo.samplerate)); 73 eo_do(in, obj->sfinfo.samplerate = ecore_audio_obj_in_samplerate_get());
74 eo_do(in, ecore_audio_obj_in_channels_get(&obj->sfinfo.channels)); 74 eo_do(in, obj->sfinfo.channels = ecore_audio_obj_in_channels_get());
75 75
76 obj->handle = sf_open(ea_obj->source, SFM_WRITE, &obj->sfinfo); 76 obj->handle = sf_open(ea_obj->source, SFM_WRITE, &obj->sfinfo);
77 77
78 if (!obj->handle) { 78 if (!obj->handle) {
79 eina_stringshare_del(ea_obj->source); 79 eina_stringshare_del(ea_obj->source);
80 ea_obj->source = NULL; 80 ea_obj->source = NULL;
81 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in, NULL)); 81 eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in));
82 return EINA_FALSE; 82 return EINA_FALSE;
83 } 83 }
84 84
@@ -165,7 +165,7 @@ _ecore_audio_out_sndfile_eo_base_constructor(Eo *eo_obj, Ecore_Audio_Out_Sndfile
165 165
166 eo_do_super(eo_obj, MY_CLASS, eo_constructor()); 166 eo_do_super(eo_obj, MY_CLASS, eo_constructor());
167 167
168 eo_do(eo_obj, ecore_audio_obj_format_set(ECORE_AUDIO_FORMAT_OGG, NULL)); 168 eo_do(eo_obj, ecore_audio_obj_format_set(ECORE_AUDIO_FORMAT_OGG));
169 169
170 // FIXME: Use writer from output 170 // FIXME: Use writer from output
171 out_obj->need_writer = EINA_FALSE; 171 out_obj->need_writer = EINA_FALSE;
diff --git a/src/lib/ecore_audio/ecore_audio_private.h b/src/lib/ecore_audio/ecore_audio_private.h
index b997ea8e03..36a06f5f4c 100644
--- a/src/lib/ecore_audio/ecore_audio_private.h
+++ b/src/lib/ecore_audio/ecore_audio_private.h
@@ -94,7 +94,7 @@ struct _Ecore_Audio_Module
94struct _Ecore_Audio_Vio_Internal { 94struct _Ecore_Audio_Vio_Internal {
95 Ecore_Audio_Vio *vio; 95 Ecore_Audio_Vio *vio;
96 void *data; 96 void *data;
97 eo_base_data_free_func free_func; 97 eo_key_data_free_func free_func;
98}; 98};
99typedef struct _Ecore_Audio_Vio_Internal Ecore_Audio_Vio_Internal; 99typedef struct _Ecore_Audio_Vio_Internal Ecore_Audio_Vio_Internal;
100 100
diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c
index db301f1078..6120ff0adb 100644
--- a/src/lib/edje/edje_edit.c
+++ b/src/lib/edje/edje_edit.c
@@ -193,7 +193,7 @@ _edje_edit_edje_file_set(Eo *obj, Edje_Edit *eed, const char *file, const char *
193 * groups). 193 * groups).
194 */ 194 */
195 Eina_Bool int_ret = EINA_FALSE; 195 Eina_Bool int_ret = EINA_FALSE;
196 eo_do_super(obj, MY_CLASS, edje_obj_file_set(file, group, &int_ret)); 196 eo_do_super(obj, MY_CLASS, int_ret = edje_obj_file_set(file, group));
197 if (!int_ret) 197 if (!int_ret)
198 return ret; 198 return ret;
199 199
diff --git a/src/lib/edje/edje_multisense.c b/src/lib/edje/edje_multisense.c
index 07653a15ea..7fc8fc54ed 100644
--- a/src/lib/edje/edje_multisense.c
+++ b/src/lib/edje/edje_multisense.c
@@ -264,7 +264,7 @@ _edje_multisense_internal_sound_tone_play(Edje *ed, const char *tone_name, const
264 { 264 {
265 in = eo_add(ECORE_AUDIO_OBJ_IN_TONE_CLASS, NULL); 265 in = eo_add(ECORE_AUDIO_OBJ_IN_TONE_CLASS, NULL);
266 eo_do(in, ecore_audio_obj_name_set("tone")); 266 eo_do(in, ecore_audio_obj_name_set("tone"));
267 eo_do(in, eo_base_data_set(ECORE_AUDIO_ATTR_TONE_FREQ, &tone->value, NULL)); 267 eo_do(in, eo_key_data_set(ECORE_AUDIO_ATTR_TONE_FREQ, &tone->value, NULL));
268 eo_do(in, ecore_audio_obj_in_length_set(duration)); 268 eo_do(in, ecore_audio_obj_in_length_set(duration));
269 eo_do(in, eo_event_callback_add(ECORE_AUDIO_IN_EVENT_IN_STOPPED, _play_finished, NULL)); 269 eo_do(in, eo_event_callback_add(ECORE_AUDIO_IN_EVENT_IN_STOPPED, _play_finished, NULL));
270 270
diff --git a/src/lib/edje/edje_program.c b/src/lib/edje/edje_program.c
index 1a2126c5ad..46bb3fdfe0 100644
--- a/src/lib/edje/edje_program.c
+++ b/src/lib/edje/edje_program.c
@@ -78,7 +78,7 @@ edje_object_signal_callback_del(Evas_Object *obj, const char *emission, const ch
78{ 78{
79 if (!obj) return NULL; 79 if (!obj) return NULL;
80 void *ret = NULL; 80 void *ret = NULL;
81 eo_do(obj, edje_obj_signal_callback_del(emission, source, (Edje_Signal_Cb)func, NULL, &ret)); 81 eo_do(obj, ret = edje_obj_signal_callback_del(emission, source, (Edje_Signal_Cb)func, NULL));
82 return ret; 82 return ret;
83} 83}
84 84
@@ -107,7 +107,7 @@ edje_object_signal_callback_del_full(Evas_Object *obj, const char *emission, con
107{ 107{
108 if (!obj) return NULL; 108 if (!obj) return NULL;
109 void *ret = NULL; 109 void *ret = NULL;
110 eo_do(obj, edje_obj_signal_callback_del(emission, source, func, data, &ret)); 110 eo_do(obj, ret = edje_obj_signal_callback_del(emission, source, func, data));
111 return ret; 111 return ret;
112} 112}
113 113
diff --git a/src/lib/edje/edje_smart.c b/src/lib/edje/edje_smart.c
index 536356edb7..a4de77fc0c 100644
--- a/src/lib/edje/edje_smart.c
+++ b/src/lib/edje/edje_smart.c
@@ -52,8 +52,8 @@ _edje_eo_base_dbg_info_get(Eo *eo_obj, Edje *_pd EINA_UNUSED, Eo_Dbg_Info *root)
52 EO_DBG_INFO_APPEND(group, "File", EINA_VALUE_TYPE_STRING, file); 52 EO_DBG_INFO_APPEND(group, "File", EINA_VALUE_TYPE_STRING, file);
53 EO_DBG_INFO_APPEND(group, "Group", EINA_VALUE_TYPE_STRING, edje_group); 53 EO_DBG_INFO_APPEND(group, "Group", EINA_VALUE_TYPE_STRING, edje_group);
54 54
55 Edje_Load_Error error; 55 Edje_Load_Error error = EDJE_LOAD_ERROR_NONE;
56 eo_do(eo_obj, edje_obj_load_error_get(&error)); 56 eo_do(eo_obj, error = edje_obj_load_error_get());
57 if (error != EDJE_LOAD_ERROR_NONE) 57 if (error != EDJE_LOAD_ERROR_NONE)
58 { 58 {
59 EO_DBG_INFO_APPEND(group, "Error", EINA_VALUE_TYPE_STRING, 59 EO_DBG_INFO_APPEND(group, "Error", EINA_VALUE_TYPE_STRING,
@@ -363,4 +363,4 @@ _edje_mmap_set(Eo *obj, Edje *_pd EINA_UNUSED, const Eina_File *f, const char *g
363 return ret; 363 return ret;
364} 364}
365 365
366#include "edje.eo.c" \ No newline at end of file 366#include "edje.eo.c"
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 7f77b393cf..6e6979942d 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -230,20 +230,6 @@ EAPI void eo_dbg_info_free(Eo_Dbg_Info *info);
230 */ 230 */
231 231
232/** 232/**
233 * @def EO_TYPECHECK(type, x)
234 *
235 * Checks x is castable to type "type" and casts it to it.
236 * @param type The C type to check against.
237 * @param x the variable to test and cast.
238 */
239#define EO_TYPECHECK(type, x) \
240 ({ \
241 type __x; \
242 __x = x; \
243 (type) __x; \
244 })
245
246/**
247 * @typedef Eo_Op 233 * @typedef Eo_Op
248 * The Eo operation type id. 234 * The Eo operation type id.
249 */ 235 */
@@ -256,15 +242,6 @@ typedef unsigned int Eo_Op;
256#define EO_NOOP ((Eo_Op) 0) 242#define EO_NOOP ((Eo_Op) 0)
257 243
258/** 244/**
259 * @typedef eo_op_func_type
260 * The type of the Op functions. This is the type of the functions used by
261 * Eo.
262 *
263 * @see eo_op_func_type_class
264 */
265typedef void (*eo_op_func_type)(Eo *, void *class_data, va_list *list);
266
267/**
268 * @addtogroup Eo_Events Eo's Event Handling 245 * @addtogroup Eo_Events Eo's Event Handling
269 * @{ 246 * @{
270 */ 247 */
@@ -383,70 +360,19 @@ enum _Eo_Class_Type
383typedef enum _Eo_Class_Type Eo_Class_Type; 360typedef enum _Eo_Class_Type Eo_Class_Type;
384 361
385/** 362/**
386 * @struct _Eo_Op_Func_Description
387 * Used to associate an Op with a func.
388 * @see eo_class_funcs_set
389 */
390struct _Eo_Op_Func_Description
391{
392 Eo_Op op; /**< The op */
393 eo_op_func_type func; /**< The function to call for the op. */
394 Eo_Op_Type op_type; /**< The type of the op */
395};
396
397/**
398 * @typedef Eo_Op_Func_Description
399 * A convenience typedef for #_Eo_Op_Func_Description
400 */
401typedef struct _Eo_Op_Func_Description Eo_Op_Func_Description;
402
403/**
404 * @def EO_OP_FUNC(op, func)
405 * A convenience macro to be used when populating the #Eo_Op_Func_Description
406 * array.
407 */
408#define EO_OP_FUNC(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EO_OP_TYPE_REGULAR }
409
410/**
411 * @def EO_OP_FUNC_CLASS(op, func)
412 * A convenience macro to be used when populating the #Eo_Op_Func_Description
413 * array.
414 * The same as #EO_OP_FUNC but for class functions.
415 *
416 * @see EO_OP_FUNC
417 */
418#define EO_OP_FUNC_CLASS(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EO_OP_TYPE_CLASS }
419
420/**
421 * @def EO_OP_FUNC_SENTINEL
422 * A convenience macro to be used when populating the #Eo_Op_Func_Description
423 * array. It must appear at the end of the ARRAY.
424 */
425#define EO_OP_FUNC_SENTINEL { 0, NULL, EO_OP_TYPE_INVALID }
426
427/**
428 * @struct _Eo_Op_Description
429 * This struct holds the description of a specific op.
430 */
431struct _Eo_Op_Description
432{
433 Eo_Op sub_op; /**< The sub_id of the op in it's class. */
434 const char *name; /**< The name of the op. */
435 const char *doc; /**< Explanation about the Op. */
436 Eo_Op_Type op_type; /**< The type of the Op. */
437};
438
439/**
440 * @typedef Eo_Op_Description
441 * A convenience typedef for #_Eo_Op_Description
442 */
443typedef struct _Eo_Op_Description Eo_Op_Description;
444
445/**
446 * @def EO_VERSION 363 * @def EO_VERSION
447 * The current version of EO. 364 * The current version of EO.
448 */ 365 */
449#define EO_VERSION 1 366#define EO_VERSION 2
367
368typedef struct _Eo_Op_Description
369{
370 void *api_func; /**< The EAPI function offering this op. */
371 void *func; /**< The static function to call for the op. */
372 Eo_Op op; /**< The op. */
373 Eo_Op_Type op_type; /**< The type of the Op. */
374 const char *doc; /**< Explanation about the Op. */
375} Eo_Op_Description;
450 376
451/** 377/**
452 * @struct _Eo_Class_Description 378 * @struct _Eo_Class_Description
@@ -460,8 +386,7 @@ struct _Eo_Class_Description
460 const char *name; /**< The name of the class. */ 386 const char *name; /**< The name of the class. */
461 Eo_Class_Type type; /**< The type of the class. */ 387 Eo_Class_Type type; /**< The type of the class. */
462 struct { 388 struct {
463 Eo_Op *base_op_id; 389 Eo_Op_Description *descs2;
464 const Eo_Op_Description *descs;
465 size_t count; 390 size_t count;
466 } ops; /**< The ops description, should be filled using #EO_CLASS_DESCRIPTION_OPS */ 391 } ops; /**< The ops description, should be filled using #EO_CLASS_DESCRIPTION_OPS */
467 const Eo_Event_Description **events; /**< The event descriptions for this class. */ 392 const Eo_Event_Description **events; /**< The event descriptions for this class. */
@@ -477,60 +402,6 @@ struct _Eo_Class_Description
477typedef struct _Eo_Class_Description Eo_Class_Description; 402typedef struct _Eo_Class_Description Eo_Class_Description;
478 403
479/** 404/**
480 * @def EO_CLASS_DESCRIPTION_OPS(base_op_id, op_descs, count)
481 * An helper macro to help populating #Eo_Class_Description.
482 * @param base_op_id A pointer to the base op id of the class.
483 * @param op_descs the op descriptions array.
484 * @param count the number of ops in the op descriptions array.
485 */
486#define EO_CLASS_DESCRIPTION_OPS(base_op_id, op_descs, count) { base_op_id, op_descs, count }
487
488/**
489 * @def EO_OP_DESCRIPTION(op, doc)
490 * An helper macro to help populating #Eo_Op_Description
491 * @param sub_id The sub id of the op being described.
492 * @param doc Additional doc for the op.
493 * @see Eo_Op_Description
494 * @see EO_OP_DESCRIPTION_CLASS
495 * @see EO_OP_DESCRIPTION_SENTINEL
496 */
497#define EO_OP_DESCRIPTION(sub_id, doc) { sub_id, #sub_id, doc, EO_OP_TYPE_REGULAR }
498
499/**
500 * @def EO_OP_DESCRIPTION_CLASS(op, doc)
501 * An helper macro to help populating #Eo_Op_Description
502 * This macro is the same as EO_OP_DESCRIPTION but indicates that the op's
503 * implementation is of type CLASS.
504 * @param sub_id The sub id of the op being described.
505 * @param doc Additional doc for the op.
506 * @see Eo_Op_Description
507 * @see EO_OP_DESCRIPTION
508 * @see EO_OP_DESCRIPTION_SENTINEL
509 */
510#define EO_OP_DESCRIPTION_CLASS(sub_id, doc) { sub_id, #sub_id, doc, EO_OP_TYPE_CLASS }
511
512/**
513 * @def EO_OP_DESCRIPTION_SENTINEL
514 * An helper macro to help populating #Eo_Op_Description
515 * Should be placed at the end of the array.
516 * @see Eo_Op_Description
517 * @see EO_OP_DESCRIPTION
518 */
519#define EO_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, EO_OP_TYPE_INVALID }
520
521/**
522 * @def EO_PARAMETER_GET
523 * An helper macro to get parameter with less mistake
524 */
525#define EO_PARAMETER_GET(Type, Name, List) Type Name = va_arg(*List, Type);
526
527/**
528 * @def EO_PARAMETER_ENUM_GET
529 * An helper macro to get parameter that are enum with less mistake (require to ask an int)
530 */
531#define EO_PARAMETER_ENUM_GET(Type, Name, List) Type Name = va_arg(*List, int);
532
533/**
534 * @brief Create a new class. 405 * @brief Create a new class.
535 * @param desc the class description to create the class with. 406 * @param desc the class description to create the class with.
536 * @param parent the class to inherit from. 407 * @param parent the class to inherit from.
@@ -555,15 +426,6 @@ EAPI const Eo_Class *eo_class_new(const Eo_Class_Description *desc, const Eo_Cla
555EAPI Eina_Bool eo_isa(const Eo *obj, const Eo_Class *klass); 426EAPI Eina_Bool eo_isa(const Eo *obj, const Eo_Class *klass);
556 427
557/** 428/**
558 * @brief Sets the OP functions for a class.
559 * @param klass the class to set the functions to.
560 * @param func_descs a NULL terminated array of #Eo_Op_Func_Description
561 *
562 * Should be called from within the class constructor.
563 */
564EAPI void eo_class_funcs_set(Eo_Class *klass, const Eo_Op_Func_Description *func_descs);
565
566/**
567 * @brief Gets the name of the passed class. 429 * @brief Gets the name of the passed class.
568 * @param klass the class to work on. 430 * @param klass the class to work on.
569 * @return The class's name. 431 * @return The class's name.
@@ -592,73 +454,139 @@ EAPI Eina_Bool eo_init(void);
592 */ 454 */
593EAPI Eina_Bool eo_shutdown(void); 455EAPI Eina_Bool eo_shutdown(void);
594 456
595/** 457// computes size of Eo_Op_Description[]
596 * @def eo_do 458#define EO_OP_DESC_SIZE(desc) (sizeof(desc)/sizeof(*desc) - 1)
597 * A convenience wrapper around eo_do_internal()
598 * @see eo_do_internal
599 */
600#define eo_do(obj, ...) eo_do_internal(__FILE__, __LINE__, obj, __VA_ARGS__, EO_NOOP)
601 459
602/** 460// Helpers macro to help populating #Eo_Class_Description.
603 * @def eo_vdo 461#define EO_CLASS_DESCRIPTION_NOOPS() { NULL, 0}
604 * A convenience wrapper around eo_vdo_internal() 462#define EO_CLASS_DESCRIPTION_OPS(op_descs) { op_descs, EO_OP_DESC_SIZE(op_descs) }
605 * @see eo_vdo_internal
606 */
607#define eo_vdo(obj, args) eo_vdo_internal(__FILE__, __LINE__, obj, args)
608 463
609/** 464// to fetch internal function and object data at once
610 * @brief Calls op functions of an object 465typedef struct _Eo_Op_Call_Data
611 * @param obj The object to work on 466{
612 * @param ... NULL terminated list of OPs and parameters. 467 Eo *obj;
613 * @return @c EINA_TRUE on success. 468 Eo_Class *klass; // remove this not necessary in Eo_Hook_Call
614 * 469 void *func;
615 * Use the helper macros, don't pass the parameters manually. 470 void *data;
616 * Use #eo_do instead of this function. 471} Eo_Op_Call_Data;
617 * 472
618 * @see #eo_do 473typedef void (*Eo_Hook_Call)(const Eo_Class *klass_id, const Eo *obj, void *func, ...);
619 */ 474
620EAPI Eina_Bool eo_do_internal(const char *file, int line, const Eo *obj, ...); 475EAPI extern Eo_Hook_Call eo_hook_call_pre;
476EAPI extern Eo_Hook_Call eo_hook_call_post;
477
478// to pass the internal function call to EO_FUNC_BODY (as Func parameter)
479#define EO_FUNC_CALL(...) __VA_ARGS__
480
481#define EO_HOOK_CALL_PREPARE(Hook) \
482 if (Hook) \
483 Hook(call.klass, call.obj, call.func);
484
485#define EO_HOOK_CALL_PREPAREV(Hook, ...) \
486 if (Hook) \
487 Hook(call.klass, call.obj, call.func, __VA_ARGS__);
488
489// cache OP id, get real fct and object data then do the call
490#define EO_FUNC_COMMON_OP(Name, DefRet) \
491 Eo_Op_Call_Data call; \
492 static Eo_Op op = EO_NOOP; \
493 if (op == EO_NOOP) \
494 op = _eo_api_op_id_get((void*) Name, __FILE__, __LINE__); \
495 if (!_eo_call_resolve(#Name, op, &call, __FILE__, __LINE__)) return DefRet; \
496 _Eo_##Name##_func _func_ = (_Eo_##Name##_func) call.func; \
497
498// to define an EAPI function
499#define EO_FUNC_BODY(Name, Ret, DefRet) \
500 Ret \
501 Name(void) \
502 { \
503 typedef Ret (*_Eo_##Name##_func)(Eo *, void *obj_data); \
504 Ret _r; \
505 EO_FUNC_COMMON_OP(Name, DefRet); \
506 EO_HOOK_CALL_PREPARE(eo_hook_call_pre); \
507 _r = _func_(call.obj, call.data); \
508 EO_HOOK_CALL_PREPARE(eo_hook_call_post); \
509 return _r; \
510 }
621 511
622/** 512#define EO_VOID_FUNC_BODY(Name) \
623 * @brief Calls op functions of an object 513 void \
624 * @param obj The object to work on 514 Name(void) \
625 * @param ops NULL terminated list of OPs and parameters. 515 { \
626 * @return @c EINA_TRUE on success. 516 typedef void (*_Eo_##Name##_func)(Eo *, void *obj_data); \
627 * 517 EO_FUNC_COMMON_OP(Name, ); \
628 * Use the helper macros, don't pass the parameters manually. 518 EO_HOOK_CALL_PREPARE(eo_hook_call_pre); \
629 * Use #eo_vdo instead of this function. 519 _func_(call.obj, call.data); \
630 * 520 EO_HOOK_CALL_PREPARE(eo_hook_call_post); \
631 * @see #eo_vdo 521 }
632 */
633EAPI Eina_Bool eo_vdo_internal(const char *file, int line, const Eo *obj, va_list *ops);
634 522
635/** 523#define EO_FUNC_BODYV(Name, Ret, DefRet, Arguments, ...) \
636 * @brief Calls the super function for the specific op. 524 Ret \
637 * @param obj The object to work on 525 Name(__VA_ARGS__) \
638 * @param cur_klass The *current* class (use the class *after* this in the MRO). 526 { \
639 * @param ... list of parameters. 527 typedef Ret (*_Eo_##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
640 * @return @c EINA_TRUE on success. 528 Ret _r; \
641 * 529 EO_FUNC_COMMON_OP(Name, DefRet); \
642 * Unlike eo_do(), this function only accepts one op. 530 EO_HOOK_CALL_PREPAREV(eo_hook_call_pre, Arguments); \
643 * 531 _r = _func_(call.obj, call.data, Arguments); \
644 * @see #eo_do 532 EO_HOOK_CALL_PREPAREV(eo_hook_call_post, Arguments); \
645 */ 533 return _r; \
646#define eo_do_super(obj, cur_klass, ...) eo_do_super_internal(__FILE__, __LINE__, obj, cur_klass, __VA_ARGS__) 534 }
647 535
648/** 536#define EO_VOID_FUNC_BODYV(Name, Arguments, ...) \
649 * @brief Calls the super function for the specific op. 537 void \
650 * @param obj The object to work on 538 Name(__VA_ARGS__) \
651 * @param cur_klass The *current* class (use the class *after* this in the MRO). 539 { \
652 * @param op The wanted op. 540 typedef void (*_Eo_##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
653 * @param ... list of parameters. 541 EO_FUNC_COMMON_OP(Name, ); \
654 * @return @c EINA_TRUE on success. 542 EO_HOOK_CALL_PREPAREV(eo_hook_call_pre, Arguments); \
655 * 543 _func_(call.obj, call.data, Arguments); \
656 * Don't use this function, use the wrapping macros instead. 544 EO_HOOK_CALL_PREPAREV(eo_hook_call_post, Arguments); \
657 * 545 }
658 * @see #eo_do 546
659 * @see #eo_do_super 547// OP ID of an overriding function
660 */ 548#define EO_OP_OVERRIDE ((Eo_Op) -1)
661EAPI Eina_Bool eo_do_super_internal(const char *file, int line, const Eo *obj, const Eo_Class *cur_klass, Eo_Op op, ...); 549
550#define EO_OP_FUNC(_api, _private, _doc) {_api, _private, EO_NOOP, EO_OP_TYPE_REGULAR, _doc}
551#define EO_OP_CLASS_FUNC(_api, _private, _doc) {_api, _private, EO_NOOP, EO_OP_TYPE_CLASS, _doc}
552#define EO_OP_FUNC_OVERRIDE(_api, _private) {_api, _private, EO_OP_OVERRIDE, EO_OP_TYPE_REGULAR, NULL}
553#define EO_OP_CLASS_FUNC_OVERRIDE(_api, _private) {_api, _private, EO_OP_OVERRIDE, EO_OP_TYPE_CLASS, NULL}
554#define EO_OP_SENTINEL { NULL, NULL, 0, EO_OP_TYPE_INVALID, NULL}
555
556// returns the OP id corresponding to the given api_func
557EAPI Eo_Op _eo_api_op_id_get(const void *api_func, const char *file, int line);
558
559// gets the real function pointer and the object data
560EAPI Eina_Bool _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, const char *file, int line);
561
562// start of eo_do barrier, gets the object pointer and ref it, put it on the stask
563EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, Eina_Bool is_super, const char *file, const char *func, int line);
564
565// end of the eo_do barrier, unref the obj, move the stack pointer
566EAPI void _eo_do_end(const Eo **ojb);
567
568#define EO_DO_CLEANUP __attribute__((cleanup(_eo_do_end)))
569
570// eo object method calls batch,
571
572#define _eo_do_common(eoid, clsid, is_super, ...) \
573 do \
574 { \
575 const Eo *_eoid_ = eoid; \
576 if (_eo_do_start(_eoid_, clsid, is_super, __FILE__, __FUNCTION__, __LINE__)) \
577 { \
578 const Eo *_id_clean_ EO_DO_CLEANUP = _eoid_; \
579 __VA_ARGS__; \
580 (void) _id_clean_; \
581 } \
582 } while (0)
583
584
585#define eo_do(eoid, ...) _eo_do_common(eoid, NULL, EINA_FALSE, __VA_ARGS__)
586
587#define eo_do_super(eoid, clsid, func) _eo_do_common(eoid, clsid, EINA_TRUE, func)
588
589/*****************************************************************************/
662 590
663/** 591/**
664 * @brief Gets the class of the object. 592 * @brief Gets the class of the object.
@@ -695,7 +623,13 @@ EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line);
695#define eo_add(klass, parent, ...) \ 623#define eo_add(klass, parent, ...) \
696 ({ \ 624 ({ \
697 const Eo_Class *_tmp_klass = klass; \ 625 const Eo_Class *_tmp_klass = klass; \
698 eo_add_internal(__FILE__, __LINE__, _tmp_klass, parent, eo_constructor(), ## __VA_ARGS__, EO_NOOP); \ 626 Eo *_tmp_obj = _eo_add_internal_start(__FILE__, __LINE__, _tmp_klass, parent); \
627 eo_do(_tmp_obj, \
628 eo_constructor(); \
629 __VA_ARGS__; \
630 _tmp_obj = _eo_add_internal_end(__FILE__, __LINE__, _tmp_obj); \
631 ); \
632 _tmp_obj; \
699 }) 633 })
700 634
701/** 635/**
@@ -711,22 +645,16 @@ EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line);
711#define eo_add_custom(klass, parent, ...) \ 645#define eo_add_custom(klass, parent, ...) \
712 ({ \ 646 ({ \
713 const Eo_Class *_tmp_klass = klass; \ 647 const Eo_Class *_tmp_klass = klass; \
714 eo_add_internal(__FILE__, __LINE__, _tmp_klass, parent, ## __VA_ARGS__, EO_NOOP); \ 648 Eo *_tmp_obj = _eo_add_internal_start(__FILE__, __LINE__, _tmp_klass, parent); \
649 eo_do(_tmp_obj, \
650 __VA_ARGS__; \
651 _tmp_obj = _eo_add_internal_end(__FILE__, __LINE__, _tmp_obj); \
652 ); \
653 _tmp_obj; \
715 }) 654 })
716 655
717/** 656EAPI Eo * _eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo *parent);
718 * @brief Create a new object. 657EAPI Eo * _eo_add_internal_end(const char *file, int line, const Eo *obj);
719 * @param klass the class of the object to create.
720 * @param parent the parent to set to the object.
721 * @param ... The ops to run. With the constructor being first.
722 * @return An handle to the new object on success, NULL otherwise.
723 *
724 * Use the helper macros, don't pass the parameters manually.
725 * Use #eo_add or #eo_add_custom instead of this function.
726 *
727 * @see #eo_add
728 */
729EAPI Eo *eo_add_internal(const char *file, int line, const Eo_Class *klass, Eo *parent, ...);
730 658
731/** 659/**
732 * @brief Get a pointer to the data of an object for a specific class. 660 * @brief Get a pointer to the data of an object for a specific class.
@@ -994,16 +922,6 @@ EAPI Eina_Bool eo_composite_is(const Eo *comp_obj);
994EAPI const Eo_Class *eo_class_class_get(void); 922EAPI const Eo_Class *eo_class_class_get(void);
995 923
996/** 924/**
997 * @var EO_CLASS_CLASS_BASE_ID
998 * #EO_CLASS_CLASS 's base id.
999 */
1000extern EAPI Eo_Op EO_CLASS_CLASS_BASE_ID;
1001
1002enum {
1003 EO_CLASS_CLASS_SUB_ID_LAST
1004};
1005
1006/**
1007 * @} 925 * @}
1008 */ 926 */
1009 927
@@ -1013,105 +931,59 @@ enum {
1013 */ 931 */
1014 932
1015/** 933/**
1016 * @def EO_BASE_CLASS 934 * @def EO_CLASS
1017 * The class type for the Eo base class. 935 * The class type for the Eo base class.
1018 */ 936 */
1019#define EO_BASE_CLASS eo_base_class_get() 937#define EO_CLASS eo_base_class_get()
1020/** 938/**
1021 * @brief Use #EO_BASE_CLASS 939 * @brief Use #EO_CLASS
1022 * @internal 940 * @internal
1023 * */ 941 * */
1024EAPI const Eo_Class *eo_base_class_get(void); 942EAPI const Eo_Class *eo_base_class_get(void);
1025 943
1026/** 944/**
1027 * @typedef eo_base_data_free_func 945 * @typedef eo_key_data_free_func
1028 * Data free func prototype. 946 * Data free func prototype.
1029 */ 947 */
1030typedef void (*eo_base_data_free_func)(void *); 948typedef void (*eo_key_data_free_func)(void *);
1031
1032/**
1033 * @var EO_BASE_BASE_ID
1034 * #EO_BASE_CLASS 's base id.
1035 */
1036extern EAPI Eo_Op EO_BASE_BASE_ID;
1037
1038enum {
1039 EO_BASE_SUB_ID_CONSTRUCTOR,
1040 EO_BASE_SUB_ID_DESTRUCTOR,
1041 EO_BASE_SUB_ID_PARENT_SET,
1042 EO_BASE_SUB_ID_PARENT_GET,
1043 EO_BASE_SUB_ID_CHILDREN_ITERATOR_NEW,
1044 EO_BASE_SUB_ID_DATA_SET,
1045 EO_BASE_SUB_ID_DATA_GET,
1046 EO_BASE_SUB_ID_DATA_DEL,
1047 EO_BASE_SUB_ID_WREF_ADD,
1048 EO_BASE_SUB_ID_WREF_DEL,
1049 EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD,
1050 EO_BASE_SUB_ID_EVENT_CALLBACK_DEL,
1051 EO_BASE_SUB_ID_EVENT_CALLBACK_ARRAY_PRIORITY_ADD,
1052 EO_BASE_SUB_ID_EVENT_CALLBACK_ARRAY_DEL,
1053 EO_BASE_SUB_ID_EVENT_CALLBACK_CALL,
1054 EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD,
1055 EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL,
1056 EO_BASE_SUB_ID_EVENT_FREEZE,
1057 EO_BASE_SUB_ID_EVENT_THAW,
1058 EO_BASE_SUB_ID_EVENT_FREEZE_GET,
1059 EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE,
1060 EO_BASE_SUB_ID_EVENT_GLOBAL_THAW,
1061 EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET,
1062 EO_BASE_SUB_ID_DBG_INFO_GET,
1063 EO_BASE_SUB_ID_LAST
1064};
1065
1066/**
1067 * @def EO_BASE_ID(sub_id)
1068 * Helper macro to get the full Op ID out of the sub_id for EO_BASE.
1069 * @param sub_id the sub id inside EO_BASE.
1070 */
1071#define EO_BASE_ID(sub_id) (EO_BASE_BASE_ID + (sub_id))
1072 949
1073/** 950/**
1074 * @def eo_base_data_set(key, data, free_func) 951 * @brief Set generic data to object.
1075 * Set generic data to object.
1076 * @param[in] key the key associated with the data 952 * @param[in] key the key associated with the data
1077 * @param[in] data the data to set. 953 * @param[in] data the data to set.
1078 * @param[in] free_func the func to free data with (NULL means "do nothing"). 954 * @param[in] free_func the func to free data with (NULL means "do nothing").
1079 * 955 *
1080 * @see #eo_base_data_get 956 * @see #eo_key_data_get
1081 * @see #eo_base_data_del 957 * @see #eo_key_data_del
1082 */ 958 */
1083#define eo_base_data_set(key, data, free_func) EO_BASE_ID(EO_BASE_SUB_ID_DATA_SET), EO_TYPECHECK(const char *, key), EO_TYPECHECK(const void *, data), EO_TYPECHECK(eo_base_data_free_func, free_func) 959EAPI void eo_key_data_set(const char *key, const void *data, eo_key_data_free_func free_func);
1084 960
1085/** 961/**
1086 * @def eo_base_data_get(key, data) 962 * @brief Get generic data from object.
1087 * Get generic data from object.
1088 * @param[in] key the key associated with the data 963 * @param[in] key the key associated with the data
1089 * @param[out] data the data for the key 964 * @param[out] data the data for the key
1090 * 965 *
1091 * @see #eo_base_data_set 966 * @see #eo_key_data_set
1092 * @see #eo_base_data_del 967 * @see #eo_key_data_del
1093 */ 968 */
1094#define eo_base_data_get(key, data) EO_BASE_ID(EO_BASE_SUB_ID_DATA_GET), EO_TYPECHECK(const char *, key), EO_TYPECHECK(void **, data) 969EAPI void *eo_key_data_get(const char *key);
1095 970
1096/** 971/**
1097 * @def eo_dbg_info_get(root_node) 972 * @brief Get dbg information from the object.
1098 * Get dbg information from the object.
1099 * @param[in] root node of the tree 973 * @param[in] root node of the tree
1100 */ 974 */
1101#define eo_dbg_info_get(root_node) EO_BASE_ID(EO_BASE_SUB_ID_DBG_INFO_GET), EO_TYPECHECK(Eo_Dbg_Info *, root_node) 975EAPI void eo_dbg_info_get(Eo_Dbg_Info *root_node);
1102 976
1103/** 977/**
1104 * @def eo_base_data_del(key) 978 * @brief Del generic data from object.
1105 * Del generic data from object.
1106 * @param[in] key the key associated with the data 979 * @param[in] key the key associated with the data
1107 * 980 *
1108 * @see #eo_base_data_set 981 * @see #eo_key_data_set
1109 * @see #eo_base_data_get 982 * @see #eo_key_data_get
1110 */ 983 */
1111#define eo_base_data_del(key) EO_BASE_ID(EO_BASE_SUB_ID_DATA_DEL), EO_TYPECHECK(const char *, key) 984EAPI void eo_key_data_del(const char *key);
1112 985
1113/** 986/**
1114 * @def eo_parent_set
1115 * @brief Set the parent of an object 987 * @brief Set the parent of an object
1116 * @param[in] parent the new parent. 988 * @param[in] parent the new parent.
1117 * 989 *
@@ -1122,29 +994,26 @@ enum {
1122 * @see eo_del() 994 * @see eo_del()
1123 * @see eo_parent_get() 995 * @see eo_parent_get()
1124 */ 996 */
1125#define eo_parent_set(parent) EO_BASE_ID(EO_BASE_SUB_ID_PARENT_SET), EO_TYPECHECK(Eo *, parent) 997EAPI void eo_parent_set(Eo *parent);
1126 998
1127/** 999/**
1128 * @def eo_parent_get
1129 * @brief Get the parent of an object 1000 * @brief Get the parent of an object
1130 * @param[out] a pointer to the parent object. 1001 * @param[out] a pointer to the parent object.
1131 * 1002 *
1132 * @see eo_parent_set() 1003 * @see eo_parent_set()
1133 */ 1004 */
1134#define eo_parent_get(parent) EO_BASE_ID(EO_BASE_SUB_ID_PARENT_GET), EO_TYPECHECK(Eo **, parent) 1005EAPI Eo *eo_parent_get(void);
1135 1006
1136/** 1007/**
1137 * @def eo_children_iterator_new
1138 * @brief Get an iterator on all childrens 1008 * @brief Get an iterator on all childrens
1139 * @param obj the object to get the childrens from. 1009 * @param obj the object to get the childrens from.
1140 * @return a pointer to an Eina_Iterator containing all the childrens. 1010 * @return a pointer to an Eina_Iterator containing all the childrens.
1141 * 1011 *
1142 * @see eo_parent_set() 1012 * @see eo_parent_set()
1143 */ 1013 */
1144#define eo_children_iterator_new(it) EO_BASE_ID(EO_BASE_SUB_ID_CHILDREN_ITERATOR_NEW), EO_TYPECHECK(Eina_Iterator **, it) 1014EAPI Eina_Iterator *eo_children_iterator_new(void);
1145 1015
1146/** 1016/**
1147 * @def eo_wref_add
1148 * @brief Add a new weak reference to obj. 1017 * @brief Add a new weak reference to obj.
1149 * @param wref The pointer to use for the weak ref. 1018 * @param wref The pointer to use for the weak ref.
1150 * 1019 *
@@ -1155,16 +1024,15 @@ enum {
1155 * 1024 *
1156 * @see #eo_wref_del 1025 * @see #eo_wref_del
1157 */ 1026 */
1158#define eo_wref_add(wref) EO_BASE_ID(EO_BASE_SUB_ID_WREF_ADD), EO_TYPECHECK(Eo **, wref) 1027EAPI void eo_wref_add(Eo **wref);
1159 1028
1160/** 1029/**
1161 * @def eo_wref_del
1162 * @brief Delete the weak reference passed. 1030 * @brief Delete the weak reference passed.
1163 * @param wref the weak reference to free. 1031 * @param wref the weak reference to free.
1164 * 1032 *
1165 * @see #eo_wref_add 1033 * @see #eo_wref_add
1166 */ 1034 */
1167#define eo_wref_del(wref) EO_BASE_ID(EO_BASE_SUB_ID_WREF_DEL), EO_TYPECHECK(Eo **, wref) 1035EAPI void eo_wref_del(Eo **wref);
1168 1036
1169/** 1037/**
1170 * @def eo_weak_ref 1038 * @def eo_weak_ref
@@ -1178,9 +1046,9 @@ enum {
1178 * @see eo_weak_unref 1046 * @see eo_weak_unref
1179 * @see eo_wref_add 1047 * @see eo_wref_add
1180 */ 1048 */
1181#define eo_weak_ref(wref) \ 1049#define eo_weak_ref(wref) \
1182 do { \ 1050 do { \
1183 if (*wref) eo_do(*wref, eo_wref_add(wref)); \ 1051 if (*wref) eo_do(*wref, eo_wref_add(wref)); \
1184 } while (0) 1052 } while (0)
1185 1053
1186/** 1054/**
@@ -1196,9 +1064,9 @@ enum {
1196 * @see eo_wref_del 1064 * @see eo_wref_del
1197 * @see eo_wref_del_safe 1065 * @see eo_wref_del_safe
1198 */ 1066 */
1199#define eo_weak_unref(wref) \ 1067#define eo_weak_unref(wref) \
1200 do { \ 1068 do { \
1201 if (*wref) eo_do(*wref, eo_wref_del(wref)); \ 1069 if (*wref) eo_do(*wref, eo_wref_del(wref)); \
1202 } while (0) 1070 } while (0)
1203 1071
1204/** 1072/**
@@ -1214,24 +1082,22 @@ enum {
1214#define eo_wref_del_safe(wref) eo_weak_unref(wref) 1082#define eo_wref_del_safe(wref) eo_weak_unref(wref)
1215 1083
1216/** 1084/**
1217 * @def eo_constructor
1218 * @brief Call the object's constructor. 1085 * @brief Call the object's constructor.
1219 * 1086 *
1220 * Should not be used with #eo_do. Only use it with #eo_do_super. 1087 * Should not be used with #eo_do. Only use it with #eo_do_super.
1221 * 1088 *
1222 * @see #eo_destructor 1089 * @see #eo_destructor
1223 */ 1090 */
1224#define eo_constructor() EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR) 1091EAPI void eo_constructor(void);
1225 1092
1226/** 1093/**
1227 * @def eo_destructor
1228 * @brief Call the object's destructor. 1094 * @brief Call the object's destructor.
1229 * 1095 *
1230 * Should not be used with #eo_do. Only use it with #eo_do_super. 1096 * Should not be used with #eo_do. Only use it with #eo_do_super.
1231 * 1097 *
1232 * @see #eo_constructor 1098 * @see #eo_constructor
1233 */ 1099 */
1234#define eo_destructor() EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR) 1100EAPI void eo_destructor(void);
1235 1101
1236/** 1102/**
1237 * @addtogroup Eo_Events Eo's Event Handling 1103 * @addtogroup Eo_Events Eo's Event Handling
@@ -1316,47 +1182,42 @@ struct _Eo_Callback_Array_Item
1316 } 1182 }
1317 1183
1318/** 1184/**
1319 * @def eo_event_callback_forwarder_add
1320 * @brief Add an event callback forwarder for an event and an object. 1185 * @brief Add an event callback forwarder for an event and an object.
1321 * @param[in] desc The description of the event to listen to. 1186 * @param[in] desc The description of the event to listen to.
1322 * @param[in] new_obj The object to emit events from. 1187 * @param[in] new_obj The object to emit events from.
1323 * 1188 *
1324 * @see eo_event_callback_forwarder_del() 1189 * @see eo_event_callback_forwarder_del()
1325 */ 1190 */
1326#define eo_event_callback_forwarder_add(desc, new_obj) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo *, new_obj) 1191EAPI void eo_event_callback_forwarder_add(const Eo_Event_Description *desc, Eo *new_obj);
1327 1192
1328/** 1193/**
1329 * @def eo_event_callback_forwarder_del
1330 * @brief Remove an event callback forwarder for an event and an object. 1194 * @brief Remove an event callback forwarder for an event and an object.
1331 * @param[in] desc The description of the event to listen to. 1195 * @param[in] desc The description of the event to listen to.
1332 * @param[in] new_obj The object to emit events from. 1196 * @param[in] new_obj The object to emit events from.
1333 * 1197 *
1334 * @see eo_event_callback_forwarder_add() 1198 * @see eo_event_callback_forwarder_add()
1335 */ 1199 */
1336#define eo_event_callback_forwarder_del(desc, new_obj) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo *, new_obj) 1200EAPI void eo_event_callback_forwarder_del(const Eo_Event_Description *desc, Eo *new_obj);
1337 1201
1338/** 1202/**
1339 * @def eo_event_freeze
1340 * @brief freeze events of object. 1203 * @brief freeze events of object.
1341 * 1204 *
1342 * Prevents event callbacks from being called for the object. 1205 * Prevents event callbacks from being called for the object.
1343 * 1206 *
1344 * @see #eo_event_thaw 1207 * @see #eo_event_thaw
1345 */ 1208 */
1346#define eo_event_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE) 1209EAPI void eo_event_freeze(void);
1347 1210
1348/** 1211/**
1349 * @def eo_event_thaw
1350 * @brief thaw events of object. 1212 * @brief thaw events of object.
1351 * 1213 *
1352 * Lets event callbacks be called for the object. 1214 * Lets event callbacks be called for the object.
1353 * 1215 *
1354 * @see #eo_event_freeze 1216 * @see #eo_event_freeze
1355 */ 1217 */
1356#define eo_event_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW) 1218EAPI void eo_event_thaw(void);
1357 1219
1358/** 1220/**
1359 * @def eo_event_freeze_get
1360 * @brief return freeze events of object. 1221 * @brief return freeze events of object.
1361 * 1222 *
1362 * @param[out] fcount The event freeze count of the object. 1223 * @param[out] fcount The event freeze count of the object.
@@ -1366,10 +1227,9 @@ struct _Eo_Callback_Array_Item
1366 * @see #eo_event_freeze 1227 * @see #eo_event_freeze
1367 * @see #eo_event_thaw 1228 * @see #eo_event_thaw
1368 */ 1229 */
1369#define eo_event_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), EO_TYPECHECK(int *, fcount) 1230EAPI int eo_event_freeze_get(void);
1370 1231
1371/** 1232/**
1372 * @def eo_event_global_freeze
1373 * @brief freeze events of object. 1233 * @brief freeze events of object.
1374 * 1234 *
1375 * Prevents event callbacks from being called for the object. 1235 * Prevents event callbacks from being called for the object.
@@ -1377,10 +1237,9 @@ struct _Eo_Callback_Array_Item
1377 * @see #eo_event_freeze 1237 * @see #eo_event_freeze
1378 * @see #eo_event_global_thaw 1238 * @see #eo_event_global_thaw
1379 */ 1239 */
1380#define eo_event_global_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE) 1240EAPI void eo_event_global_freeze(void);
1381 1241
1382/** 1242/**
1383 * @def eo_event_global_thaw
1384 * @brief thaw events of object. 1243 * @brief thaw events of object.
1385 * 1244 *
1386 * Lets event callbacks be called for the object. 1245 * Lets event callbacks be called for the object.
@@ -1388,10 +1247,9 @@ struct _Eo_Callback_Array_Item
1388 * @see #eo_event_thaw 1247 * @see #eo_event_thaw
1389 * @see #eo_event_global_freeze 1248 * @see #eo_event_global_freeze
1390 */ 1249 */
1391#define eo_event_global_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW) 1250EAPI void eo_event_global_thaw(void);
1392 1251
1393/** 1252/**
1394 * @def eo_event_global_freeze_get
1395 * @brief return freeze events of object. 1253 * @brief return freeze events of object.
1396 * 1254 *
1397 * @param[out] fcount The event freeze count of the object. 1255 * @param[out] fcount The event freeze count of the object.
@@ -1402,7 +1260,7 @@ struct _Eo_Callback_Array_Item
1402 * @see #eo_event_global_freeze 1260 * @see #eo_event_global_freeze
1403 * @see #eo_event_global_thaw 1261 * @see #eo_event_global_thaw
1404 */ 1262 */
1405#define eo_event_global_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET), EO_TYPECHECK(int *, fcount) 1263EAPI int eo_event_global_freeze_get(void);
1406 1264
1407/** 1265/**
1408 * @def eo_event_callback_add(obj, desc, cb, data) 1266 * @def eo_event_callback_add(obj, desc, cb, data)
@@ -1420,7 +1278,6 @@ struct _Eo_Callback_Array_Item
1420 EO_CALLBACK_PRIORITY_DEFAULT, cb, data) 1278 EO_CALLBACK_PRIORITY_DEFAULT, cb, data)
1421 1279
1422/** 1280/**
1423 * @def eo_event_callback_priority_add
1424 * @brief Add a callback for an event with a specific priority. 1281 * @brief Add a callback for an event with a specific priority.
1425 * @param[in] desc The description of the event to listen to. 1282 * @param[in] desc The description of the event to listen to.
1426 * @param[in] priority The priority of the callback. 1283 * @param[in] priority The priority of the callback.
@@ -1431,17 +1288,21 @@ struct _Eo_Callback_Array_Item
1431 * 1288 *
1432 * @see #eo_event_callback_add 1289 * @see #eo_event_callback_add
1433 */ 1290 */
1434#define eo_event_callback_priority_add(desc, priority, cb, data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo_Callback_Priority, priority), EO_TYPECHECK(Eo_Event_Cb, cb), EO_TYPECHECK(const void *, data) 1291EAPI void eo_event_callback_priority_add(const Eo_Event_Description *desc,
1292 Eo_Callback_Priority priority,
1293 Eo_Event_Cb func,
1294 const void *user_data);
1435 1295
1436/** 1296/**
1437 * @def eo_event_callback_del
1438 * @brief Del a callback with a specific data associated to it for an event. 1297 * @brief Del a callback with a specific data associated to it for an event.
1439 * @param[in] desc The description of the event to listen to. 1298 * @param[in] desc The description of the event to listen to.
1440 * @param[in] func the callback to delete. 1299 * @param[in] func the callback to delete.
1441 * @param[in] user_data The data to compare. 1300 * @param[in] user_data The data to compare.
1442 * 1301 *
1443 */ 1302 */
1444#define eo_event_callback_del(desc, func, user_data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_DEL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo_Event_Cb, func), EO_TYPECHECK(const void *, user_data) 1303EAPI void eo_event_callback_del(const Eo_Event_Description *desc,
1304 Eo_Event_Cb func,
1305 const void *user_data);
1445 1306
1446/** 1307/**
1447 * @def eo_event_callback_array_add(obj, desc, cb, data) 1308 * @def eo_event_callback_array_add(obj, desc, cb, data)
@@ -1458,7 +1319,6 @@ struct _Eo_Callback_Array_Item
1458 EO_CALLBACK_PRIORITY_DEFAULT, data) 1319 EO_CALLBACK_PRIORITY_DEFAULT, data)
1459 1320
1460/** 1321/**
1461 * @def eo_event_callback_array_priority_add
1462 * @brief Add a callback array for an event with a specific priority. 1322 * @brief Add a callback array for an event with a specific priority.
1463 * @param[in] array an #Eo_Callback_Array_Item of events to listen to. 1323 * @param[in] array an #Eo_Callback_Array_Item of events to listen to.
1464 * @param[in] priority The priority of the callback. 1324 * @param[in] priority The priority of the callback.
@@ -1468,25 +1328,26 @@ struct _Eo_Callback_Array_Item
1468 * 1328 *
1469 * @see #eo_event_callback_add 1329 * @see #eo_event_callback_add
1470 */ 1330 */
1471#define eo_event_callback_array_priority_add(array, priority, data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_ARRAY_PRIORITY_ADD), EO_TYPECHECK(const Eo_Callback_Array_Item *, array), EO_TYPECHECK(Eo_Callback_Priority, priority), EO_TYPECHECK(const void *, data) 1331EAPI void eo_event_callback_array_priority_add(const Eo_Callback_Array_Item *array,
1332 Eo_Callback_Priority priority,
1333 const void *user_data);
1472 1334
1473/** 1335/**
1474 * @def eo_event_callback_array_del
1475 * @brief Del a callback array with a specific data associated to it for an event. 1336 * @brief Del a callback array with a specific data associated to it for an event.
1476 * @param[in] array an #Eo_Callback_Array_Item of events to listen to. 1337 * @param[in] array an #Eo_Callback_Array_Item of events to listen to.
1477 * @param[in] user_data The data to compare. 1338 * @param[in] user_data The data to compare.
1478 * 1339 *
1479 */ 1340 */
1480#define eo_event_callback_array_del(array, user_data) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_ARRAY_DEL), EO_TYPECHECK(const Eo_Callback_Array_Item *, array), EO_TYPECHECK(const void *, user_data) 1341EAPI void eo_event_callback_array_del(const Eo_Callback_Array_Item *array,
1342 const void *user_data);
1481 1343
1482/** 1344/**
1483 * @def eo_event_callback_call
1484 * @brief Call the callbacks for an event of an object. 1345 * @brief Call the callbacks for an event of an object.
1485 * @param[in] desc The description of the event to call. 1346 * @param[in] desc The description of the event to call.
1486 * @param[in] event_info Extra event info to pass to the callbacks. 1347 * @param[in] event_info Extra event info to pass to the callbacks.
1487 * @param[out] aborted @c EINA_TRUE if one of the callbacks aborted the call, @c EINA_FALSE otherwise. 1348 * @param[out] aborted @c EINA_TRUE if one of the callbacks aborted the call, @c EINA_FALSE otherwise.
1488 */ 1349 */
1489#define eo_event_callback_call(desc, event_info, aborted) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(const void *, event_info), EO_TYPECHECK(Eina_Bool *, aborted) 1350EAPI Eina_Bool eo_event_callback_call(const Eo_Event_Description *desc, void *event_info);
1490 1351
1491/** 1352/**
1492 * @} 1353 * @}
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 7842aa8a91..d207f206c0 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -28,7 +28,7 @@ static inline void *_eo_data_scope_get(const _Eo_Object *obj, const _Eo_Class *k
28static inline void *_eo_data_xref_internal(const char *file, int line, _Eo_Object *obj, const _Eo_Class *klass, const _Eo_Object *ref_obj); 28static inline void *_eo_data_xref_internal(const char *file, int line, _Eo_Object *obj, const _Eo_Class *klass, const _Eo_Object *ref_obj);
29static inline void _eo_data_xunref_internal(_Eo_Object *obj, void *data, const _Eo_Object *ref_obj); 29static inline void _eo_data_xunref_internal(_Eo_Object *obj, void *data, const _Eo_Object *ref_obj);
30static const _Eo_Class *_eo_op_class_get(Eo_Op op); 30static const _Eo_Class *_eo_op_class_get(Eo_Op op);
31static const Eo_Op_Description *_eo_op_id_desc_get(Eo_Op op); 31static const char * _eo_op_id_name_get(Eo_Op op);
32 32
33/* Start of Dich */ 33/* Start of Dich */
34 34
@@ -96,22 +96,27 @@ _dich_func_get(const _Eo_Class *klass, Eo_Op op)
96 return &chain1->funcs[DICH_CHAIN_LAST(op)]; 96 return &chain1->funcs[DICH_CHAIN_LAST(op)];
97} 97}
98 98
99static inline void 99static inline Eina_Bool
100_dich_func_set(_Eo_Class *klass, Eo_Op op, eo_op_func_type func) 100_dich_func_set(_Eo_Class *klass, Eo_Op op, eo_op_func_type func)
101{ 101{
102 op_type_funcs *fsrc;
102 size_t idx1 = DICH_CHAIN1(op); 103 size_t idx1 = DICH_CHAIN1(op);
103 Dich_Chain1 *chain1 = &klass->chain[idx1]; 104 Dich_Chain1 *chain1 = &klass->chain[idx1];
104 _dich_chain_alloc(chain1); 105 _dich_chain_alloc(chain1);
105 if (chain1->funcs[DICH_CHAIN_LAST(op)].src == klass) 106 fsrc = &chain1->funcs[DICH_CHAIN_LAST(op)];
107 if (fsrc->src == klass)
106 { 108 {
107 const _Eo_Class *op_kls = _eo_op_class_get(op); 109 const _Eo_Class *op_kls = _eo_op_class_get(op);
108 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op); 110 const char *op_name = _eo_op_id_name_get(op);
109 ERR("Already set function for op 0x%x (%s:%s). Overriding with func %p", 111 ERR("Class '%s': Overriding func %p for op %d (%s:'%s') with %p.",
110 op, op_kls->desc->name, op_desc->name, func); 112 klass->desc->name, fsrc->func, op, op_kls->desc->name, op_name, func);
113 return EINA_FALSE;
111 } 114 }
112 115
113 chain1->funcs[DICH_CHAIN_LAST(op)].func = func; 116 fsrc->func = func;
114 chain1->funcs[DICH_CHAIN_LAST(op)].src = klass; 117 fsrc->src = klass;
118
119 return EINA_TRUE;
115} 120}
116 121
117static inline void 122static inline void
@@ -131,20 +136,16 @@ _dich_func_clean_all(_Eo_Class *klass)
131 136
132/* END OF DICH */ 137/* END OF DICH */
133 138
134static const Eo_Op_Description noop_desc =
135 EO_OP_DESCRIPTION(EO_NOOP, "No operation.");
136
137
138static inline Eina_Bool 139static inline Eina_Bool
139_eo_is_a_class(const Eo *obj_id) 140_eo_is_a_class(const Eo *eo_id)
140{ 141{
141 Eo_Id oid; 142 Eo_Id oid;
142#ifdef HAVE_EO_ID 143#ifdef HAVE_EO_ID
143 oid = (Eo_Id) obj_id; 144 oid = (Eo_Id) eo_id;
144#else 145#else
145 /* fortunately EO_OBJ_POINTER_RETURN* will handle NULL obj_id */ 146 /* fortunately EO_OBJ_POINTER_RETURN* will handle NULL eo_id */
146 if (!obj_id) return EINA_FALSE; 147 if (!eo_id) return EINA_FALSE;
147 oid = ((Eo_Base *) obj_id)->id; 148 oid = ((Eo_Base *) eo_id)->id;
148#endif 149#endif
149 return (((oid >> REF_TAG_SHIFT) & 0x1) == 0x0); 150 return (((oid >> REF_TAG_SHIFT) & 0x1) == 0x0);
150} 151}
@@ -186,18 +187,24 @@ _eo_op_class_get(Eo_Op op)
186static const Eo_Op_Description * 187static const Eo_Op_Description *
187_eo_op_id_desc_get(Eo_Op op) 188_eo_op_id_desc_get(Eo_Op op)
188{ 189{
190 unsigned int i;
189 const _Eo_Class *klass; 191 const _Eo_Class *klass;
192 const Eo_Op_Description *op_descs;
190 193
191 if (op == EO_NOOP) 194 if (op == EO_NOOP)
192 return &noop_desc; 195 return NULL;
193 196
194 klass = _eo_op_class_get(op); 197 klass = _eo_op_class_get(op);
198 DBG("klass %p %s", klass, klass->desc->name);
195 199
196 if (klass) 200 if (klass)
197 { 201 {
198 Eo_Op sub_id = op - klass->base_id; 202 op_descs = klass->desc->ops.descs2;
199 if (sub_id < klass->desc->ops.count) 203 for (i = 0; i < klass->desc->ops.count; i++)
200 return klass->desc->ops.descs + sub_id; 204 {
205 if (op_descs[i].op == op)
206 return &op_descs[i];
207 }
201 } 208 }
202 209
203 return NULL; 210 return NULL;
@@ -207,10 +214,10 @@ static const char *
207_eo_op_id_name_get(Eo_Op op) 214_eo_op_id_name_get(Eo_Op op)
208{ 215{
209 const Eo_Op_Description *desc = _eo_op_id_desc_get(op); 216 const Eo_Op_Description *desc = _eo_op_id_desc_get(op);
210 return (desc) ? desc->name : NULL; 217 return (desc) ? desc->doc : NULL;
211} 218}
212 219
213static inline const _Eo_Class * 220static inline const op_type_funcs *
214_eo_kls_itr_next(const _Eo_Class *orig_kls, const _Eo_Class *cur_klass, Eo_Op op) 221_eo_kls_itr_next(const _Eo_Class *orig_kls, const _Eo_Class *cur_klass, Eo_Op op)
215{ 222{
216 const _Eo_Class **kls_itr = NULL; 223 const _Eo_Class **kls_itr = NULL;
@@ -231,241 +238,607 @@ _eo_kls_itr_next(const _Eo_Class *orig_kls, const _Eo_Class *cur_klass, Eo_Op op
231 kls_itr++; 238 kls_itr++;
232 continue; 239 continue;
233 } 240 }
234 return fsrc->src; 241 return fsrc;
235 } 242 }
236 } 243 }
237 244
238 return NULL; 245 return NULL;
239} 246}
240 247
241static inline const op_type_funcs * 248/************************************ EO ************************************/
242_eo_kls_itr_func_get(const _Eo_Class *cur_klass, Eo_Op op) 249
250EAPI Eo_Hook_Call eo_hook_call_pre = NULL;
251EAPI Eo_Hook_Call eo_hook_call_post = NULL;
252
253// FIXME: Thread Local Storage
254#define EO_INVALID_DATA (void *) -1
255#define EO_CALL_STACK_DEPTH 30
256
257typedef struct _Eo_Stack_Frame
243{ 258{
244 const _Eo_Class *klass = cur_klass; 259 const Eo *eo_id;
245 if (klass) 260 union {
261 _Eo_Object *obj;
262 const _Eo_Class *kls;
263 } o;
264 const _Eo_Class *cur_klass;
265 void *obj_data;
266} Eo_Stack_Frame;
267
268static Eina_TLS _eo_call_stack_key = 0;
269
270typedef struct _Eo_Call_Stack {
271 Eo_Stack_Frame *frames;
272 Eo_Stack_Frame *frame_ptr;
273 Eo_Stack_Frame *last_frame;
274 Eo_Stack_Frame *shrink_frame;
275} Eo_Call_Stack;
276
277static Eo_Call_Stack *
278_eo_call_stack_create()
279{
280 Eo_Call_Stack *stack;
281
282 stack = calloc(1, sizeof(Eo_Call_Stack));
283 if (!stack)
284 return NULL;
285
286 stack->frames = calloc(EO_CALL_STACK_DEPTH, sizeof(Eo_Stack_Frame));
287 if (!stack->frames)
246 { 288 {
247 const op_type_funcs *func = _dich_func_get(klass, op); 289 free(stack);
290 return NULL;
291 }
248 292
249 if (func && func->func) 293 // first frame is never used
250 { 294 stack->frame_ptr = stack->frames;
251 return func; 295 stack->last_frame = &stack->frames[EO_CALL_STACK_DEPTH - 1];
252 } 296 stack->shrink_frame = stack->frames;
297
298 return stack;
299}
300
301static void
302_eo_call_stack_free(void *ptr)
303{
304 Eo_Call_Stack *stack = (Eo_Call_Stack *) ptr;
305
306 if (!stack) return;
307
308 if (stack->frames)
309 free(stack->frames);
310 free(stack);
311}
312
313static inline Eo_Call_Stack *
314_eo_call_stack_get()
315{
316 Eo_Call_Stack *stack = eina_tls_get(_eo_call_stack_key);
317
318 if (stack) return stack;
319
320 stack = _eo_call_stack_create();
321 if (!stack)
322 {
323 EINA_LOG_ERR("Could not alloc eo call stack.");
324 return NULL;
253 } 325 }
254 326
255 return NULL; 327 if (!eina_tls_set(_eo_call_stack_key, stack))
328 {
329 EINA_LOG_ERR("Could not set eo call stack in TLS key.");
330 _eo_call_stack_free(stack);
331 return NULL;
332 }
333
334 return stack;
256} 335}
257 336
258#define _EO_OP_ERR_NO_OP_PRINT(file, line, op, klass) \ 337static inline void
259 do \ 338_eo_call_stack_resize(Eo_Call_Stack *stack, Eina_Bool grow)
260 { \ 339{
261 const _Eo_Class *op_klass = _eo_op_class_get(op); \ 340 size_t sz, next_sz;
262 const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; \ 341 int frame_offset;
263 ERR("in %s:%d: Can't execute function %s:%s (op 0x%x) for class '%s'. Aborting.", \ 342
264 file, line, _dom_name, _eo_op_id_name_get(op), op, \ 343 frame_offset = stack->frame_ptr - stack->frames;
265 (klass) ? klass->desc->name : NULL); \ 344 sz = stack->last_frame - stack->frames + 1;
266 } \ 345 if (grow)
267 while (0) 346 next_sz = sz << 1;
347 else
348 next_sz = sz >> 1;
349
350 DBG("resize from %lu to %lu", (long unsigned int)sz, (long unsigned int)next_sz);
351 stack->frames = realloc(stack->frames, next_sz * sizeof(Eo_Stack_Frame));
352 if(!stack->frames)
353 {
354 CRI("unable to resize call stack, abort.");
355 abort();
356 }
357
358 stack->frame_ptr = &stack->frames[frame_offset];
359 stack->last_frame = &stack->frames[next_sz - 1];
360
361 if (grow)
362 frame_offset = (sz >> 1);
363 if (next_sz == EO_CALL_STACK_DEPTH)
364 frame_offset = 0;
365 else
366 frame_offset = (next_sz >> 1);
367 stack->shrink_frame = &stack->frames[frame_offset];
368}
268 369
269static inline Eina_Bool 370static inline Eina_Bool
270_eo_op_internal(const char *file, int line, Eo_Base *eo_ptr, const _Eo_Class *cur_klass, 371_eo_do_internal(const Eo *eo_id, const Eo_Class *cur_klass_id,
271 Eo_Op_Type op_type, Eo_Op op, va_list *p_list) 372 Eina_Bool is_super, Eo_Stack_Frame *fptr, Eo_Stack_Frame *pfptr)
272{ 373{
273#ifdef EO_DEBUG 374 Eina_Bool is_klass = _eo_is_a_class(eo_id);
274 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
275 375
276 if (op_desc && (op_type != op_desc->op_type)) 376 /* If we are already in the same object context, we inherit info from it. */
377 if (pfptr)
378 {
379 memcpy(fptr, pfptr, sizeof(Eo_Stack_Frame));
380 if (!is_klass)
381 _eo_ref(fptr->o.obj);
382 }
383 else
277 { 384 {
278 if (op_type == EO_OP_TYPE_REGULAR) 385 fptr->eo_id = eo_id;
386 fptr->obj_data = EO_INVALID_DATA;
387 if (is_klass)
279 { 388 {
280 ERR("in %s:%d: Tried calling a class op '%s' (0x%x) from a non-class context.", 389 EO_CLASS_POINTER_RETURN_VAL(eo_id, _klass, EINA_FALSE);
281 file, line, op_desc->name, op); 390 fptr->o.kls = _klass;
282 } 391 }
283 else 392 else
284 { 393 {
285 ERR("in %s:%d: Tried calling an instance op '%s' (0x%x) from a class context.", 394 EO_OBJ_POINTER_RETURN_VAL(eo_id, _obj, EINA_FALSE);
286 file, line, op_desc->name, op); 395 fptr->o.obj = _obj;
396 _eo_ref(_obj);
287 } 397 }
398 }
399
400 if (is_super)
401 {
402 EO_CLASS_POINTER_RETURN_VAL(cur_klass_id, cur_klass, EINA_FALSE);
403 if (fptr->cur_klass == cur_klass)
404 fptr->obj_data = EO_INVALID_DATA;
405 fptr->cur_klass = cur_klass;
406 }
407 else
408 {
409 fptr->cur_klass = NULL;
410 }
411
412 return EINA_TRUE;
413}
414
415EAPI Eina_Bool
416_eo_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super, const char *file EINA_UNUSED, const char *func EINA_UNUSED, int line EINA_UNUSED)
417{
418 Eo_Stack_Frame *fptr, *pfptr;
419 Eo_Call_Stack *stack = _eo_call_stack_get();
420
421 if (stack->frame_ptr == stack->last_frame)
422 _eo_call_stack_resize(stack, EINA_TRUE);
423
424 fptr = stack->frame_ptr;
425
426 pfptr = ((eo_id) && (fptr->eo_id == eo_id) ? fptr : NULL);
427 fptr++;
428
429 if (!_eo_do_internal(eo_id, cur_klass_id, is_super, fptr, pfptr))
430 return EINA_FALSE;
431
432 stack->frame_ptr++;
433
434 return EINA_TRUE;
435}
436
437EAPI void
438_eo_do_end(const Eo **eo_id EINA_UNUSED)
439{
440 Eo_Stack_Frame *fptr;
441 Eo_Call_Stack *stack = _eo_call_stack_get();
442
443 fptr = stack->frame_ptr;
444
445 if (!_eo_is_a_class(fptr->eo_id) && fptr->o.obj)
446 _eo_unref(fptr->o.obj);
447
448 fptr->obj_data = EO_INVALID_DATA;
449
450 if (fptr == stack->frames)
451 {
452 CRI("call stack underflow, abort.");
453 abort();
454 }
455
456 stack->frame_ptr--;
457
458 if (fptr == stack->shrink_frame)
459 _eo_call_stack_resize(stack, EINA_FALSE);
460}
461
462EAPI Eina_Bool
463_eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, const char *file, int line)
464{
465 Eo_Stack_Frame *fptr;
466 const _Eo_Class *klass;
467 const op_type_funcs *func;
468 Eina_Bool is_obj;
469
470 if (op == EO_NOOP) return EINA_FALSE;
471
472 fptr = _eo_call_stack_get()->frame_ptr;
473 is_obj = !_eo_is_a_class(fptr->eo_id);
474
475 klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls;
476
477 /* If we have a current class, we need to itr to the next. */
478 if (fptr->cur_klass)
479 {
480 func = _eo_kls_itr_next(klass, fptr->cur_klass, op);
481
482 if (!func)
483 goto end;
484
485 klass = func->src;
486 }
487 else
488 {
489 func = _dich_func_get(klass, op);
490 }
491
492 if (EINA_UNLIKELY(func == NULL))
493 {
494 ERR("in %s:%d: you called func '%s' (%d) which is unknown in class '%s'.",
495 file, line, func_name, op, klass->desc->name);
288 return EINA_FALSE; 496 return EINA_FALSE;
289 } 497 }
290#endif
291 498
499 if (EINA_LIKELY(func->func && func->src))
292 { 500 {
293 const op_type_funcs *func = _eo_kls_itr_func_get(cur_klass, op); 501 call->func = func->func;
294 if (EINA_LIKELY(func != NULL)) 502 call->klass = _eo_class_id_get(klass);
503
504 if (is_obj)
295 { 505 {
296 void *func_data = NULL; 506 call->obj = (Eo *)fptr->eo_id;
297 Eo *calling_obj; 507 if (func->src == fptr->o.obj->klass)
298 if (op_type == EO_OP_TYPE_REGULAR)
299 { 508 {
300 func_data = _eo_data_scope_get((_Eo_Object *) eo_ptr, func->src); 509 if (fptr->obj_data == EO_INVALID_DATA)
301 calling_obj = _eo_id_get((_Eo_Object *) eo_ptr); 510 fptr->obj_data = _eo_data_scope_get(fptr->o.obj, func->src);
511
512 call->data = fptr->obj_data;
302 } 513 }
303 else 514 else
515 call->data = _eo_data_scope_get(fptr->o.obj, func->src);
516 }
517 else
518 {
519 call->obj = call->klass;
520 call->data = NULL;
521 }
522
523 return EINA_TRUE;
524 }
525
526 if (func->src != NULL)
527 {
528 ERR("in %s:%d: you called a pure virtual func '%s' (%d).",
529 file, line, func_name, op);
530 return EINA_FALSE;
531 }
532
533
534end:
535 /* Try composite objects */
536 if (is_obj)
537 {
538 const _Eo_Object **comp_itr = fptr->o.obj->composites;
539 if (!comp_itr) goto end2;
540
541 for (unsigned int i = 0; i < fptr->o.obj->klass->composites_count; i++, comp_itr++)
542 {
543 const _Eo_Object *emb_obj = *comp_itr;
544
545 func = _dich_func_get(emb_obj->klass, op);
546 if (func == NULL)
547 continue;
548
549 if (EINA_LIKELY(func->func && func->src))
304 { 550 {
305 calling_obj = _eo_class_id_get(cur_klass); 551 call->obj = _eo_id_get(emb_obj);
552 call->klass = _eo_class_id_get(emb_obj->klass);
553 call->func = func->func;
554 call->data = _eo_data_scope_get(emb_obj, func->src);
555
556 return EINA_TRUE;
306 } 557 }
307 func->func(calling_obj, func_data, p_list);
308 return EINA_TRUE;
309 } 558 }
310 } 559 }
311 560
312 /* Try composite objects */ 561end2:
313 if (op_type == EO_OP_TYPE_REGULAR)
314 { 562 {
315 const _Eo_Object **comp_itr = ((_Eo_Object *) eo_ptr)->composites; 563 const _Eo_Class *main_klass;
316 if (!comp_itr) return EINA_FALSE; 564 main_klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls;
317 565
318 for (unsigned int i = 0; i < ((_Eo_Object *) eo_ptr)->klass->composites_count; i++, comp_itr++) 566 /* If it's a do_super call. */
319 if (*comp_itr) 567 if (fptr->cur_klass)
320 { 568 {
321 if (_eo_op_internal(file, line, (Eo_Base *) (*comp_itr), (*comp_itr)->klass, op_type, op, p_list)) 569 ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s' for super of '%s'.",
322 { 570 file, line, func_name, op, main_klass->desc->name,
323 return EINA_TRUE; 571 fptr->cur_klass->desc->name);
324 } 572 }
325 } 573 else
574 {
575 /* we should not be able to take this branch */
576 ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s'.",
577 file, line, func_name, op, main_klass->desc->name);
578 }
326 } 579 }
327 580
328 return EINA_FALSE; 581 return EINA_FALSE;
329} 582}
330 583
331static inline Eina_Bool 584
332_eo_dov_internal(const char *file, int line, Eo_Base *obj, const _Eo_Class *klass, Eo_Op_Type op_type, va_list *p_list) 585static inline const Eo_Op_Description *
586_eo_api_desc_get(const void *api_func, const _Eo_Class *klass, const _Eo_Class **extns)
333{ 587{
334 Eina_Bool ret = EINA_TRUE; 588 int imin, imax, imid;
335 Eo_Op op = EO_NOOP; 589 const _Eo_Class *cur_klass;
590 const _Eo_Class **kls_itr = NULL;
591 const Eo_Op_Description *op_desc;
592 const Eo_Op_Description *op_descs;
336 593
337 op = va_arg(*p_list, Eo_Op); 594 if (klass)
338 while (op)
339 { 595 {
340 if (!_eo_op_internal(file, line, obj, klass, op_type, op, p_list)) 596 for (kls_itr = klass->mro ; *kls_itr ; kls_itr++)
341 { 597 {
342 _EO_OP_ERR_NO_OP_PRINT(file, line, op, klass); 598 cur_klass = *kls_itr;
343 ret = EINA_FALSE; 599 imin = 0;
344 break; 600 imax = cur_klass->desc->ops.count - 1;
601 op_descs = cur_klass->desc->ops.descs2;
602
603 while (imax >= imin)
604 {
605 imid = (imax + imin) / 2;
606 op_desc = op_descs + imid;
607
608 if (op_desc->api_func > api_func)
609 imin = imid + 1;
610 else if (op_desc->api_func < api_func)
611 imax = imid - 1;
612 else
613 return op_desc;
614 }
615
345 } 616 }
346 op = va_arg(*p_list, Eo_Op);
347 } 617 }
348 618
349 return ret; 619 if (extns)
620 {
621 for (kls_itr = extns ; *kls_itr ; kls_itr++)
622 {
623 cur_klass = *kls_itr;
624 op_desc = _eo_api_desc_get(api_func, cur_klass, NULL);
625 if (op_desc) return op_desc;
626 }
627 }
628
629 return NULL;
350} 630}
351 631
352static inline Eina_Bool 632EAPI Eo_Op
353_eo_obj_dov_internal(const char *file, int line, _Eo_Object *obj, va_list *p_list) 633_eo_api_op_id_get(const void *api_func, const char *file, int line)
354{ 634{
355 Eina_Bool prev_error; 635 const Eo_Op_Description *desc;
356 Eina_Bool ret = EINA_TRUE; 636 const _Eo_Class *klass;
637 Eo_Call_Stack *stack = _eo_call_stack_get();
357 638
358 prev_error = obj->do_error; 639 Eina_Bool class_ref = _eo_is_a_class(stack->frame_ptr->eo_id);
359 _eo_ref(obj);
360 640
361 ret = _eo_dov_internal(file, line, (Eo_Base *) obj, obj->klass, EO_OP_TYPE_REGULAR, p_list); 641 if (class_ref)
642 klass = stack->frame_ptr->o.kls;
643 else
644 klass = stack->frame_ptr->o.obj->klass;
362 645
363 if (obj->do_error) 646 desc = _eo_api_desc_get(api_func, klass, klass->extensions);
364 ret = EINA_FALSE;
365 647
366 obj->do_error = prev_error; 648 if (desc == NULL)
367 _eo_unref(obj); 649 {
650 ERR("in %s:%d: unable to resolve %s api func %p.",
651 file, line, (class_ref ? "class" : "regular"), api_func);
652 return EO_NOOP;
653 }
368 654
369 return ret; 655 return desc->op;
370} 656}
371 657
372static inline Eina_Bool 658static int
373_eo_class_dov_internal(const char *file, int line, _Eo_Class *klass, va_list *p_list) 659eo_api_funcs_cmp(const void *p1, const void *p2)
374{ 660{
375 return _eo_dov_internal(file, line, (Eo_Base *) klass, klass, EO_OP_TYPE_CLASS, p_list); 661 const Eo_Op_Description *op1, *op2;
662 op1 = (Eo_Op_Description *) p1;
663 op2 = (Eo_Op_Description *) p2;
664 if (op1->api_func > op2->api_func) return -1;
665 else if (op1->api_func < op2->api_func) return 1;
666 else return 0;
376} 667}
377 668
378EAPI Eina_Bool 669static Eina_Bool
379eo_do_internal(const char *file, int line, const Eo *obj_id, ...) 670_eo_class_funcs_set(_Eo_Class *klass)
380{ 671{
381 Eina_Bool ret = EINA_TRUE; 672 int op_id;
382 va_list p_list; 673 const void *last_api_func;
383 Eina_Bool class_ref = _eo_is_a_class(obj_id); 674 const Eo_Op_Description *api_desc;
675 Eo_Op_Description *op_desc;
676 Eo_Op_Description *op_descs;
384 677
385 if (class_ref) 678 op_id = klass->base_id;
386 { 679 op_descs = klass->desc->ops.descs2;
387 EO_CLASS_POINTER_RETURN_VAL(obj_id, klass, EINA_FALSE);
388 680
389 va_start(p_list, obj_id); 681 DBG("Set functions for class '%s':%p", klass->desc->name, klass);
390 ret = _eo_class_dov_internal(file, line, klass, &p_list); 682
391 va_end(p_list); 683 if (!op_descs) return EINA_TRUE;
392 } 684
393 else 685 qsort((void*)op_descs, klass->desc->ops.count, sizeof(Eo_Op_Description), eo_api_funcs_cmp);
686
687 last_api_func = NULL;
688 for (op_desc = op_descs; op_desc->op_type != EO_OP_TYPE_INVALID; op_desc++)
394 { 689 {
395 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE); 690 if(op_desc->api_func == NULL)
691 {
692 ERR("Class '%s': NULL API not allowed (%d NULL->%p '%s').",
693 klass->desc->name, op_desc->op, op_desc->func, op_desc->doc);
694 return EINA_FALSE;
695 }
396 696
397 va_start(p_list, obj_id); 697 if (op_desc->op == EO_NOOP)
398 ret = _eo_obj_dov_internal(file, line, obj, &p_list); 698 {
399 va_end(p_list); 699 if (op_desc->api_func == last_api_func)
700 {
701 ERR("Class '%s': API previously defined (%d %p->%p '%s').",
702 klass->desc->name, op_desc->op, op_desc->api_func, op_desc->func, op_desc->doc);
703 return EINA_FALSE;
704 }
705 op_desc->op = op_id;
706 op_id++;
707 }
708 else if (op_desc->op == EO_OP_OVERRIDE)
709 {
710 api_desc = _eo_api_desc_get(op_desc->api_func, klass->parent, klass->extensions);
711
712 if (api_desc == NULL)
713 {
714 ERR("Class '%s': Can't find api func description in class hierarchy (%p->%p) (%s).",
715 klass->desc->name, op_desc->api_func, op_desc->func, op_desc->doc);
716 return EINA_FALSE;
717 }
718
719 op_desc->op = api_desc->op;
720 op_desc->doc = api_desc->doc;
721 }
722
723 DBG(" %4d %p->%p '%s'", op_desc->op, op_desc->api_func, op_desc->func, op_desc->doc);
724
725 if (!_dich_func_set(klass, op_desc->op, op_desc->func))
726 return EINA_FALSE;
727
728 last_api_func = op_desc->api_func;
400 } 729 }
401 730
402 return ret; 731 return EINA_TRUE;
403} 732}
404 733
405EAPI Eina_Bool 734EAPI Eo *
406eo_vdo_internal(const char *file, int line, const Eo *obj_id, va_list *ops) 735_eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo *parent_id)
407{ 736{
408 Eina_Bool class_ref = _eo_is_a_class(obj_id); 737 _Eo_Object *obj;
409 738
410 if (class_ref) 739 EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, NULL);
740
741 if (parent_id)
742 {
743 EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, NULL);
744 }
745
746 if (EINA_UNLIKELY(klass->desc->type != EO_CLASS_TYPE_REGULAR))
747 {
748 ERR("in %s:%d: Class '%s' is not instantiate-able. Aborting.", file, line, klass->desc->name);
749 return NULL;
750 }
751
752 eina_spinlock_take(&klass->objects.trash_lock);
753 obj = eina_trash_pop(&klass->objects.trash);
754 if (obj)
411 { 755 {
412 EO_CLASS_POINTER_RETURN_VAL(obj_id, klass, EINA_FALSE); 756 memset(obj, 0, klass->obj_size);
413 return _eo_class_dov_internal(file, line, klass, ops); 757 klass->objects.trash_count--;
414 } 758 }
415 else 759 else
416 { 760 {
417 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE); 761 obj = calloc(1, klass->obj_size);
418 return _eo_obj_dov_internal(file, line, obj, ops);
419 } 762 }
763 eina_spinlock_release(&klass->objects.trash_lock);
764
765 obj->refcount++;
766 obj->klass = klass;
767 if (klass->composites_count == 0)
768 obj->composites = NULL;
769 else
770 obj->composites = (const _Eo_Object **)
771 ((char *) obj + klass->obj_size - (klass->composites_count * sizeof(_Eo_Object *)));
772
773#ifndef HAVE_EO_ID
774 EINA_MAGIC_SET((Eo_Base *) obj, EO_EINA_MAGIC);
775#endif
776 Eo_Id eo_id = _eo_id_allocate(obj);
777 obj->header.id = eo_id;
778
779 _eo_condtor_reset(obj);
780
781 _eo_ref(obj);
782
783 eo_do(_eo_id_get(obj), eo_parent_set(parent_id));
784
785 return _eo_id_get(obj);
420} 786}
421 787
422EAPI Eina_Bool 788EAPI Eo *
423eo_do_super_internal(const char *file, int line, const Eo *obj_id, const Eo_Class *cur_klass_id, Eo_Op op, ...) 789_eo_add_internal_end(const char *file, int line, const Eo *eo_id)
424{ 790{
425 const _Eo_Class *nklass; 791 Eo_Stack_Frame *fptr;
426 Eina_Bool op_ret = EINA_TRUE; 792 Eo_Call_Stack *stack = _eo_call_stack_get();
427 Eina_Bool ret = EINA_TRUE;
428 va_list p_list;
429 793
430 EO_CLASS_POINTER_RETURN_VAL(cur_klass_id, cur_klass, EINA_FALSE); 794 fptr = stack->frame_ptr;
431 795
432 if (_eo_is_a_class(obj_id)) 796 if ((fptr == NULL) || (fptr->eo_id != eo_id))
433 { 797 {
434 EO_CLASS_POINTER_RETURN_VAL(obj_id, klass, EINA_FALSE); 798 ERR("in %s:%d - Something very wrong happend to the call stack.", file, line);
435 799 return NULL;
436 va_start(p_list, op);
437 nklass = _eo_kls_itr_next(klass, cur_klass, op);
438 op_ret = _eo_op_internal(file, line, (Eo_Base *) klass, nklass, EO_OP_TYPE_CLASS, op, &p_list);
439 va_end(p_list);
440 } 800 }
441 else
442 {
443 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
444 801
445 va_start(p_list, op); 802 if (!fptr->o.obj->condtor_done || fptr->o.obj->do_error)
446 nklass = _eo_kls_itr_next(obj->klass, cur_klass, op); 803 {
447 op_ret = _eo_op_internal(file, line, (Eo_Base *) obj, nklass, EO_OP_TYPE_REGULAR, op, &p_list); 804 const _Eo_Class *klass = (fptr->cur_klass) ?
448 if (obj->do_error) 805 fptr->cur_klass : fptr->o.obj->klass;
449 ret = EINA_FALSE; 806 ERR("in %s:%d: Object of class '%s' - Not all of the object constructors have been executed.",
450 va_end(p_list); 807 file, line, klass->desc->name);
808 /* Unref twice, once for the ref in _eo_add_internal_start, and once for the basic object ref. */
809 _eo_unref(fptr->o.obj);
810 _eo_unref(fptr->o.obj);
811 return NULL;
451 } 812 }
452 813
453 if (!op_ret) 814 _eo_unref(fptr->o.obj);
454 _EO_OP_ERR_NO_OP_PRINT(file, line, op, nklass);
455 815
456 return (ret & op_ret); 816 return (Eo *)eo_id;
457} 817}
458 818
819/*****************************************************************************/
820
821#define _EO_OP_ERR_NO_OP_PRINT(file, line, op, klass) \
822 do \
823 { \
824 const _Eo_Class *op_klass = _eo_op_class_get(op); \
825 const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; \
826 ERR("in %s:%d: Can't execute function %s:%s (op 0x%x) for class '%s'. Aborting.", \
827 file, line, _dom_name, _eo_op_id_name_get(op), op, \
828 (klass) ? klass->desc->name : NULL); \
829 } \
830 while (0)
831
459EAPI const Eo_Class * 832EAPI const Eo_Class *
460eo_class_get(const Eo *obj_id) 833eo_class_get(const Eo *eo_id)
461{ 834{
462 if (_eo_is_a_class(obj_id)) 835 if (_eo_is_a_class(eo_id))
463 { 836 {
464 EO_CLASS_POINTER_RETURN_VAL(obj_id, _klass, NULL); 837 EO_CLASS_POINTER_RETURN_VAL(eo_id, _klass, NULL);
465 return eo_class_class_get(); 838 return eo_class_class_get();
466 } 839 }
467 840
468 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL); 841 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, NULL);
469 842
470 if (obj->klass) 843 if (obj->klass)
471 return _eo_class_id_get(obj->klass); 844 return _eo_class_id_get(obj->klass);
@@ -473,18 +846,18 @@ eo_class_get(const Eo *obj_id)
473} 846}
474 847
475EAPI const char * 848EAPI const char *
476eo_class_name_get(const Eo_Class *obj_id) 849eo_class_name_get(const Eo_Class *eo_id)
477{ 850{
478 const _Eo_Class *klass; 851 const _Eo_Class *klass;
479 852
480 if (_eo_is_a_class(obj_id)) 853 if (_eo_is_a_class(eo_id))
481 { 854 {
482 EO_CLASS_POINTER_RETURN_VAL(obj_id, _klass, NULL); 855 EO_CLASS_POINTER_RETURN_VAL(eo_id, _klass, NULL);
483 klass = _klass; 856 klass = _klass;
484 } 857 }
485 else 858 else
486 { 859 {
487 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL); 860 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, NULL);
488 klass = obj->klass; 861 klass = obj->klass;
489 } 862 }
490 863
@@ -498,9 +871,6 @@ _eo_class_base_op_init(_Eo_Class *klass)
498 871
499 klass->base_id = _eo_ops_last_id; 872 klass->base_id = _eo_ops_last_id;
500 873
501 if (desc->ops.base_op_id)
502 *(desc->ops.base_op_id) = klass->base_id;
503
504 _eo_ops_last_id += desc->ops.count + 1; 874 _eo_ops_last_id += desc->ops.count + 1;
505 875
506 klass->chain_size = DICH_CHAIN1(_eo_ops_last_id) + 1; 876 klass->chain_size = DICH_CHAIN1(_eo_ops_last_id) + 1;
@@ -632,46 +1002,12 @@ static void
632_eo_class_constructor(_Eo_Class *klass) 1002_eo_class_constructor(_Eo_Class *klass)
633{ 1003{
634 if (klass->constructed) 1004 if (klass->constructed)
635 return; 1005 return;
636 1006
637 klass->constructed = EINA_TRUE; 1007 klass->constructed = EINA_TRUE;
638 1008
639 if (klass->desc->class_constructor) 1009 if (klass->desc->class_constructor)
640 klass->desc->class_constructor(_eo_class_id_get(klass)); 1010 klass->desc->class_constructor(_eo_class_id_get(klass));
641}
642
643EAPI void
644eo_class_funcs_set(Eo_Class *klass_id, const Eo_Op_Func_Description *func_descs)
645{
646 EO_CLASS_POINTER_RETURN(klass_id, klass);
647
648 const Eo_Op_Func_Description *itr;
649 itr = func_descs;
650 if (itr)
651 {
652 for ( ; itr->op_type != EO_OP_TYPE_INVALID ; itr++)
653 {
654 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(itr->op);
655
656 if (EINA_UNLIKELY(!op_desc || (itr->op == EO_NOOP)))
657 {
658 ERR("Setting implementation for non-existent op 0x%x for class '%s'. Func index: %lu", itr->op, klass->desc->name, (unsigned long) (itr - func_descs));
659 }
660 else if (EINA_LIKELY(itr->op_type == op_desc->op_type))
661 {
662 _dich_func_set(klass, itr->op, itr->func);
663 }
664 else
665 {
666 ERR("Set function's op type (0x%x) is different than the one in the op description (%d) for op '%s:%s'. Func index: %lu",
667 itr->op_type,
668 (op_desc) ? op_desc->op_type : EO_OP_TYPE_REGULAR,
669 klass->desc->name,
670 (op_desc) ? op_desc->name : NULL,
671 (unsigned long) (itr - func_descs));
672 }
673 }
674 }
675} 1011}
676 1012
677static void 1013static void
@@ -699,59 +1035,9 @@ eo_class_free(_Eo_Class *klass)
699 free(klass); 1035 free(klass);
700} 1036}
701 1037
702/* DEVCHECK */
703static Eina_Bool
704_eo_class_check_op_descs(const Eo_Class_Description *desc)
705{
706 const Eo_Op_Description *itr;
707 size_t i;
708
709 if (desc->ops.count > 0)
710 {
711 if (!desc->ops.base_op_id)
712 {
713 ERR("Class '%s' has a non-zero ops count, but base_id is NULL.",
714 desc->name);
715 return EINA_FALSE;
716 }
717
718 if (!desc->ops.descs)
719 {
720 ERR("Class '%s' has a non-zero ops count, but there are no descs.",
721 desc->name);
722 return EINA_FALSE;
723 }
724 }
725
726 itr = desc->ops.descs;
727 for (i = 0 ; i < desc->ops.count ; i++, itr++)
728 {
729 if (itr->sub_op != i)
730 {
731 if (itr->name)
732 {
733 ERR("Wrong order in Ops description for class '%s'. Expected 0x%lx and got 0x%lx", desc->name, (unsigned long) i, (unsigned long) itr->sub_op);
734 }
735 else
736 {
737 ERR("Found too few Ops description for class '%s'. Expected 0x%lx descriptions, but found 0x%lx.", desc->name, (unsigned long) desc->ops.count, (unsigned long) i);
738 }
739 return EINA_FALSE;
740 }
741 }
742
743 if (itr && itr->name)
744 {
745 ERR("Found extra Ops description for class '%s'. Expected %lu descriptions, but found more.", desc->name, (unsigned long) desc->ops.count);
746 return EINA_FALSE;
747 }
748
749 return EINA_TRUE;
750}
751
752/* Not really called, just used for the ptr... */ 1038/* Not really called, just used for the ptr... */
753static void 1039static void
754_eo_class_isa_func(Eo *obj_id EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED) 1040_eo_class_isa_func(Eo *eo_id EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
755{ 1041{
756 /* Do nonthing. */ 1042 /* Do nonthing. */
757} 1043}
@@ -767,11 +1053,6 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
767 EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL); 1053 EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL);
768 EINA_SAFETY_ON_NULL_RETURN_VAL(desc->name, NULL); 1054 EINA_SAFETY_ON_NULL_RETURN_VAL(desc->name, NULL);
769 1055
770 DBG("Started building class '%s'", desc->name);
771
772 if (!_eo_class_check_op_descs(desc))
773 return NULL;
774
775 _Eo_Class *parent = _eo_class_pointer_get(parent_id); 1056 _Eo_Class *parent = _eo_class_pointer_get(parent_id);
776#ifndef HAVE_EO_ID 1057#ifndef HAVE_EO_ID
777 if (parent && !EINA_MAGIC_CHECK((Eo_Base *) parent, EO_CLASS_EINA_MAGIC)) 1058 if (parent && !EINA_MAGIC_CHECK((Eo_Base *) parent, EO_CLASS_EINA_MAGIC))
@@ -972,6 +1253,7 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
972 } 1253 }
973 1254
974 _eo_class_base_op_init(klass); 1255 _eo_class_base_op_init(klass);
1256
975 /* Flatten the function array */ 1257 /* Flatten the function array */
976 { 1258 {
977 const _Eo_Class **mro_itr = klass->mro; 1259 const _Eo_Class **mro_itr = klass->mro;
@@ -1008,6 +1290,15 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
1008 } 1290 }
1009 } 1291 }
1010 1292
1293 if (!_eo_class_funcs_set(klass))
1294 {
1295 eina_spinlock_free(&klass->objects.trash_lock);
1296 eina_spinlock_free(&klass->iterators.trash_lock);
1297 _dich_func_clean_all(klass);
1298 free(klass);
1299 return NULL;
1300 }
1301
1011 eina_spinlock_take(&_eo_class_creation_lock); 1302 eina_spinlock_take(&_eo_class_creation_lock);
1012 klass->header.id = ++_eo_classes_last_id | MASK_CLASS_TAG; 1303 klass->header.id = ++_eo_classes_last_id | MASK_CLASS_TAG;
1013 { 1304 {
@@ -1033,9 +1324,9 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
1033} 1324}
1034 1325
1035EAPI Eina_Bool 1326EAPI Eina_Bool
1036eo_isa(const Eo *obj_id, const Eo_Class *klass_id) 1327eo_isa(const Eo *eo_id, const Eo_Class *klass_id)
1037{ 1328{
1038 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE); 1329 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
1039 EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE); 1330 EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE);
1040 const op_type_funcs *func = _dich_func_get(obj->klass, 1331 const op_type_funcs *func = _dich_func_get(obj->klass,
1041 klass->base_id + klass->desc->ops.count); 1332 klass->base_id + klass->desc->ops.count);
@@ -1045,103 +1336,6 @@ eo_isa(const Eo *obj_id, const Eo_Class *klass_id)
1045 return (func && (func->func == _eo_class_isa_func)); 1336 return (func && (func->func == _eo_class_isa_func));
1046} 1337}
1047 1338
1048// A little bit hacky, but does the job
1049static void
1050_eo_parent_internal_set(_Eo_Object *obj, ...)
1051{
1052 va_list p_list;
1053
1054 va_start(p_list, obj);
1055 _eo_op_internal(__FILE__, __LINE__, (Eo_Base *) obj, obj->klass,
1056 EO_OP_TYPE_REGULAR, EO_BASE_ID(EO_BASE_SUB_ID_PARENT_SET),
1057 &p_list);
1058 va_end(p_list);
1059}
1060
1061EAPI Eo *
1062eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent_id, ...)
1063{
1064 Eina_Bool do_err;
1065 _Eo_Object *obj;
1066 EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, NULL);
1067
1068 if (parent_id)
1069 {
1070 EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, NULL);
1071 }
1072
1073 if (EINA_UNLIKELY(klass->desc->type != EO_CLASS_TYPE_REGULAR))
1074 {
1075 ERR("in %s:%d: Class '%s' is not instantiate-able. Aborting.", file, line, klass->desc->name);
1076 return NULL;
1077 }
1078
1079 eina_spinlock_take(&klass->objects.trash_lock);
1080 obj = eina_trash_pop(&klass->objects.trash);
1081 if (obj)
1082 {
1083 memset(obj, 0, klass->obj_size);
1084 klass->objects.trash_count--;
1085 }
1086 else
1087 {
1088 obj = calloc(1, klass->obj_size);
1089 }
1090 eina_spinlock_release(&klass->objects.trash_lock);
1091
1092 obj->refcount++;
1093 obj->klass = klass;
1094 if (klass->composites_count == 0)
1095 obj->composites = NULL;
1096 else
1097 obj->composites = (const _Eo_Object **)
1098 ((char *) obj + klass->obj_size - (klass->composites_count * sizeof(_Eo_Object *)));
1099
1100#ifndef HAVE_EO_ID
1101 EINA_MAGIC_SET((Eo_Base *) obj, EO_EINA_MAGIC);
1102#endif
1103 Eo_Id obj_id = _eo_id_allocate(obj);
1104 obj->header.id = obj_id;
1105
1106 _eo_condtor_reset(obj);
1107
1108 _eo_ref(obj);
1109
1110 _eo_parent_internal_set(obj, parent_id);
1111
1112 /* Run the relevant do stuff. */
1113 {
1114 va_list p_list;
1115 va_start(p_list, parent_id);
1116 do_err = !_eo_obj_dov_internal(file, line, obj, &p_list);
1117 va_end(p_list);
1118 }
1119
1120 if (EINA_UNLIKELY(do_err))
1121 {
1122 ERR("in %s:%d, Object of class '%s' - One of the object constructors have failed.",
1123 file, line, klass->desc->name);
1124 goto fail;
1125 }
1126
1127 if (!obj->condtor_done)
1128 {
1129 ERR("in %s:%d: Object of class '%s' - Not all of the object constructors have been executed.",
1130 file, line, klass->desc->name);
1131 goto fail;
1132 }
1133
1134 _eo_unref(obj);
1135
1136 return _eo_id_get(obj);
1137
1138fail:
1139 /* Unref twice, once for the ref above, and once for the basic object ref. */
1140 _eo_unref(obj);
1141 _eo_unref(obj);
1142 return NULL;
1143}
1144
1145EAPI Eo * 1339EAPI Eo *
1146eo_xref_internal(const char *file, int line, Eo *obj_id, const Eo *ref_obj_id) 1340eo_xref_internal(const char *file, int line, Eo *obj_id, const Eo *ref_obj_id)
1147{ 1341{
@@ -1213,6 +1407,7 @@ eo_unref(const Eo *obj_id)
1213EAPI void 1407EAPI void
1214eo_del(const Eo *obj) 1408eo_del(const Eo *obj)
1215{ 1409{
1410 EO_OBJ_POINTER_RETURN(obj, _obj);
1216 eo_do((Eo *) obj, eo_parent_set(NULL)); 1411 eo_do((Eo *) obj, eo_parent_set(NULL));
1217 eo_unref(obj); 1412 eo_unref(obj);
1218} 1413}
@@ -1230,7 +1425,7 @@ eo_error_set_internal(const Eo *obj_id, const char *file, int line)
1230{ 1425{
1231 EO_OBJ_POINTER_RETURN(obj_id, obj); 1426 EO_OBJ_POINTER_RETURN(obj_id, obj);
1232 1427
1233 ERR("Error with obj '%p' at %s:%d", obj, file, line); 1428 ERR("Error with obj '%p' at %s:%d.", obj, file, line);
1234 1429
1235 obj->do_error = EINA_TRUE; 1430 obj->do_error = EINA_TRUE;
1236} 1431}
@@ -1370,7 +1565,7 @@ eo_data_scope_get(const Eo *obj_id, const Eo_Class *klass_id)
1370#ifdef EO_DEBUG 1565#ifdef EO_DEBUG
1371 if (!ret && (klass->desc->data_size == 0)) 1566 if (!ret && (klass->desc->data_size == 0))
1372 { 1567 {
1373 ERR("Tried getting data of class '%s', but it has none..", klass->desc->name); 1568 ERR("Tried getting data of class '%s', but it has none.", klass->desc->name);
1374 } 1569 }
1375#endif 1570#endif
1376 1571
@@ -1403,7 +1598,7 @@ eo_data_xref_internal(const char *file, int line, const Eo *obj_id, const Eo_Cla
1403#ifdef EO_DEBUG 1598#ifdef EO_DEBUG
1404 if (klass && !ret && (klass->desc->data_size == 0)) 1599 if (klass && !ret && (klass->desc->data_size == 0))
1405 { 1600 {
1406 ERR("Tried getting data of class '%s', but it has none..", klass->desc->name); 1601 ERR("Tried getting data of class '%s', but it has none.", klass->desc->name);
1407 } 1602 }
1408#endif 1603#endif
1409 1604
@@ -1436,7 +1631,7 @@ eo_init(void)
1436 _eo_log_dom = eina_log_domain_register(log_dom, EINA_COLOR_LIGHTBLUE); 1631 _eo_log_dom = eina_log_domain_register(log_dom, EINA_COLOR_LIGHTBLUE);
1437 if (_eo_log_dom < 0) 1632 if (_eo_log_dom < 0)
1438 { 1633 {
1439 EINA_LOG_ERR("Could not register log domain: %s", log_dom); 1634 EINA_LOG_ERR("Could not register log domain: %s.", log_dom);
1440 return EINA_FALSE; 1635 return EINA_FALSE;
1441 } 1636 }
1442 1637
@@ -1465,6 +1660,18 @@ eo_init(void)
1465 /* bootstrap EO_CLASS_CLASS */ 1660 /* bootstrap EO_CLASS_CLASS */
1466 (void) eo_class_class_get(); 1661 (void) eo_class_class_get();
1467 1662
1663 if (_eo_call_stack_key != 0)
1664 WRN("_eo_call_stack_key already set, this should not happen.");
1665 else
1666 {
1667 if (!eina_tls_cb_new(&_eo_call_stack_key, _eo_call_stack_free))
1668 {
1669 EINA_LOG_ERR("Could not create TLS key for call stack.");
1670 return EINA_FALSE;
1671
1672 }
1673 }
1674
1468 return EINA_TRUE; 1675 return EINA_TRUE;
1469} 1676}
1470 1677
@@ -1492,6 +1699,9 @@ eo_shutdown(void)
1492 1699
1493 eina_spinlock_free(&_eo_class_creation_lock); 1700 eina_spinlock_free(&_eo_class_creation_lock);
1494 1701
1702 if (_eo_call_stack_key != 0)
1703 eina_tls_free(_eo_call_stack_key);
1704
1495 _eo_free_ids_tables(); 1705 _eo_free_ids_tables();
1496 1706
1497 eina_log_domain_unregister(_eo_log_dom); 1707 eina_log_domain_unregister(_eo_log_dom);
@@ -1532,6 +1742,7 @@ eo_composite_attach(Eo *comp_obj_id, Eo *parent_id)
1532 1742
1533 comp_obj->composite = EINA_TRUE; 1743 comp_obj->composite = EINA_TRUE;
1534 *comp_dst = comp_obj; 1744 *comp_dst = comp_obj;
1745
1535 eo_do(comp_obj_id, eo_parent_set(parent_id)); 1746 eo_do(comp_obj_id, eo_parent_set(parent_id));
1536 1747
1537 return EINA_TRUE; 1748 return EINA_TRUE;
diff --git a/src/lib/eo/eo_base.eo b/src/lib/eo/eo_base.eo
index 376ba38415..d3980544b2 100644
--- a/src/lib/eo/eo_base.eo
+++ b/src/lib/eo/eo_base.eo
@@ -1,5 +1,7 @@
1abstract Eo_Base () 1abstract Eo_Base ()
2{ 2{
3 eo_prefix: eo;
4
3 constructors { 5 constructors {
4 constructor { 6 constructor {
5 /*@ Call the object's constructor. 7 /*@ Call the object's constructor.
@@ -75,15 +77,15 @@ Prevents event callbacks from being called for the object. */
75 /*@ Call the object's destructor. 77 /*@ Call the object's destructor.
76Should not be used with #eo_do. Only use it with #eo_do_super. */ 78Should not be used with #eo_do. Only use it with #eo_do_super. */
77 } 79 }
78 data_set { 80 key_data_set {
79 /*@ Set generic data to object. */ 81 /*@ Set generic data to object. */
80 params { 82 params {
81 @in const char* key; /*@ the key associated with the data */ 83 @in const char* key; /*@ the key associated with the data */
82 @in const void* data; /*@ the data to set */ 84 @in const void* data; /*@ the data to set */
83 @in eo_base_data_free_func free_func; /*@ the func to free data with (NULL means */ 85 @in eo_key_data_free_func free_func; /*@ the func to free data with (NULL means */
84 } 86 }
85 } 87 }
86 data_get { 88 key_data_get {
87 /*@ Get generic data from object. */ 89 /*@ Get generic data from object. */
88 params { 90 params {
89 @in const char* key; /*@ the key associated with the data */ 91 @in const char* key; /*@ the key associated with the data */
@@ -102,7 +104,7 @@ Should not be used with #eo_do. Only use it with #eo_do_super. */
102 /*@ thaw events of object. 104 /*@ thaw events of object.
103Lets event callbacks be called for the object. */ 105Lets event callbacks be called for the object. */
104 } 106 }
105 data_del { 107 key_data_del {
106 /*@ Del generic data from object. */ 108 /*@ Del generic data from object. */
107 params { 109 params {
108 @in const char* key; /*@ the key associated with the data */ 110 @in const char* key; /*@ the key associated with the data */
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index c83b19bb23..b1bd8b2673 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -8,8 +8,6 @@
8#include "eo_ptr_indirection.h" 8#include "eo_ptr_indirection.h"
9#include "eo_private.h" 9#include "eo_private.h"
10 10
11EAPI Eo_Op EO_BASE_BASE_ID = 0;
12
13static int event_freeze_count = 0; 11static int event_freeze_count = 0;
14 12
15typedef struct _Eo_Callback_Description Eo_Callback_Description; 13typedef struct _Eo_Callback_Description Eo_Callback_Description;
@@ -33,7 +31,7 @@ typedef struct
33 EINA_INLIST; 31 EINA_INLIST;
34 Eina_Stringshare *key; 32 Eina_Stringshare *key;
35 void *data; 33 void *data;
36 eo_base_data_free_func free_func; 34 eo_key_data_free_func free_func;
37} Eo_Generic_Data_Node; 35} Eo_Generic_Data_Node;
38 36
39static void 37static void
@@ -61,19 +59,16 @@ _eo_generic_data_del_all(Private_Data *pd)
61} 59}
62 60
63static void 61static void
64_data_set(Eo *obj, void *class_data, va_list *list) 62_data_set(Eo *obj, void *class_data,
63 const char *key, const void *data, eo_key_data_free_func free_func)
65{ 64{
66 Private_Data *pd = class_data; 65 Private_Data *pd = class_data;
67 66
68 EO_PARAMETER_GET(const char *, key, list);
69 EO_PARAMETER_GET(const void *, data, list);
70 EO_PARAMETER_GET(eo_base_data_free_func, free_func, list);
71
72 Eo_Generic_Data_Node *node; 67 Eo_Generic_Data_Node *node;
73 68
74 if (!key) return; 69 if (!key) return;
75 70
76 eo_do(obj, eo_base_data_del(key)); 71 eo_do(obj, eo_key_data_del(key); );
77 72
78 node = malloc(sizeof(Eo_Generic_Data_Node)); 73 node = malloc(sizeof(Eo_Generic_Data_Node));
79 if (!node) return; 74 if (!node) return;
@@ -83,21 +78,17 @@ _data_set(Eo *obj, void *class_data, va_list *list)
83 pd->generic_data = eina_inlist_prepend(pd->generic_data, 78 pd->generic_data = eina_inlist_prepend(pd->generic_data,
84 EINA_INLIST_GET(node)); 79 EINA_INLIST_GET(node));
85} 80}
81EAPI EO_VOID_FUNC_BODYV(eo_key_data_set, EO_FUNC_CALL(key, data, free_func),
82 const char *key, const void *data, eo_key_data_free_func free_func);
86 83
87static void 84static void *
88_data_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list) 85_data_get(Eo *obj EINA_UNUSED, void *class_data, const char *key)
89{ 86{
90 /* We don't really change it... */ 87 /* We don't really change it... */
91 Eo_Generic_Data_Node *node; 88 Eo_Generic_Data_Node *node;
92 Private_Data *pd = (Private_Data *) class_data; 89 Private_Data *pd = (Private_Data *) class_data;
93 90
94 EO_PARAMETER_GET(const char *, key, list); 91 if (!key) return NULL;
95 EO_PARAMETER_GET(void **, data, list);
96
97 if (!data) return;
98 *data = NULL;
99
100 if (!key) return;
101 92
102 EINA_INLIST_FOREACH(pd->generic_data, node) 93 EINA_INLIST_FOREACH(pd->generic_data, node)
103 { 94 {
@@ -105,21 +96,21 @@ _data_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
105 { 96 {
106 pd->generic_data = 97 pd->generic_data =
107 eina_inlist_promote(pd->generic_data, EINA_INLIST_GET(node)); 98 eina_inlist_promote(pd->generic_data, EINA_INLIST_GET(node));
108 *data = node->data; 99 return node->data;
109 return;
110 } 100 }
111 } 101 }
102
103 return NULL;
112} 104}
105EAPI EO_FUNC_BODYV(eo_key_data_get, void*, NULL, EO_FUNC_CALL(key), const char *key);
113 106
114static void 107static void
115_parent_set(Eo *obj, void *class_data, va_list *list) 108_parent_set(Eo *obj, void *class_data, Eo *parent_id)
116{ 109{
117 Private_Data *pd = (Private_Data *) class_data; 110 Private_Data *pd = (Private_Data *) class_data;
118 111
119 EO_PARAMETER_GET(Eo *, parent_id, list);
120
121 if (pd->parent == parent_id) 112 if (pd->parent == parent_id)
122 return ; 113 return;
123 114
124 if (eo_composite_is(obj) && pd->parent) 115 if (eo_composite_is(obj) && pd->parent)
125 { 116 {
@@ -130,11 +121,11 @@ _parent_set(Eo *obj, void *class_data, va_list *list)
130 { 121 {
131 Private_Data *old_parent_pd; 122 Private_Data *old_parent_pd;
132 123
133 old_parent_pd = eo_data_scope_get(pd->parent, EO_BASE_CLASS); 124 old_parent_pd = eo_data_scope_get(pd->parent, EO_CLASS);
134 if (old_parent_pd) 125 if (old_parent_pd)
135 { 126 {
136 old_parent_pd->children = eina_list_remove(old_parent_pd->children, 127 old_parent_pd->children = eina_list_remove(old_parent_pd->children,
137 obj); 128 obj);
138 } 129 }
139 else 130 else
140 { 131 {
@@ -149,7 +140,7 @@ _parent_set(Eo *obj, void *class_data, va_list *list)
149 if (parent_id) 140 if (parent_id)
150 { 141 {
151 Private_Data *parent_pd = NULL; 142 Private_Data *parent_pd = NULL;
152 parent_pd = eo_data_scope_get(parent_id, EO_BASE_CLASS); 143 parent_pd = eo_data_scope_get(parent_id, EO_CLASS);
153 144
154 if (EINA_LIKELY(parent_pd != NULL)) 145 if (EINA_LIKELY(parent_pd != NULL))
155 { 146 {
@@ -170,18 +161,16 @@ _parent_set(Eo *obj, void *class_data, va_list *list)
170 pd->parent = NULL; 161 pd->parent = NULL;
171 } 162 }
172} 163}
164EAPI EO_VOID_FUNC_BODYV(eo_parent_set, EO_FUNC_CALL(parent_id), Eo *parent_id);
173 165
174static void 166static Eo *
175_parent_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list) 167_parent_get(Eo *obj EINA_UNUSED, void *class_data)
176{ 168{
177 Private_Data *pd = (Private_Data *) class_data; 169 Private_Data *pd = (Private_Data *) class_data;
178 170
179 EO_PARAMETER_GET(Eo **, parent_id, list); 171 return pd->parent;
180
181 if (!parent_id) return ;
182 *parent_id = pd->parent;
183} 172}
184 173EAPI EO_FUNC_BODY(eo_parent_get, Eo *, NULL);
185 174
186/* Children accessor */ 175/* Children accessor */
187typedef struct _Eo_Children_Iterator Eo_Children_Iterator; 176typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
@@ -191,7 +180,6 @@ struct _Eo_Children_Iterator
191 Eina_List *current; 180 Eina_List *current;
192 _Eo_Object *obj; 181 _Eo_Object *obj;
193 Eo *obj_id; 182 Eo *obj_id;
194
195}; 183};
196 184
197static Eina_Bool 185static Eina_Bool
@@ -231,65 +219,63 @@ _eo_children_iterator_free(Eo_Children_Iterator *it)
231 free(it); 219 free(it);
232 } 220 }
233 eina_spinlock_release(&klass->iterators.trash_lock); 221 eina_spinlock_release(&klass->iterators.trash_lock);
234 222
235 _eo_unref(obj); 223 _eo_unref(obj);
236} 224}
237 225
238static void 226static Eina_Iterator *
239_children_iterator_new(Eo *obj_id, void *class_data, va_list *list) 227_children_iterator_new(Eo *obj_id, void *class_data)
240{ 228{
241 Private_Data *pd = class_data; 229 Private_Data *pd = class_data;
242 _Eo_Class *klass; 230 _Eo_Class *klass;
231 Eo_Children_Iterator *it;
243 232
244 EO_PARAMETER_GET(Eo_Children_Iterator **, it, list); 233 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
245 EO_OBJ_POINTER_RETURN(obj_id, obj);
246 234
247 if (!it) return ; 235 if (!pd->children) return NULL;
248 *it = NULL;
249
250 if (!pd->children) return ;
251 236
252 klass = (_Eo_Class *) obj->klass; 237 klass = (_Eo_Class *) obj->klass;
253 238
254 eina_spinlock_take(&klass->iterators.trash_lock); 239 eina_spinlock_take(&klass->iterators.trash_lock);
255 *it = eina_trash_pop(&klass->iterators.trash); 240 it = eina_trash_pop(&klass->iterators.trash);
256 if (*it) 241 if (it)
257 { 242 {
258 klass->iterators.trash_count--; 243 klass->iterators.trash_count--;
259 memset(*it, 0, sizeof (Eo_Children_Iterator)); 244 memset(it, 0, sizeof (Eo_Children_Iterator));
260 } 245 }
261 else 246 else
262 { 247 {
263 *it = calloc(1, sizeof (Eo_Children_Iterator)); 248 it = calloc(1, sizeof (Eo_Children_Iterator));
264 } 249 }
265 eina_spinlock_release(&klass->iterators.trash_lock); 250 eina_spinlock_release(&klass->iterators.trash_lock);
266 if (!*it) return ; 251 if (!it) return NULL;
252
253 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
254 it->current = obj->children;
255 it->obj = _eo_ref(obj);
256 it->obj_id = obj_id;
267 257
268 EINA_MAGIC_SET(&(*it)->iterator, EINA_MAGIC_ITERATOR); 258 it->iterator.next = FUNC_ITERATOR_NEXT(_eo_children_iterator_next);
269 (*it)->current = obj->children; 259 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eo_children_iterator_container);
270 (*it)->obj = _eo_ref(obj); 260 it->iterator.free = FUNC_ITERATOR_FREE(_eo_children_iterator_free);
271 (*it)->obj_id = obj_id;
272 261
273 (*it)->iterator.next = FUNC_ITERATOR_NEXT(_eo_children_iterator_next); 262 return (Eina_Iterator *)it;
274 (*it)->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eo_children_iterator_container);
275 (*it)->iterator.free = FUNC_ITERATOR_FREE(_eo_children_iterator_free);
276} 263}
264EAPI EO_FUNC_BODY(eo_children_iterator_new, Eina_Iterator *, NULL);
277 265
278static void 266static void
279_dbg_info_get(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, 267_dbg_info_get(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, Eo_Dbg_Info *root_node EINA_UNUSED)
280 va_list *data EINA_UNUSED)
281{ /* No info required in the meantime */ 268{ /* No info required in the meantime */
282 return; 269 return;
283} 270}
271EAPI EO_VOID_FUNC_BODYV(eo_dbg_info_get, EO_FUNC_CALL(root_node), Eo_Dbg_Info *root_node);
284 272
285static void 273static void
286_data_del(Eo *obj EINA_UNUSED, void *class_data, va_list *list) 274_data_del(Eo *obj EINA_UNUSED, void *class_data, const char *key)
287{ 275{
288 Eo_Generic_Data_Node *node; 276 Eo_Generic_Data_Node *node;
289 Private_Data *pd = class_data; 277 Private_Data *pd = class_data;
290 278
291 EO_PARAMETER_GET(const char *, key, list);
292
293 if (!key) return; 279 if (!key) return;
294 280
295 EINA_INLIST_FOREACH(pd->generic_data, node) 281 EINA_INLIST_FOREACH(pd->generic_data, node)
@@ -303,6 +289,7 @@ _data_del(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
303 } 289 }
304 } 290 }
305} 291}
292EAPI EO_VOID_FUNC_BODYV(eo_key_data_del, EO_FUNC_CALL(key), const char *key);
306 293
307/* Weak reference. */ 294/* Weak reference. */
308 295
@@ -314,41 +301,38 @@ _wref_count(Private_Data *pd)
314 return 0; 301 return 0;
315 302
316 Eo ***itr; 303 Eo ***itr;
317 for (itr = pd->wrefs ; *itr ; itr++) 304 for (itr = pd->wrefs; *itr; itr++)
318 count++; 305 count++;
319 306
320 return count; 307 return count;
321} 308}
322 309
323static void 310static void
324_wref_add(Eo *obj, void *class_data, va_list *list) 311_wref_add(Eo *obj, void *class_data, Eo **wref)
325{ 312{
326 Private_Data *pd = (Private_Data *) class_data; 313 Private_Data *pd = (Private_Data *) class_data;
327 size_t count; 314 size_t count;
328 Eo ***tmp; 315 Eo ***tmp;
329 316
330 EO_PARAMETER_GET(Eo **, wref, list);
331
332 count = _wref_count(pd); 317 count = _wref_count(pd);
333 count += 1; /* New wref. */ 318 count += 1; /* New wref. */
334 319
335 tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * (count + 1)); 320 tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * (count + 1));
336 if (!tmp) return ; 321 if (!tmp) return;
337 pd->wrefs = tmp; 322 pd->wrefs = tmp;
338 323
339 pd->wrefs[count - 1] = wref; 324 pd->wrefs[count - 1] = wref;
340 pd->wrefs[count] = NULL; 325 pd->wrefs[count] = NULL;
341 *wref = obj; 326 *wref = obj;
342} 327}
328EAPI EO_VOID_FUNC_BODYV(eo_wref_add, EO_FUNC_CALL(wref), Eo **wref);
343 329
344static void 330static void
345_wref_del(Eo *obj, void *class_data, va_list *list) 331_wref_del(Eo *obj, void *class_data, Eo **wref)
346{ 332{
347 Private_Data *pd = (Private_Data *) class_data; 333 Private_Data *pd = (Private_Data *) class_data;
348 size_t count; 334 size_t count;
349 335
350 EO_PARAMETER_GET(Eo **, wref, list);
351
352 if (*wref != obj) 336 if (*wref != obj)
353 { 337 {
354 ERR("Wref is a weak ref to %p, while this function was called on %p.", 338 ERR("Wref is a weak ref to %p, while this function was called on %p.",
@@ -368,7 +352,7 @@ _wref_del(Eo *obj, void *class_data, va_list *list)
368 352
369 { 353 {
370 Eo ***itr; 354 Eo ***itr;
371 for (itr = pd->wrefs ; *itr ; itr++) 355 for (itr = pd->wrefs; *itr; itr++)
372 { 356 {
373 if (*itr == wref) 357 if (*itr == wref)
374 { 358 {
@@ -390,7 +374,7 @@ _wref_del(Eo *obj, void *class_data, va_list *list)
390 Eo ***tmp; 374 Eo ***tmp;
391 // No count--; because of the NULL that is not included in the count. */ 375 // No count--; because of the NULL that is not included in the count. */
392 tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * count); 376 tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * count);
393 if (!tmp) return ; 377 if (!tmp) return;
394 pd->wrefs = tmp; 378 pd->wrefs = tmp;
395 pd->wrefs[count - 1] = NULL; 379 pd->wrefs[count - 1] = NULL;
396 } 380 }
@@ -402,6 +386,7 @@ _wref_del(Eo *obj, void *class_data, va_list *list)
402 386
403 *wref = NULL; 387 *wref = NULL;
404} 388}
389EAPI EO_VOID_FUNC_BODYV(eo_wref_del, EO_FUNC_CALL(wref), Eo **wref);
405 390
406static inline void 391static inline void
407_wref_destruct(Private_Data *pd) 392_wref_destruct(Private_Data *pd)
@@ -410,7 +395,7 @@ _wref_destruct(Private_Data *pd)
410 if (!pd->wrefs) 395 if (!pd->wrefs)
411 return; 396 return;
412 397
413 for (itr = pd->wrefs ; *itr ; itr++) 398 for (itr = pd->wrefs; *itr; itr++)
414 { 399 {
415 **itr = NULL; 400 **itr = NULL;
416 } 401 }
@@ -445,11 +430,13 @@ struct _Eo_Callback_Description
445static void 430static void
446_eo_callback_remove(Private_Data *pd, Eo_Callback_Description *cb) 431_eo_callback_remove(Private_Data *pd, Eo_Callback_Description *cb)
447{ 432{
448 Eo_Callback_Description *itr, *pitr = NULL; 433 Eo_Callback_Description *itr, *pitr;
449 434
450 itr = pd->callbacks; 435 itr = pitr = pd->callbacks;
436 if (pd->callbacks == cb)
437 pd->callbacks = cb->next;
451 438
452 for ( ; itr ; ) 439 for ( ; itr; )
453 { 440 {
454 Eo_Callback_Description *titr = itr; 441 Eo_Callback_Description *titr = itr;
455 itr = itr->next; 442 itr = itr->next;
@@ -460,10 +447,6 @@ _eo_callback_remove(Private_Data *pd, Eo_Callback_Description *cb)
460 { 447 {
461 pitr->next = titr->next; 448 pitr->next = titr->next;
462 } 449 }
463 else
464 {
465 pd->callbacks = titr->next;
466 }
467 free(titr); 450 free(titr);
468 } 451 }
469 else 452 else
@@ -485,7 +468,7 @@ _eo_callback_remove_all(Private_Data *pd)
485 } 468 }
486} 469}
487 470
488static inline void 471static void
489_eo_callbacks_clear(Private_Data *pd) 472_eo_callbacks_clear(Private_Data *pd)
490{ 473{
491 Eo_Callback_Description *cb = NULL; 474 Eo_Callback_Description *cb = NULL;
@@ -500,7 +483,7 @@ _eo_callbacks_clear(Private_Data *pd)
500 483
501 pd->deletions_waiting = EINA_FALSE; 484 pd->deletions_waiting = EINA_FALSE;
502 485
503 for (cb = pd->callbacks ; cb ; ) 486 for (cb = pd->callbacks; cb; )
504 { 487 {
505 Eo_Callback_Description *titr = cb; 488 Eo_Callback_Description *titr = cb;
506 cb = cb->next; 489 cb = cb->next;
@@ -516,7 +499,7 @@ static void
516_eo_callbacks_sorted_insert(Private_Data *pd, Eo_Callback_Description *cb) 499_eo_callbacks_sorted_insert(Private_Data *pd, Eo_Callback_Description *cb)
517{ 500{
518 Eo_Callback_Description *itr, *itrp = NULL; 501 Eo_Callback_Description *itr, *itrp = NULL;
519 for (itr = pd->callbacks ; itr && (itr->priority < cb->priority) ; 502 for (itr = pd->callbacks; itr && (itr->priority < cb->priority);
520 itr = itr->next) 503 itr = itr->next)
521 { 504 {
522 itrp = itr; 505 itrp = itr;
@@ -535,41 +518,45 @@ _eo_callbacks_sorted_insert(Private_Data *pd, Eo_Callback_Description *cb)
535} 518}
536 519
537static void 520static void
538_ev_cb_priority_add(Eo *obj, void *class_data, va_list *list) 521_ev_cb_priority_add(Eo *obj, void *class_data,
522 const Eo_Event_Description *desc,
523 Eo_Callback_Priority priority,
524 Eo_Event_Cb func,
525 const void *user_data)
539{ 526{
540 Eo_Callback_Description *cb; 527 Eo_Callback_Description *cb;
541 Private_Data *pd = (Private_Data *) class_data; 528 Private_Data *pd = (Private_Data *) class_data;
542 529
543 EO_PARAMETER_GET(const Eo_Event_Description *, desc, list);
544 EO_PARAMETER_ENUM_GET(Eo_Callback_Priority, priority, list);
545 EO_PARAMETER_GET(Eo_Event_Cb, func, list);
546 EO_PARAMETER_GET(const void *, data, list);
547
548 cb = calloc(1, sizeof(*cb)); 530 cb = calloc(1, sizeof(*cb));
549 if (!cb) return ; 531 if (!cb) return;
550 cb->items.item.desc = desc; 532 cb->items.item.desc = desc;
551 cb->items.item.func = func; 533 cb->items.item.func = func;
552 cb->func_data = (void *) data; 534 cb->func_data = (void *) user_data;
553 cb->priority = priority; 535 cb->priority = priority;
554 _eo_callbacks_sorted_insert(pd, cb); 536 _eo_callbacks_sorted_insert(pd, cb);
555 537
556 { 538 {
557 const Eo_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; 539 const Eo_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}};
558 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, arr, NULL)); 540 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, (void *)arr));
559 } 541 }
560} 542}
543EAPI EO_VOID_FUNC_BODYV(eo_event_callback_priority_add,
544 EO_FUNC_CALL(desc, priority, func, user_data),
545 const Eo_Event_Description *desc,
546 Eo_Callback_Priority priority,
547 Eo_Event_Cb func,
548 const void *user_data);
561 549
562static void 550static void
563_ev_cb_del(Eo *obj, void *class_data, va_list *list) 551_ev_cb_del(Eo *obj, void *class_data,
552 const Eo_Event_Description *desc,
553 Eo_Event_Cb func,
554 void *user_data)
564{ 555{
565 Eo_Callback_Description *cb; 556 Eo_Callback_Description *cb;
566 Private_Data *pd = (Private_Data *) class_data; 557 Private_Data *pd = (Private_Data *) class_data;
567 558
568 EO_PARAMETER_GET(const Eo_Event_Description *, desc, list); 559 for (cb = pd->callbacks; cb; cb = cb->next)
569 EO_PARAMETER_GET(Eo_Event_Cb, func, list);
570 EO_PARAMETER_GET(void *, user_data, list);
571
572 for (cb = pd->callbacks ; cb ; cb = cb->next)
573 { 560 {
574 if ((cb->items.item.desc == desc) && (cb->items.item.func == func) && 561 if ((cb->items.item.desc == desc) && (cb->items.item.func == func) &&
575 (cb->func_data == user_data)) 562 (cb->func_data == user_data))
@@ -579,47 +566,55 @@ _ev_cb_del(Eo *obj, void *class_data, va_list *list)
579 cb->delete_me = EINA_TRUE; 566 cb->delete_me = EINA_TRUE;
580 pd->deletions_waiting = EINA_TRUE; 567 pd->deletions_waiting = EINA_TRUE;
581 _eo_callbacks_clear(pd); 568 _eo_callbacks_clear(pd);
582 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, arr, NULL)); 569 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, (void *)arr); );
583 return; 570 return;
584 } 571 }
585 } 572 }
586 573
587 DBG("Callback of object %p with function %p and data %p not found.", obj, func, user_data); 574 DBG("Callback of object %p with function %p and data %p not found.", obj, func, user_data);
588} 575}
576EAPI EO_VOID_FUNC_BODYV(eo_event_callback_del,
577 EO_FUNC_CALL(desc, func, user_data),
578 const Eo_Event_Description *desc,
579 Eo_Event_Cb func,
580 const void *user_data);
589 581
590static void 582static void
591_ev_cb_array_priority_add(Eo *obj, void *class_data, va_list *list) 583_ev_cb_array_priority_add(Eo *obj, void *class_data,
584 const Eo_Callback_Array_Item *array,
585 Eo_Callback_Priority priority,
586 const void *user_data)
592{ 587{
593 Eo_Callback_Description *cb; 588 Eo_Callback_Description *cb;
594 Private_Data *pd = (Private_Data *) class_data; 589 Private_Data *pd = (Private_Data *) class_data;
595 590
596 EO_PARAMETER_GET(const Eo_Callback_Array_Item *, array, list);
597 EO_PARAMETER_ENUM_GET(Eo_Callback_Priority, priority, list);
598 EO_PARAMETER_GET(const void *, data, list);
599
600 cb = calloc(1, sizeof(*cb)); 591 cb = calloc(1, sizeof(*cb));
601 if (!cb) return ; 592 if (!cb) return;
602 cb->func_data = (void *) data; 593 cb->func_data = (void *) user_data;
603 cb->priority = priority; 594 cb->priority = priority;
604 cb->items.item_array = array; 595 cb->items.item_array = array;
605 cb->func_array = EINA_TRUE; 596 cb->func_array = EINA_TRUE;
606 _eo_callbacks_sorted_insert(pd, cb); 597 _eo_callbacks_sorted_insert(pd, cb);
607 598
608 { 599 {
609 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, array, NULL)); 600 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, (void *)array); );
610 } 601 }
611} 602}
603EAPI EO_VOID_FUNC_BODYV(eo_event_callback_array_priority_add,
604 EO_FUNC_CALL(array, priority, user_data),
605 const Eo_Callback_Array_Item *array,
606 Eo_Callback_Priority priority,
607 const void *user_data);
612 608
613static void 609static void
614_ev_cb_array_del(Eo *obj, void *class_data, va_list *list) 610_ev_cb_array_del(Eo *obj, void *class_data,
611 const Eo_Callback_Array_Item *array,
612 void *user_data)
615{ 613{
616 Eo_Callback_Description *cb; 614 Eo_Callback_Description *cb;
617 Private_Data *pd = (Private_Data *) class_data; 615 Private_Data *pd = (Private_Data *) class_data;
618 616
619 EO_PARAMETER_GET(const Eo_Callback_Array_Item *, array, list); 617 for (cb = pd->callbacks; cb; cb = cb->next)
620 EO_PARAMETER_GET(void *, user_data, list);
621
622 for (cb = pd->callbacks ; cb ; cb = cb->next)
623 { 618 {
624 if ((cb->items.item_array == array) && (cb->func_data == user_data)) 619 if ((cb->items.item_array == array) && (cb->func_data == user_data))
625 { 620 {
@@ -627,32 +622,35 @@ _ev_cb_array_del(Eo *obj, void *class_data, va_list *list)
627 pd->deletions_waiting = EINA_TRUE; 622 pd->deletions_waiting = EINA_TRUE;
628 _eo_callbacks_clear(pd); 623 _eo_callbacks_clear(pd);
629 624
630 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, array, NULL)); 625 eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, (void *)array); );
631 return; 626 return;
632 } 627 }
633 } 628 }
634 629
635 DBG("Callback of object %p with function array %p and data %p not found.", obj, array, user_data); 630 DBG("Callback of object %p with function array %p and data %p not found.", obj, array, user_data);
636} 631}
632EAPI EO_VOID_FUNC_BODYV(eo_event_callback_array_del,
633 EO_FUNC_CALL(array, user_data),
634 const Eo_Callback_Array_Item *array,
635 const void *user_data);
637 636
638static void 637static Eina_Bool
639_ev_cb_call(Eo *obj_id, void *class_data, va_list *list) 638_ev_cb_call(Eo *obj_id, void *class_data,
639 const Eo_Event_Description *desc,
640 void *event_info)
640{ 641{
642 Eina_Bool ret;
641 Eo_Callback_Description *cb; 643 Eo_Callback_Description *cb;
642 Private_Data *pd = (Private_Data *) class_data; 644 Private_Data *pd = (Private_Data *) class_data;
643 645
644 EO_PARAMETER_GET(const Eo_Event_Description *, desc, list); 646 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
645 EO_PARAMETER_GET(void *, event_info, list);
646 EO_PARAMETER_GET(Eina_Bool *, ret, list);
647
648 EO_OBJ_POINTER_RETURN(obj_id, obj);
649 647
650 if (ret) *ret = EINA_TRUE; 648 ret = EINA_TRUE;
651 649
652 _eo_ref(obj); 650 _eo_ref(obj);
653 pd->walking_list++; 651 pd->walking_list++;
654 652
655 for (cb = pd->callbacks ; cb ; cb = cb->next) 653 for (cb = pd->callbacks; cb; cb = cb->next)
656 { 654 {
657 if (!cb->delete_me) 655 if (!cb->delete_me)
658 { 656 {
@@ -660,7 +658,7 @@ _ev_cb_call(Eo *obj_id, void *class_data, va_list *list)
660 { 658 {
661 const Eo_Callback_Array_Item *it; 659 const Eo_Callback_Array_Item *it;
662 660
663 for (it = cb->items.item_array ; it->func ; it++) 661 for (it = cb->items.item_array; it->func; it++)
664 { 662 {
665 if (it->desc != desc) 663 if (it->desc != desc)
666 continue; 664 continue;
@@ -672,7 +670,7 @@ _ev_cb_call(Eo *obj_id, void *class_data, va_list *list)
672 if (!it->func((void *) cb->func_data, obj_id, desc, 670 if (!it->func((void *) cb->func_data, obj_id, desc,
673 (void *) event_info)) 671 (void *) event_info))
674 { 672 {
675 if (ret) *ret = EINA_FALSE; 673 ret = EINA_FALSE;
676 goto end; 674 goto end;
677 } 675 }
678 } 676 }
@@ -690,7 +688,7 @@ _ev_cb_call(Eo *obj_id, void *class_data, va_list *list)
690 if (!cb->items.item.func((void *) cb->func_data, obj_id, desc, 688 if (!cb->items.item.func((void *) cb->func_data, obj_id, desc,
691 (void *) event_info)) 689 (void *) event_info))
692 { 690 {
693 if (ret) *ret = EINA_FALSE; 691 ret = EINA_FALSE;
694 goto end; 692 goto end;
695 } 693 }
696 } 694 }
@@ -701,52 +699,68 @@ end:
701 pd->walking_list--;