summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-26 06:56:52 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-26 06:56:52 +0000
commit3b5a3448b7dfc53c2f129bdb04bea9f7a02741a6 (patch)
tree18ad8a6b1841e9832c85a46f887b2cd6d6dacc4b /src
parent195d31c73fef88cfaa803b07b2ae3cba983a4093 (diff)
merge: add eo
SVN revision: 77072
Diffstat (limited to 'src')
-rw-r--r--src/benchmarks/Makefile.am5
-rw-r--r--src/benchmarks/eo/Makefile.am29
-rw-r--r--src/benchmarks/eo/class_simple.c50
-rw-r--r--src/benchmarks/eo/class_simple.h23
-rw-r--r--src/benchmarks/eo/eo_bench.c55
-rw-r--r--src/benchmarks/eo/eo_bench.h6
-rw-r--r--src/benchmarks/eo/eo_bench_eo_do.c26
-rw-r--r--src/examples/Makefile.am8
-rw-r--r--src/examples/eo/Makefile.am83
-rw-r--r--src/examples/eo/evas/evas_elw_box.c74
-rw-r--r--src/examples/eo/evas/evas_elw_box.h25
-rw-r--r--src/examples/eo/evas/evas_elw_boxedbutton.c57
-rw-r--r--src/examples/eo/evas/evas_elw_boxedbutton.h9
-rw-r--r--src/examples/eo/evas/evas_elw_button.c115
-rw-r--r--src/examples/eo/evas/evas_elw_button.h29
-rw-r--r--src/examples/eo/evas/evas_elw_win.c74
-rw-r--r--src/examples/eo/evas/evas_elw_win.h9
-rw-r--r--src/examples/eo/evas/evas_evas_obj.c146
-rw-r--r--src/examples/eo/evas/evas_evas_obj.h90
-rw-r--r--src/examples/eo/evas/evas_test.c68
-rw-r--r--src/examples/eo/isa/eo_isa_complex.c21
-rw-r--r--src/examples/eo/isa/eo_isa_complex.h10
-rw-r--r--src/examples/eo/isa/eo_isa_interface.c29
-rw-r--r--src/examples/eo/isa/eo_isa_interface.h26
-rw-r--r--src/examples/eo/isa/eo_isa_main.c36
-rw-r--r--src/examples/eo/isa/eo_isa_mixin.c53
-rw-r--r--src/examples/eo/isa/eo_isa_mixin.h26
-rw-r--r--src/examples/eo/isa/eo_isa_simple.c78
-rw-r--r--src/examples/eo/isa/eo_isa_simple.h35
-rw-r--r--src/examples/eo/simple/simple_interface.c29
-rw-r--r--src/examples/eo/simple/simple_interface.h26
-rw-r--r--src/examples/eo/simple/simple_main.c31
-rw-r--r--src/examples/eo/simple/simple_mixin.c53
-rw-r--r--src/examples/eo/simple/simple_mixin.h26
-rw-r--r--src/examples/eo/simple/simple_simple.c78
-rw-r--r--src/examples/eo/simple/simple_simple.h35
-rw-r--r--src/lib/Makefile.am6
-rw-r--r--src/lib/eo/Eo.h1200
-rw-r--r--src/lib/eo/Makefile.am21
-rw-r--r--src/lib/eo/eo.c1582
-rw-r--r--src/lib/eo/eo_base_class.c579
-rw-r--r--src/lib/eo/eo_private.h59
-rw-r--r--src/tests/Makefile.am6
-rw-r--r--src/tests/eo/Makefile.am126
-rw-r--r--src/tests/eo/access/access_inherit.c49
-rw-r--r--src/tests/eo/access/access_inherit.h18
-rw-r--r--src/tests/eo/access/access_main.c27
-rw-r--r--src/tests/eo/access/access_simple.c70
-rw-r--r--src/tests/eo/access/access_simple.h26
-rw-r--r--src/tests/eo/access/access_simple_protected.h10
-rw-r--r--src/tests/eo/composite_objects/composite_objects_comp.c65
-rw-r--r--src/tests/eo/composite_objects/composite_objects_comp.h7
-rw-r--r--src/tests/eo/composite_objects/composite_objects_main.c65
-rw-r--r--src/tests/eo/composite_objects/composite_objects_simple.c71
-rw-r--r--src/tests/eo/composite_objects/composite_objects_simple.h28
-rw-r--r--src/tests/eo/constructors/constructors_main.c79
-rw-r--r--src/tests/eo/constructors/constructors_mixin.c70
-rw-r--r--src/tests/eo/constructors/constructors_mixin.h18
-rw-r--r--src/tests/eo/constructors/constructors_simple.c124
-rw-r--r--src/tests/eo/constructors/constructors_simple.h26
-rw-r--r--src/tests/eo/constructors/constructors_simple2.c42
-rw-r--r--src/tests/eo/constructors/constructors_simple2.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple3.c40
-rw-r--r--src/tests/eo/constructors/constructors_simple3.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple4.c24
-rw-r--r--src/tests/eo/constructors/constructors_simple4.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple5.c40
-rw-r--r--src/tests/eo/constructors/constructors_simple5.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple6.c42
-rw-r--r--src/tests/eo/constructors/constructors_simple6.h7
-rw-r--r--src/tests/eo/constructors/constructors_simple7.c43
-rw-r--r--src/tests/eo/constructors/constructors_simple7.h7
-rw-r--r--src/tests/eo/eunit_tests.h17
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit.c22
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit.h7
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit2.c82
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit2.h20
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit3.c44
-rw-r--r--src/tests/eo/function_overrides/function_overrides_inherit3.h7
-rw-r--r--src/tests/eo/function_overrides/function_overrides_main.c63
-rw-r--r--src/tests/eo/function_overrides/function_overrides_simple.c82
-rw-r--r--src/tests/eo/function_overrides/function_overrides_simple.h32
-rw-r--r--src/tests/eo/interface/interface_interface.c30
-rw-r--r--src/tests/eo/interface/interface_interface.h24
-rw-r--r--src/tests/eo/interface/interface_interface2.c31
-rw-r--r--src/tests/eo/interface/interface_interface2.h24
-rw-r--r--src/tests/eo/interface/interface_main.c37
-rw-r--r--src/tests/eo/interface/interface_simple.c100
-rw-r--r--src/tests/eo/interface/interface_simple.h47
-rw-r--r--src/tests/eo/mixin/mixin_inherit.c42
-rw-r--r--src/tests/eo/mixin/mixin_inherit.h7
-rw-r--r--src/tests/eo/mixin/mixin_main.c47
-rw-r--r--src/tests/eo/mixin/mixin_mixin.c67
-rw-r--r--src/tests/eo/mixin/mixin_mixin.h24
-rw-r--r--src/tests/eo/mixin/mixin_mixin2.c70
-rw-r--r--src/tests/eo/mixin/mixin_mixin2.h12
-rw-r--r--src/tests/eo/mixin/mixin_mixin3.c70
-rw-r--r--src/tests/eo/mixin/mixin_mixin3.h12
-rw-r--r--src/tests/eo/mixin/mixin_mixin4.c26
-rw-r--r--src/tests/eo/mixin/mixin_mixin4.h7
-rw-r--r--src/tests/eo/mixin/mixin_simple.c77
-rw-r--r--src/tests/eo/mixin/mixin_simple.h47
-rw-r--r--src/tests/eo/signals/signals_main.c183
-rw-r--r--src/tests/eo/signals/signals_simple.c112
-rw-r--r--src/tests/eo/signals/signals_simple.h31
-rw-r--r--src/tests/eo/suite/eo_suite.c106
-rw-r--r--src/tests/eo/suite/eo_suite.h11
-rw-r--r--src/tests/eo/suite/eo_test_class_errors.c350
-rw-r--r--src/tests/eo/suite/eo_test_class_simple.c69
-rw-r--r--src/tests/eo/suite/eo_test_class_simple.h30
-rw-r--r--src/tests/eo/suite/eo_test_general.c752
-rw-r--r--src/tests/eo/suite/eo_test_init.c22
112 files changed, 9019 insertions, 2 deletions
diff --git a/src/benchmarks/Makefile.am b/src/benchmarks/Makefile.am
index b16aab1fd7..15fa26cece 100644
--- a/src/benchmarks/Makefile.am
+++ b/src/benchmarks/Makefile.am
@@ -1,11 +1,14 @@
1MAINTAINERCLEANFILES = Makefile.in 1MAINTAINERCLEANFILES = Makefile.in
2 2
3SUBDIRS = eina 3SUBDIRS = eina eo
4 4
5.PHONY: benchmark benchmark-e17 5.PHONY: benchmark benchmark-e17
6 6
7benchmark: 7benchmark:
8 @$(MAKE) $(AM_MAKEFLAGS) -C eina benchmark 8 @$(MAKE) $(AM_MAKEFLAGS) -C eina benchmark
9if EFL_BUILD_EO
10 @$(MAKE) $(AM_MAKEFLAGS) -C eo benchmark
11endif
9 12
10benchmark-e17: 13benchmark-e17:
11 @$(MAKE) $(AM_MAKEFLAGS) -C eina benchmark-e17 14 @$(MAKE) $(AM_MAKEFLAGS) -C eina benchmark-e17
diff --git a/src/benchmarks/eo/Makefile.am b/src/benchmarks/eo/Makefile.am
new file mode 100644
index 0000000000..e0f9e4c0f3
--- /dev/null
+++ b/src/benchmarks/eo/Makefile.am
@@ -0,0 +1,29 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-I$(top_srcdir)/src/include/eina \
6-I$(top_srcdir)/src/lib/eo \
7-I$(top_builddir)/src/include/eina \
8-I$(top_builddir)/src/lib/eo \
9@EFL_EO_BUILD@ \
10@EO_CFLAGS@
11
12EXTRA_PROGRAMS = eo_bench
13
14benchmark: eo_bench
15
16eo_bench_SOURCES = \
17class_simple.c \
18class_simple.h \
19eo_bench.c \
20eo_bench.h \
21eo_bench_eo_do.c
22
23eo_bench_LDADD = \
24$(top_builddir)/src/lib/eo/libeo.la \
25$(top_builddir)/src/lib/eina/libeina.la \
26@EO_LIBS@
27
28clean-local:
29 rm -rf *.gcno ..\#..\#src\#*.gcov *.gcda
diff --git a/src/benchmarks/eo/class_simple.c b/src/benchmarks/eo/class_simple.c
new file mode 100644
index 0000000000..2e8dc3f621
--- /dev/null
+++ b/src/benchmarks/eo/class_simple.c
@@ -0,0 +1,50 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "class_simple.h"
7
8#define MY_CLASS SIMPLE_CLASS
9
10EAPI Eo_Op SIMPLE_BASE_ID = 0;
11
12static void
13_a_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
14{
15 Simple_Public_Data *pd = class_data;
16 int a;
17 a = va_arg(*list, int);
18
19 pd->a = a;
20}
21
22static void
23_class_constructor(Eo_Class *klass)
24{
25 const Eo_Op_Func_Description func_desc[] = {
26 EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
27 EO_OP_FUNC_SENTINEL
28 };
29
30 eo_class_funcs_set(klass, func_desc);
31}
32
33static const Eo_Op_Description op_desc[] = {
34 EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
35 EO_OP_DESCRIPTION_SENTINEL
36};
37
38static const Eo_Class_Description class_desc = {
39 EO_VERSION,
40 "Simple",
41 EO_CLASS_TYPE_REGULAR,
42 EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
43 NULL,
44 sizeof(Simple_Public_Data),
45 _class_constructor,
46 NULL
47};
48
49EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, NULL)
50
diff --git a/src/benchmarks/eo/class_simple.h b/src/benchmarks/eo/class_simple.h
new file mode 100644
index 0000000000..b29e7987c1
--- /dev/null
+++ b/src/benchmarks/eo/class_simple.h
@@ -0,0 +1,23 @@
1#ifndef SIMPLE_H
2#define SIMPLE_H
3
4extern EAPI Eo_Op SIMPLE_BASE_ID;
5
6enum {
7 SIMPLE_SUB_ID_A_SET,
8 SIMPLE_SUB_ID_LAST
9};
10
11typedef struct
12{
13 int a;
14} Simple_Public_Data;
15
16#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
17
18#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
19
20#define SIMPLE_CLASS simple_class_get()
21const Eo_Class *simple_class_get(void);
22
23#endif
diff --git a/src/benchmarks/eo/eo_bench.c b/src/benchmarks/eo/eo_bench.c
new file mode 100644
index 0000000000..0da83a1f34
--- /dev/null
+++ b/src/benchmarks/eo/eo_bench.c
@@ -0,0 +1,55 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <limits.h>
8
9#include <Eina.h>
10
11#include "Eo.h"
12#include "eo_bench.h"
13
14typedef struct _Eina_Benchmark_Case Eina_Benchmark_Case;
15struct _Eina_Benchmark_Case
16{
17 const char *bench_case;
18 void (*build)(Eina_Benchmark *bench);
19};
20
21static const Eina_Benchmark_Case etc[] = {
22 { "eo_do", eo_bench_eo_do },
23 { NULL, NULL }
24};
25
26int
27main(int argc, char **argv)
28{
29 Eina_Benchmark *test;
30 unsigned int i;
31
32 if (argc != 2)
33 return -1;
34
35 eina_init();
36 eo_init();
37
38 for (i = 0; etc[i].bench_case; ++i)
39 {
40 test = eina_benchmark_new(etc[i].bench_case, argv[1]);
41 if (!test)
42 continue;
43
44 etc[i].build(test);
45
46 eina_benchmark_run(test);
47
48 eina_benchmark_free(test);
49 }
50
51 eo_shutdown();
52 eina_shutdown();
53
54 return 0;
55}
diff --git a/src/benchmarks/eo/eo_bench.h b/src/benchmarks/eo/eo_bench.h
new file mode 100644
index 0000000000..feea3bc333
--- /dev/null
+++ b/src/benchmarks/eo/eo_bench.h
@@ -0,0 +1,6 @@
1#ifndef EINA_BENCH_H_
2#define EINA_BENCH_H_
3
4void eo_bench_eo_do(Eina_Benchmark *bench);
5
6#endif
diff --git a/src/benchmarks/eo/eo_bench_eo_do.c b/src/benchmarks/eo/eo_bench_eo_do.c
new file mode 100644
index 0000000000..1e8d484979
--- /dev/null
+++ b/src/benchmarks/eo/eo_bench_eo_do.c
@@ -0,0 +1,26 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "eo_bench.h"
7#include "class_simple.h"
8
9static void
10bench_eo_do_general(int request)
11{
12 int i;
13 Eo *obj = eo_add(SIMPLE_CLASS, NULL);
14 for (i = 0 ; i < request ; i++)
15 {
16 eo_do(obj, simple_a_set(i));
17 }
18
19 eo_unref(obj);
20}
21
22void eo_bench_eo_do(Eina_Benchmark *bench)
23{
24 eina_benchmark_register(bench, "various",
25 EINA_BENCHMARK(bench_eo_do_general), 100, 10000, 500);
26}
diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am
index abdebd74f9..0a874138fb 100644
--- a/src/examples/Makefile.am
+++ b/src/examples/Makefile.am
@@ -1,15 +1,21 @@
1MAINTAINERCLEANFILES = Makefile.in 1MAINTAINERCLEANFILES = Makefile.in
2 2
3SUBDIRS = eina eet 3SUBDIRS = eina eet eo
4 4
5examples: 5examples:
6 @$(MAKE) $(AM_MAKEFLAGS) -C eina examples 6 @$(MAKE) $(AM_MAKEFLAGS) -C eina examples
7if EFL_BUILD_EET 7if EFL_BUILD_EET
8 @$(MAKE) $(AM_MAKEFLAGS) -C eet examples 8 @$(MAKE) $(AM_MAKEFLAGS) -C eet examples
9endif 9endif
10if EFL_BUILD_EO
11 @$(MAKE) $(AM_MAKEFLAGS) -C eo examples
12endif
10 13
11install-examples: 14install-examples:
12 @$(MAKE) $(AM_MAKEFLAGS) -C eina install-examples 15 @$(MAKE) $(AM_MAKEFLAGS) -C eina install-examples
13if EFL_BUILD_EET 16if EFL_BUILD_EET
14 @$(MAKE) $(AM_MAKEFLAGS) -C eet install-examples 17 @$(MAKE) $(AM_MAKEFLAGS) -C eet install-examples
15endif 18endif
19if EFL_BUILD_EO
20 @$(MAKE) $(AM_MAKEFLAGS) -C eo install-examples
21endif
diff --git a/src/examples/eo/Makefile.am b/src/examples/eo/Makefile.am
new file mode 100644
index 0000000000..d7719be5b8
--- /dev/null
+++ b/src/examples/eo/Makefile.am
@@ -0,0 +1,83 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I. \
5-I$(top_srcdir)/src/lib/eo \
6-I$(top_builddir)/src/lib/eo \
7@EFL_EO_BUILD@ \
8@EO_CFLAGS@
9
10EXTRA_PROGRAMS = eo_isa eo_simple
11
12if EO_BUILD_EXAMPLE_EVAS
13
14EXTRA_PROGRAMS += eo_evas
15
16endif
17
18eo_isa_SOURCES = \
19isa/eo_isa_complex.c \
20isa/eo_isa_complex.h \
21isa/eo_isa_interface.c \
22isa/eo_isa_interface.h \
23isa/eo_isa_main.c \
24isa/eo_isa_mixin.c \
25isa/eo_isa_mixin.h \
26isa/eo_isa_simple.c \
27isa/eo_isa_simple.h
28
29eo_isa_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
30
31if EO_BUILD_EXAMPLE_EVAS
32
33eo_evas_SOURCES = \
34evas/evas_elw_box.c \
35evas/evas_elw_box.h \
36evas/evas_elw_boxedbutton.c \
37evas/evas_elw_boxedbutton.h \
38evas/evas_elw_button.c \
39evas/evas_elw_button.h \
40evas/evas_elw_win.h \
41evas/evas_elw_win.c \
42evas/evas_evas_obj.c \
43evas/evas_evas_obj.h \
44evas/evas_test.c
45
46eo_evas_LDADD = $(top_builddir)/src/lib/eo/libeo.la @ELM_LIBS@ @EO_LIBS@
47
48endif
49
50eo_simple_SOURCES = \
51simple/simple_interface.c \
52simple/simple_interface.h \
53simple/simple_main.c \
54simple/simple_mixin.c \
55simple/simple_mixin.h \
56simple/simple_simple.c \
57simple/simple_simple.h
58
59eo_simple_LDADD = $(top_builddir)/src/lib/eo/libeo.la @EO_LIBS@
60
61examples: $(EXTRA_PROGRAMS)
62
63clean-local:
64 rm -f $(EXTRA_PROGRAMS)
65
66install-examples:
67 mkdir -p $(pkgdatadir)/examples/eo/isa
68 $(install_sh_DATA) -c $(eo_isa_SOURCES) $(pkgdatadir)/examples/eo/isa
69 mkdir -p $(pkgdatadir)/examples/eo/evas
70 $(install_sh_DATA) -c $(evas_SOURCES) $(pkgdatadir)/examples/eo/evas
71 mkdir -p $(pkgdatadir)/examples/eo/simple
72 $(install_sh_DATA) -c $(simple_SOURCES) $(pkgdatadir)/examples/eo/simple
73
74uninstall-local:
75 for f in $(eo_isa_SOURCES) ; do \
76 rm -f $(pkgdatadir)/examples/eo/isa/$$f ; \
77 done
78 for f in $(evas_SOURCES) ; do \
79 rm -f $(pkgdatadir)/examples/eo/evas/$$f ; \
80 done
81 for f in $(simple_SOURCES) ; do \
82 rm -f $(pkgdatadir)/examples/eo/simple/$$f ; \
83 done
diff --git a/src/examples/eo/evas/evas_elw_box.c b/src/examples/eo/evas/evas_elw_box.c
new file mode 100644
index 0000000000..1a2330f845
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_box.c
@@ -0,0 +1,74 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Elementary.h>
6
7#include "Eo.h"
8#include "evas_obj.h"
9#include "elw_box.h"
10
11EAPI Eo_Op ELW_BOX_BASE_ID = 0;
12
13typedef struct
14{
15 Evas_Object *bx;
16} Widget_Data;
17
18#define MY_CLASS ELW_BOX_CLASS
19
20static void
21_pack_end(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
22{
23 Widget_Data *wd = class_data;
24 Eo *child_obj;
25 child_obj = va_arg(*list, Eo *);
26 /* FIXME: Ref and the later uref child_obj here... */
27 elm_box_pack_end(wd->bx, eo_evas_object_get(child_obj));
28}
29
30static void
31_constructor(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
32{
33 eo_do_super(obj, eo_constructor());
34
35 Widget_Data *wd = class_data;
36
37 /* FIXME: An hack, because our tree is not yet only Eo */
38 wd->bx = elm_box_add(eo_evas_object_get(eo_parent_get(obj)));
39 evas_object_size_hint_align_set(wd->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
40 evas_object_size_hint_weight_set(wd->bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
41
42 eo_evas_object_set(obj, wd->bx);
43}
44
45static void
46_class_constructor(Eo_Class *klass)
47{
48 const Eo_Op_Func_Description func_desc[] = {
49 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
50 EO_OP_FUNC(ELW_BOX_ID(ELW_BOX_SUB_ID_PACK_END), _pack_end),
51 EO_OP_FUNC_SENTINEL
52 };
53
54 eo_class_funcs_set(klass, func_desc);
55}
56
57static const Eo_Op_Description op_desc[] = {
58 EO_OP_DESCRIPTION(ELW_BOX_SUB_ID_PACK_END, "Pack obj at the end of box."),
59 EO_OP_DESCRIPTION_SENTINEL
60};
61
62static const Eo_Class_Description class_desc = {
63 EO_VERSION,
64 "Elw Box",
65 EO_CLASS_TYPE_REGULAR,
66 EO_CLASS_DESCRIPTION_OPS(&ELW_BOX_BASE_ID, op_desc, ELW_BOX_SUB_ID_LAST),
67 NULL,
68 sizeof(Widget_Data),
69 _class_constructor,
70 NULL
71};
72
73EO_DEFINE_CLASS(elw_box_class_get, &class_desc, EXEVAS_OBJ_CLASS, NULL)
74
diff --git a/src/examples/eo/evas/evas_elw_box.h b/src/examples/eo/evas/evas_elw_box.h
new file mode 100644
index 0000000000..c25382cf34
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_box.h
@@ -0,0 +1,25 @@
1#ifndef ELW_BOX_H
2#define ELW_BOX_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op ELW_BOX_BASE_ID;
7
8enum {
9 ELW_BOX_SUB_ID_PACK_END,
10 ELW_BOX_SUB_ID_LAST
11};
12
13#define ELW_BOX_ID(sub_id) (ELW_BOX_BASE_ID + sub_id)
14
15/**
16 * @def elw_box_pack_end(obj)
17 * @brief Pack object to the end of the box
18 * @param[in] obj object to pack into box
19 */
20#define elw_box_pack_end(obj) ELW_BOX_ID(ELW_BOX_SUB_ID_PACK_END), EO_TYPECHECK(Eo *, obj)
21
22#define ELW_BOX_CLASS elw_box_class_get()
23const Eo_Class *elw_box_class_get(void);
24
25#endif
diff --git a/src/examples/eo/evas/evas_elw_boxedbutton.c b/src/examples/eo/evas/evas_elw_boxedbutton.c
new file mode 100644
index 0000000000..457dba892a
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_boxedbutton.c
@@ -0,0 +1,57 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Elementary.h>
6
7#include "Eo.h"
8#include "evas_obj.h"
9#include "elw_box.h"
10#include "elw_button.h"
11#include "elw_boxedbutton.h"
12
13typedef struct
14{
15// Evas_Object *bx;
16} Widget_Data;
17
18#define MY_CLASS ELW_BOXEDBUTTON_CLASS
19
20static void
21_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
22{
23 eo_do_super(obj, eo_constructor());
24
25 Eo *bt = eo_add(ELW_BUTTON_CLASS, obj);
26 eo_composite_attach(bt, obj);
27 eo_do(bt, eo_event_callback_forwarder_add(EV_CLICKED, obj));
28 eo_do(bt, exevas_obj_visibility_set(EINA_TRUE));
29
30 eo_do(obj, elw_box_pack_end(bt));
31 eo_unref(bt);
32}
33
34static void
35_class_constructor(Eo_Class *klass)
36{
37 const Eo_Op_Func_Description func_desc[] = {
38 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
39 EO_OP_FUNC_SENTINEL
40 };
41
42 eo_class_funcs_set(klass, func_desc);
43}
44
45static const Eo_Class_Description class_desc = {
46 EO_VERSION,
47 "Elw BoxedButton",
48 EO_CLASS_TYPE_REGULAR,
49 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
50 NULL,
51 sizeof(Widget_Data),
52 _class_constructor,
53 NULL
54};
55
56EO_DEFINE_CLASS(elw_boxedbutton_class_get, &class_desc, ELW_BOX_CLASS, ELW_BUTTON_CLASS, NULL)
57
diff --git a/src/examples/eo/evas/evas_elw_boxedbutton.h b/src/examples/eo/evas/evas_elw_boxedbutton.h
new file mode 100644
index 0000000000..e4ecfd2f83
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_boxedbutton.h
@@ -0,0 +1,9 @@
1#ifndef ELW_BOXEDBUTTON_H
2#define ELW_BOXEDBUTTON_H
3
4#include "Eo.h"
5
6#define ELW_BOXEDBUTTON_CLASS elw_boxedbutton_class_get()
7const Eo_Class *elw_boxedbutton_class_get(void);
8
9#endif
diff --git a/src/examples/eo/evas/evas_elw_button.c b/src/examples/eo/evas/evas_elw_button.c
new file mode 100644
index 0000000000..82fa39b354
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_button.c
@@ -0,0 +1,115 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Elementary.h>
6
7#include "Eo.h"
8#include "evas_obj.h"
9#include "elw_button.h"
10
11EAPI Eo_Op ELW_BUTTON_BASE_ID = 0;
12
13EAPI const Eo_Event_Description _EV_CLICKED =
14 EO_EVENT_DESCRIPTION("clicked", "Called when there was a click.");
15
16typedef struct
17{
18 Evas_Object *bt;
19} Widget_Data;
20
21#define MY_CLASS ELW_BUTTON_CLASS
22
23static void
24_position_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
25{
26 (void) obj;
27 Evas_Coord x, y;
28 x = va_arg(*list, Evas_Coord);
29 y = va_arg(*list, Evas_Coord);
30 printf("But set position %d,%d\n", x, y);
31 eo_do_super(obj, exevas_obj_position_set(x, y));
32}
33
34static void
35_text_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
36{
37 Widget_Data *wd = class_data;
38 const char *text;
39 text = va_arg(*list, const char *);
40 elm_object_text_set(wd->bt, text);
41}
42
43static void
44_btn_clicked(void *data, Evas_Object *evas_obj, void *event_info)
45{
46 (void) evas_obj;
47 (void) event_info;
48 Eo *obj = data;
49 eo_do(obj, eo_event_callback_call(EV_CLICKED, NULL, NULL));
50}
51
52static void
53_constructor(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
54{
55 eo_do_super(obj, eo_constructor());
56
57 Widget_Data *wd = class_data;
58
59 /* FIXME: An hack, because our tree is not yet only Eo */
60 wd->bt = elm_button_add(eo_evas_object_get(eo_parent_get(obj)));
61 evas_object_size_hint_align_set(wd->bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
62 evas_object_size_hint_weight_set(wd->bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
63 evas_object_smart_callback_add(wd->bt, "clicked", _btn_clicked, obj);
64
65 eo_evas_object_set(obj, wd->bt);
66}
67
68static void
69_destructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
70{
71 eo_do_super(obj, eo_destructor());
72
73 //Widget_Data *wd = class_data;
74 /* FIXME: Commented out because it's automatically done because our tree
75 * is not made of only eo */
76 //evas_object_del(wd->bt);
77}
78
79static void
80_class_constructor(Eo_Class *klass)
81{
82 const Eo_Op_Func_Description func_desc[] = {
83 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
84 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
85 EO_OP_FUNC(ELW_BUTTON_ID(ELW_BUTTON_SUB_ID_TEXT_SET), _text_set),
86 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_POSITION_SET), _position_set),
87 EO_OP_FUNC_SENTINEL
88 };
89
90 eo_class_funcs_set(klass, func_desc);
91}
92
93static const Eo_Op_Description op_desc[] = {
94 EO_OP_DESCRIPTION(ELW_BUTTON_SUB_ID_TEXT_SET, "Text of a text supporting evas object."), // FIXME: This ID sholudn't really be defined here...
95 EO_OP_DESCRIPTION_SENTINEL
96};
97
98static const Eo_Event_Description *event_desc[] = {
99 EV_CLICKED,
100 NULL
101};
102
103static const Eo_Class_Description class_desc = {
104 EO_VERSION,
105 "Elw Button",
106 EO_CLASS_TYPE_REGULAR,
107 EO_CLASS_DESCRIPTION_OPS(&ELW_BUTTON_BASE_ID, op_desc, ELW_BUTTON_SUB_ID_LAST),
108 event_desc,
109 sizeof(Widget_Data),
110 _class_constructor,
111 NULL
112};
113
114EO_DEFINE_CLASS(elw_button_class_get, &class_desc, EXEVAS_OBJ_CLASS, NULL)
115
diff --git a/src/examples/eo/evas/evas_elw_button.h b/src/examples/eo/evas/evas_elw_button.h
new file mode 100644
index 0000000000..8cecb8104e
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_button.h
@@ -0,0 +1,29 @@
1#ifndef ELW_BUTTON_H
2#define ELW_BUTTON_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op ELW_BUTTON_BASE_ID;
7
8enum {
9 ELW_BUTTON_SUB_ID_TEXT_SET,
10 ELW_BUTTON_SUB_ID_LAST
11};
12
13#define ELW_BUTTON_ID(sub_id) (ELW_BUTTON_BASE_ID + sub_id)
14
15/**
16 * @def elw_button_text_set(text)
17 * @brief Set button text
18 * @param[in] text text to assing to button
19 * FIXME Doesn't belong here, but just for the example...
20 */
21#define elw_button_text_set(text) ELW_BUTTON_ID(ELW_BUTTON_SUB_ID_TEXT_SET), EO_TYPECHECK(const char *, text)
22
23extern const Eo_Event_Description _EV_CLICKED;
24#define EV_CLICKED (&(_EV_CLICKED))
25
26#define ELW_BUTTON_CLASS elw_button_class_get()
27const Eo_Class *elw_button_class_get(void);
28
29#endif
diff --git a/src/examples/eo/evas/evas_elw_win.c b/src/examples/eo/evas/evas_elw_win.c
new file mode 100644
index 0000000000..dd9e1002f5
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_win.c
@@ -0,0 +1,74 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Elementary.h>
6
7#include "Eo.h"
8#include "evas_obj.h"
9#include "elw_win.h"
10
11typedef struct
12{
13 Evas_Object *win;
14 Evas_Object *bg;
15} Widget_Data;
16
17#define MY_CLASS ELW_WIN_CLASS
18
19static void
20my_win_del(void *data, Evas_Object *obj, void *event_info)
21{
22 /* called when my_win_main is requested to be deleted */
23 elm_exit(); /* exit the program's main loop that runs in elm_run() */
24 (void) data;
25 (void) obj;
26 (void) event_info;
27}
28
29static void
30_constructor(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
31{
32 eo_do_super(obj, eo_constructor());
33
34 Widget_Data *wd = class_data;
35
36 /* FIXME: Will actually do something about those when I care... */
37 wd->win = elm_win_add(NULL, "eo-test", ELM_WIN_BASIC);
38 elm_win_title_set(wd->win, "Eo Test");
39 elm_win_autodel_set(wd->win, EINA_TRUE);
40 evas_object_smart_callback_add(wd->win, "delete,request", my_win_del, NULL);
41
42 wd->bg = elm_bg_add(wd->win);
43 elm_win_resize_object_add(wd->win, wd->bg);
44 evas_object_size_hint_weight_set(wd->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
45 evas_object_show(wd->bg);
46
47 eo_evas_object_set(obj, wd->win);
48}
49
50static void
51_class_constructor(Eo_Class *klass)
52{
53 const Eo_Op_Func_Description func_desc[] = {
54 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
55 EO_OP_FUNC_SENTINEL
56 };
57
58 eo_class_funcs_set(klass, func_desc);
59}
60
61static const Eo_Class_Description class_desc = {
62 EO_VERSION,
63 "Elw Win",
64 EO_CLASS_TYPE_REGULAR,
65 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
66 NULL,
67 sizeof(Widget_Data),
68 _class_constructor,
69 NULL
70};
71
72
73EO_DEFINE_CLASS(elw_win_class_get, &class_desc, EXEVAS_OBJ_CLASS, NULL)
74
diff --git a/src/examples/eo/evas/evas_elw_win.h b/src/examples/eo/evas/evas_elw_win.h
new file mode 100644
index 0000000000..babb28b11a
--- /dev/null
+++ b/src/examples/eo/evas/evas_elw_win.h
@@ -0,0 +1,9 @@
1#ifndef ELW_WIN_H
2#define ELW_WIN_H
3
4#include "Eo.h"
5
6#define ELW_WIN_CLASS elw_win_class_get()
7const Eo_Class *elw_win_class_get(void);
8
9#endif
diff --git a/src/examples/eo/evas/evas_evas_obj.c b/src/examples/eo/evas/evas_evas_obj.c
new file mode 100644
index 0000000000..9d13c66813
--- /dev/null
+++ b/src/examples/eo/evas/evas_evas_obj.c
@@ -0,0 +1,146 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Elementary.h>
6
7#include "Eo.h"
8#include "evas_obj.h"
9
10#define MY_CLASS EXEVAS_OBJ_CLASS
11
12EAPI Eo_Op EXEVAS_OBJ_BASE_ID = 0;
13
14typedef struct
15{
16 Eina_List *children;
17} Widget_Data;
18
19static void
20_position_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
21{
22 Evas_Object *evas_obj = eo_evas_object_get(obj);
23 Evas_Coord x, y;
24 x = va_arg(*list, Evas_Coord);
25 y = va_arg(*list, Evas_Coord);
26 evas_object_move(evas_obj, x, y);
27}
28
29static void
30_size_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
31{
32 Evas_Object *evas_obj = eo_evas_object_get(obj);
33 Evas_Coord w, h;
34 w = va_arg(*list, Evas_Coord);
35 h = va_arg(*list, Evas_Coord);
36 evas_object_resize(evas_obj, w, h);
37}
38
39static void
40_color_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
41{
42 Evas_Object *evas_obj = eo_evas_object_get(obj);
43 int r, g, b, a;
44 r = va_arg(*list, int);
45 g = va_arg(*list, int);
46 b = va_arg(*list, int);
47 a = va_arg(*list, int);
48 evas_object_color_set(evas_obj, r, g, b, a);
49}
50
51static void
52_color_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
53{
54 Evas_Object *evas_obj = eo_evas_object_get(obj);
55 int *r, *g, *b, *a;
56 r = va_arg(*list, int *);
57 g = va_arg(*list, int *);
58 b = va_arg(*list, int *);
59 a = va_arg(*list, int *);
60 evas_object_color_get(evas_obj, r, g, b, a);
61}
62
63static void
64_visibility_set(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
65{
66 Evas_Object *evas_obj = eo_evas_object_get(obj);
67 Eina_Bool v;
68 v = va_arg(*list, int);
69 if (v) evas_object_show(evas_obj);
70 else evas_object_hide(evas_obj);
71}
72
73static void
74_child_add(Eo *obj, void *class_data, va_list *list)
75{
76 Widget_Data *wd = class_data;
77 Eo *child;
78 child = va_arg(*list, Eo *);
79 wd->children = eina_list_append(wd->children, eo_xref(child, obj));
80}
81
82static void
83_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
84{
85 eo_do_super(obj, eo_constructor());
86
87 /* Add type check. */
88 Eo *parent = eo_parent_get(obj);
89 if (parent)
90 eo_do(parent, exevas_obj_child_add(obj));
91}
92
93static void
94_destructor(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
95{
96 eo_do_super(obj, eo_destructor());
97
98 Widget_Data *wd = class_data;
99
100 Eo *child;
101 EINA_LIST_FREE(wd->children, child)
102 {
103 eo_xunref(child, obj);
104 }
105}
106
107static void
108_class_constructor(Eo_Class *klass)
109{
110 const Eo_Op_Func_Description func_desc[] = {
111 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
112 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
113 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_POSITION_SET), _position_set),
114 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_SIZE_SET), _size_set),
115 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_COLOR_SET), _color_set),
116 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_COLOR_GET), _color_get),
117 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_VISIBILITY_SET), _visibility_set),
118 EO_OP_FUNC(EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_CHILD_ADD), _child_add),
119 EO_OP_FUNC_SENTINEL
120 };
121
122 eo_class_funcs_set(klass, func_desc);
123}
124
125static const Eo_Op_Description op_desc[] = {
126 EO_OP_DESCRIPTION(EXEVAS_OBJ_SUB_ID_POSITION_SET, "Position of an evas object."),
127 EO_OP_DESCRIPTION(EXEVAS_OBJ_SUB_ID_SIZE_SET, "Size of an evas object."),
128 EO_OP_DESCRIPTION(EXEVAS_OBJ_SUB_ID_COLOR_SET, "Color of an evas object."),
129 EO_OP_DESCRIPTION(EXEVAS_OBJ_SUB_ID_COLOR_GET, "Color of an evas object."),
130 EO_OP_DESCRIPTION(EXEVAS_OBJ_SUB_ID_VISIBILITY_SET, "Visibility of an evas object."),
131 EO_OP_DESCRIPTION(EXEVAS_OBJ_SUB_ID_CHILD_ADD, "Add a child eo."),
132 EO_OP_DESCRIPTION_SENTINEL
133};
134
135static const Eo_Class_Description class_desc = {
136 EO_VERSION,
137 "Evas Object",
138 EO_CLASS_TYPE_REGULAR_NO_INSTANT,
139 EO_CLASS_DESCRIPTION_OPS(&EXEVAS_OBJ_BASE_ID, op_desc, EXEVAS_OBJ_SUB_ID_LAST),
140 NULL,
141 sizeof(Widget_Data),
142 _class_constructor,
143 NULL
144};
145
146EO_DEFINE_CLASS(evas_object_class_get, &class_desc, EO_BASE_CLASS, NULL)
diff --git a/src/examples/eo/evas/evas_evas_obj.h b/src/examples/eo/evas/evas_evas_obj.h
new file mode 100644
index 0000000000..7aa761c648
--- /dev/null
+++ b/src/examples/eo/evas/evas_evas_obj.h
@@ -0,0 +1,90 @@
1#ifndef EXEVAS_OBJ_H
2#define EXEVAS_OBJ_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op EXEVAS_OBJ_BASE_ID;
7
8enum {
9 EXEVAS_OBJ_SUB_ID_POSITION_SET,
10 EXEVAS_OBJ_SUB_ID_SIZE_SET,
11 EXEVAS_OBJ_SUB_ID_COLOR_SET,
12 EXEVAS_OBJ_SUB_ID_COLOR_GET,
13 EXEVAS_OBJ_SUB_ID_VISIBILITY_SET,
14 EXEVAS_OBJ_SUB_ID_CHILD_ADD,
15 EXEVAS_OBJ_SUB_ID_LAST
16};
17
18#define EXEVAS_OBJ_ID(sub_id) (EXEVAS_OBJ_BASE_ID + sub_id)
19
20/**
21 * @def exevas_obj_position_set(x, y)
22 * @brief Set object's position
23 * @param[in] x object's X position
24 * @param[in] y object's Y position
25 */
26#define exevas_obj_position_set(x, y) EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_POSITION_SET), EO_TYPECHECK(Evas_Coord, x), EO_TYPECHECK(Evas_Coord, y)
27
28/**
29 * @def exevas_obj_size_set(w, h)
30 * @brief Set object's size
31 * @param[in] w object's width
32 * @param[in] h object's height
33 */
34#define exevas_obj_size_set(w, h) EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_SIZE_SET), EO_TYPECHECK(Evas_Coord, w), EO_TYPECHECK(Evas_Coord, h)
35
36/**
37 * @def exevas_obj_color_set(r, g, b, a)
38 * @brief Set object's color
39 * @param[in] r r-value of color
40 * @param[in] g g-value of color
41 * @param[in] b b-value of color
42 * @param[in] a a-value of color
43 */
44#define exevas_obj_color_set(r, g, b, a) EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_COLOR_SET), EO_TYPECHECK(int, r), EO_TYPECHECK(int, g), EO_TYPECHECK(int, b), EO_TYPECHECK(int, a)
45
46/**
47 * @def exevas_obj_color_get(r, g, b, a)
48 * @brief Set object's position
49 * @param[out] r integer pointer for r-value of color
50 * @param[out] g integer pointer for g-value of color
51 * @param[out] b integer pointer for b-value of color
52 * @param[out] a integer pointer for a-value of color
53 */
54#define exevas_obj_color_get(r, g, b, a) EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_COLOR_GET), EO_TYPECHECK(int *, r), EO_TYPECHECK(int *, g), EO_TYPECHECK(int *, b), EO_TYPECHECK(int *, a)
55
56/**
57 * @def exevas_obj_visibility_set(v)
58 * @brief Set object's visible property
59 * @param[in] v True/False value
60 */
61#define exevas_obj_visibility_set(v) EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_VISIBILITY_SET), EO_TYPECHECK(Eina_Bool, v)
62
63/**
64 * @def exevas_obj_child_add(child)
65 * @brief Add child to current object
66 * @param[in] pointer to child object
67 */
68#define exevas_obj_child_add(child) EXEVAS_OBJ_ID(EXEVAS_OBJ_SUB_ID_CHILD_ADD), EO_TYPECHECK(Eo *, child)
69
70#define EXEVAS_OBJ_CLASS evas_object_class_get()
71const Eo_Class *evas_object_class_get(void);
72
73#define EXEVAS_OBJ_STR "Evas_Obj"
74/* FIXME: Hack in the meanwhile. */
75static inline Evas_Object *
76eo_evas_object_get(const Eo *obj)
77{
78 void *data;
79 eo_do((Eo *) obj, eo_base_data_get(EXEVAS_OBJ_STR, &data));
80 return data;
81}
82
83/* FIXME: Hack in the meanwhile. */
84static inline void
85eo_evas_object_set(Eo *obj, Evas_Object *evas_obj)
86{
87 eo_do(obj, eo_base_data_set(EXEVAS_OBJ_STR, evas_obj, NULL));
88}
89
90#endif
diff --git a/src/examples/eo/evas/evas_test.c b/src/examples/eo/evas/evas_test.c
new file mode 100644
index 0000000000..7a5751367b
--- /dev/null
+++ b/src/examples/eo/evas/evas_test.c
@@ -0,0 +1,68 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Elementary.h>
6
7#include "evas_obj.h"
8#include "elw_button.h"
9#include "elw_box.h"
10#include "elw_boxedbutton.h"
11#include "elw_win.h"
12
13Eina_Bool
14_btn_clicked_cb(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
15{
16 (void) obj;
17 (void) event_info;
18 const Eo_Class *klass = eo_class_get(obj);
19 printf("%s obj-type:'%s' data:'%s'\n", desc->name, eo_class_name_get(klass), (const char *) data);
20
21 return EO_CALLBACK_CONTINUE;
22}
23
24int
25main(int argc, char *argv[])
26{
27 Evas_Coord winw, winh;
28 {
29 winw = 400;
30 winh = 400;
31 }
32
33 elm_init(argc, argv);
34 eo_init();
35
36 Eo *win = eo_add(ELW_WIN_CLASS, NULL);
37 eo_do(win, exevas_obj_size_set(winw, winh), exevas_obj_visibility_set(EINA_TRUE));
38
39 Eo *bt = eo_add(ELW_BUTTON_CLASS, win);
40 eo_do(bt, exevas_obj_position_set(25, 25),
41 exevas_obj_size_set(50, 50),
42 exevas_obj_color_set(255, 0, 0, 255),
43 elw_button_text_set("Click"),
44 exevas_obj_visibility_set(EINA_TRUE));
45 eo_do(bt, eo_event_callback_add(EV_CLICKED, _btn_clicked_cb, "btn"));
46
47 int r, g, b, a;
48 eo_do(bt, exevas_obj_color_get(&r, &g, &b, &a));
49 printf("RGBa(%d, %d, %d, %d)\n", r, g, b, a);
50
51 Eo *bx = eo_add(ELW_BOXEDBUTTON_CLASS, win);
52 eo_do(bx, exevas_obj_position_set(100, 100),
53 exevas_obj_size_set(70, 70),
54 exevas_obj_color_set(0, 0, 255, 255),
55 elw_button_text_set("Click2"),
56 exevas_obj_visibility_set(EINA_TRUE));
57 eo_do(bx, eo_event_callback_add(EV_CLICKED, _btn_clicked_cb, "bxedbtn"));
58
59 elm_run();
60
61 eo_unref(bx);
62 eo_unref(bt);
63 eo_unref(win);
64 eo_shutdown();
65 elm_shutdown();
66 return 0;
67}
68
diff --git a/src/examples/eo/isa/eo_isa_complex.c b/src/examples/eo/isa/eo_isa_complex.c
new file mode 100644
index 0000000000..4e4ff3e2c9
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_complex.c
@@ -0,0 +1,21 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "eo_isa_complex.h"
7
8#define MY_CLASS COMPLEX_CLASS
9
10static const Eo_Class_Description class_desc = {
11 EO_VERSION,
12 "Complex",
13 EO_CLASS_TYPE_REGULAR,
14 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
15 NULL,
16 0,
17 NULL,
18 NULL
19};
20
21EO_DEFINE_CLASS(complex_class_get, &class_desc, SIMPLE_CLASS, NULL);
diff --git a/src/examples/eo/isa/eo_isa_complex.h b/src/examples/eo/isa/eo_isa_complex.h
new file mode 100644
index 0000000000..035eca0741
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_complex.h
@@ -0,0 +1,10 @@
1#ifndef COMPLEX_H
2#define COMPLEX_H
3
4#include "Eo.h"
5#include "eo_isa_simple.h"
6
7#define COMPLEX_CLASS complex_class_get()
8const Eo_Class *complex_class_get(void);
9
10#endif
diff --git a/src/examples/eo/isa/eo_isa_interface.c b/src/examples/eo/isa/eo_isa_interface.c
new file mode 100644
index 0000000000..8009012e21
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_interface.c
@@ -0,0 +1,29 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "eo_isa_interface.h"
7
8EAPI Eo_Op INTERFACE_BASE_ID = 0;
9
10#define MY_CLASS INTERFACE_CLASS
11
12static const Eo_Op_Description op_desc[] = {
13 EO_OP_DESCRIPTION(INTERFACE_SUB_ID_A_POWER_3_GET, "Get the a^3"),
14 EO_OP_DESCRIPTION_SENTINEL
15};
16
17static const Eo_Class_Description class_desc = {
18 EO_VERSION,
19 "Interface",
20 EO_CLASS_TYPE_INTERFACE,
21 EO_CLASS_DESCRIPTION_OPS(&INTERFACE_BASE_ID, op_desc, INTERFACE_SUB_ID_LAST),
22 NULL,
23 0,
24 NULL,
25 NULL
26};
27
28EO_DEFINE_CLASS(interface_class_get, &class_desc, NULL, NULL)
29
diff --git a/src/examples/eo/isa/eo_isa_interface.h b/src/examples/eo/isa/eo_isa_interface.h
new file mode 100644
index 0000000000..c5bf43e135
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_interface.h
@@ -0,0 +1,26 @@
1#ifndef INTERFACE_H
2#define INTERFACE_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op INTERFACE_BASE_ID;
7
8enum {
9 INTERFACE_SUB_ID_A_POWER_3_GET,
10 INTERFACE_SUB_ID_LAST
11};
12
13#define INTERFACE_ID(sub_id) (INTERFACE_BASE_ID + sub_id)
14
15
16/**
17 * @def interface_a_power_3_get(ret)
18 * @brief Get a^3
19 * @param[out] ret integer pointer to ret - value
20 */
21#define interface_a_power_3_get(ret) INTERFACE_ID(INTERFACE_SUB_ID_A_POWER_3_GET), EO_TYPECHECK(int *, ret)
22
23#define INTERFACE_CLASS interface_class_get()
24const Eo_Class *interface_class_get(void);
25
26#endif
diff --git a/src/examples/eo/isa/eo_isa_main.c b/src/examples/eo/isa/eo_isa_main.c
new file mode 100644
index 0000000000..567ef32542
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_main.c
@@ -0,0 +1,36 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "eo_isa_simple.h"
7#include "eo_isa_complex.h"
8
9int
10main(int argc, char *argv[])
11{
12 (void) argc;
13 (void) argv;
14 eo_init();
15
16 Eo *simpleobj = eo_add(SIMPLE_CLASS, NULL);
17 Eo *complexobj = eo_add(COMPLEX_CLASS, NULL);
18
19 printf("Simple: isa-simple:%d isa-complex:%d isa-mixin:%d isa-interface:%d\n",
20 eo_isa(simpleobj, SIMPLE_CLASS),
21 eo_isa(simpleobj, COMPLEX_CLASS),
22 eo_isa(simpleobj, MIXIN_CLASS),
23 eo_isa(simpleobj, INTERFACE_CLASS));
24 printf("Complex: isa-simple:%d isa-complex:%d isa-mixin:%d isa-interface:%d\n",
25 eo_isa(complexobj, SIMPLE_CLASS),
26 eo_isa(complexobj, COMPLEX_CLASS),
27 eo_isa(complexobj, MIXIN_CLASS),
28 eo_isa(complexobj, INTERFACE_CLASS));
29
30 eo_unref(simpleobj);
31 eo_unref(complexobj);
32
33 eo_shutdown();
34 return 0;
35}
36
diff --git a/src/examples/eo/isa/eo_isa_mixin.c b/src/examples/eo/isa/eo_isa_mixin.c
new file mode 100644
index 0000000000..71f1d859cc
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_mixin.c
@@ -0,0 +1,53 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "eo_isa_mixin.h"
7#include "eo_isa_simple.h"
8
9EAPI Eo_Op MIXIN_BASE_ID = 0;
10
11#define MY_CLASS MIXIN_CLASS
12
13static void
14_a_square_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
15{
16 int a;
17 eo_do(obj, simple_a_get(&a));
18 int *ret = va_arg(*list, int *);
19 if (ret)
20 *ret = a * a;
21 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
22}
23
24static void
25_class_constructor(Eo_Class *klass)
26{
27 const Eo_Op_Func_Description func_desc[] = {
28 EO_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_A_SQUARE_GET), _a_square_get),
29 EO_OP_FUNC_SENTINEL
30 };
31
32 eo_class_funcs_set(klass, func_desc);
33}
34
35
36static const Eo_Op_Description op_desc[] = {
37 EO_OP_DESCRIPTION(MIXIN_SUB_ID_A_SQUARE_GET, "Get the value of A^2"),
38 EO_OP_DESCRIPTION_SENTINEL
39};
40
41static const Eo_Class_Description class_desc = {
42 EO_VERSION,
43 "Mixin",
44 EO_CLASS_TYPE_MIXIN,
45 EO_CLASS_DESCRIPTION_OPS(&MIXIN_BASE_ID, op_desc, MIXIN_SUB_ID_LAST),
46 NULL,
47 0,
48 _class_constructor,
49 NULL
50};
51
52EO_DEFINE_CLASS(mixin_class_get, &class_desc, NULL, NULL)
53
diff --git a/src/examples/eo/isa/eo_isa_mixin.h b/src/examples/eo/isa/eo_isa_mixin.h
new file mode 100644
index 0000000000..539504d3ad
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_mixin.h
@@ -0,0 +1,26 @@
1#ifndef MIXIN_H
2#define MIXIN_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op MIXIN_BASE_ID;
7
8enum {
9 MIXIN_SUB_ID_A_SQUARE_GET,
10 MIXIN_SUB_ID_LAST
11};
12
13#define MIXIN_ID(sub_id) (MIXIN_BASE_ID + sub_id)
14
15
16/**
17 * @def mixin_a_square_get(ret)
18 * @brief Get the square of a.
19 * @param[out] ret the square of a
20 */
21#define mixin_a_square_get(ret) MIXIN_ID(MIXIN_SUB_ID_A_SQUARE_GET), EO_TYPECHECK(int *, ret)
22
23#define MIXIN_CLASS mixin_class_get()
24const Eo_Class *mixin_class_get(void);
25
26#endif
diff --git a/src/examples/eo/isa/eo_isa_simple.c b/src/examples/eo/isa/eo_isa_simple.c
new file mode 100644
index 0000000000..789c5f4711
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_simple.c
@@ -0,0 +1,78 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "eo_isa_simple.h"
7
8EAPI Eo_Op SIMPLE_BASE_ID = 0;
9
10typedef struct
11{
12 int a;
13} Private_Data;
14
15#define MY_CLASS SIMPLE_CLASS
16
17static void
18_a_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
19{
20 const Private_Data *pd = class_data;
21 int *a;
22 a = va_arg(*list, int *);
23 *a = pd->a;
24 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
25}
26
27static void
28_a_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
29{
30 Private_Data *pd = class_data;
31 int a;
32 a = va_arg(*list, int);
33 pd->a = a;
34 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
35}
36
37static void
38_a_power_3_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
39{
40 const Private_Data *pd = class_data;
41 int *ret;
42 ret = va_arg(*list, int *);
43 if (ret)
44 *ret = pd->a * pd->a * pd->a;
45 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
46}
47
48static void
49_class_constructor(Eo_Class *klass)
50{
51 const Eo_Op_Func_Description func_desc[] = {
52 EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
53 EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
54 EO_OP_FUNC(INTERFACE_ID(INTERFACE_SUB_ID_A_POWER_3_GET), _a_power_3_get),
55 EO_OP_FUNC_SENTINEL
56 };
57
58 eo_class_funcs_set(klass, func_desc);
59}
60
61static const Eo_Op_Description op_desc[] = {
62 EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
63 EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "Get property A"),
64 EO_OP_DESCRIPTION_SENTINEL
65};
66
67static const Eo_Class_Description class_desc = {
68 EO_VERSION,
69 "Simple",
70 EO_CLASS_TYPE_REGULAR,
71 EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
72 NULL,
73 sizeof(Private_Data),
74 _class_constructor,
75 NULL
76};
77
78EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, INTERFACE_CLASS, MIXIN_CLASS, NULL);
diff --git a/src/examples/eo/isa/eo_isa_simple.h b/src/examples/eo/isa/eo_isa_simple.h
new file mode 100644
index 0000000000..eead797238
--- /dev/null
+++ b/src/examples/eo/isa/eo_isa_simple.h
@@ -0,0 +1,35 @@
1#ifndef SIMPLE_H
2#define SIMPLE_H
3
4#include "Eo.h"
5#include "eo_isa_interface.h"
6#include "eo_isa_mixin.h"
7
8extern EAPI Eo_Op SIMPLE_BASE_ID;
9
10enum {
11 SIMPLE_SUB_ID_A_SET,
12 SIMPLE_SUB_ID_A_GET,
13 SIMPLE_SUB_ID_LAST
14};
15
16#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
17
18/**
19 * @def simple_a_set(a)
20 * @brief Set value to a-property
21 * @param[in] a integer value to set
22 */
23#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
24
25/**
26 * @def simple_a_get(a)
27 * @brief Get value of a-property
28 * @param[out] integer pointer to a-value
29 */
30#define simple_a_get(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EO_TYPECHECK(int *, a)
31
32#define SIMPLE_CLASS simple_class_get()
33const Eo_Class *simple_class_get(void);
34
35#endif
diff --git a/src/examples/eo/simple/simple_interface.c b/src/examples/eo/simple/simple_interface.c
new file mode 100644
index 0000000000..e59107267a
--- /dev/null
+++ b/src/examples/eo/simple/simple_interface.c
@@ -0,0 +1,29 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "simple_interface.h"
7
8EAPI Eo_Op INTERFACE_BASE_ID = 0;
9
10#define MY_CLASS INTERFACE_CLASS
11
12static const Eo_Op_Description op_desc[] = {
13 EO_OP_DESCRIPTION(INTERFACE_SUB_ID_A_POWER_3_GET, "Get the a^3"),
14 EO_OP_DESCRIPTION_SENTINEL
15};
16
17static const Eo_Class_Description class_desc = {
18 EO_VERSION,
19 "Interface",
20 EO_CLASS_TYPE_INTERFACE,
21 EO_CLASS_DESCRIPTION_OPS(&INTERFACE_BASE_ID, op_desc, INTERFACE_SUB_ID_LAST),
22 NULL,
23 0,
24 NULL,
25 NULL
26};
27
28EO_DEFINE_CLASS(interface_class_get, &class_desc, NULL, NULL)
29
diff --git a/src/examples/eo/simple/simple_interface.h b/src/examples/eo/simple/simple_interface.h
new file mode 100644
index 0000000000..c5bf43e135
--- /dev/null
+++ b/src/examples/eo/simple/simple_interface.h
@@ -0,0 +1,26 @@
1#ifndef INTERFACE_H
2#define INTERFACE_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op INTERFACE_BASE_ID;
7
8enum {
9 INTERFACE_SUB_ID_A_POWER_3_GET,
10 INTERFACE_SUB_ID_LAST
11};
12
13#define INTERFACE_ID(sub_id) (INTERFACE_BASE_ID + sub_id)
14
15
16/**
17 * @def interface_a_power_3_get(ret)
18 * @brief Get a^3
19 * @param[out] ret integer pointer to ret - value
20 */
21#define interface_a_power_3_get(ret) INTERFACE_ID(INTERFACE_SUB_ID_A_POWER_3_GET), EO_TYPECHECK(int *, ret)
22
23#define INTERFACE_CLASS interface_class_get()
24const Eo_Class *interface_class_get(void);
25
26#endif
diff --git a/src/examples/eo/simple/simple_main.c b/src/examples/eo/simple/simple_main.c
new file mode 100644
index 0000000000..a93a5e37d2
--- /dev/null
+++ b/src/examples/eo/simple/simple_main.c
@@ -0,0 +1,31 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "simple_simple.h"
7
8int
9main(int argc, char *argv[])
10{
11 (void) argc;
12 (void) argv;
13 eo_init();
14
15 Eo *obj = eo_add(SIMPLE_CLASS, NULL);
16
17 eo_do(obj, simple_a_set(4));
18
19 int a = 0, a2 = 0, a3 = 0;
20
21 eo_do(obj, simple_a_get(&a),
22 interface_a_power_3_get(&a3),
23 mixin_a_square_get(&a2));
24
25 printf("Got %d %d %d\n", a, a2, a3);
26
27 eo_unref(obj);
28 eo_shutdown();
29 return 0;
30}
31
diff --git a/src/examples/eo/simple/simple_mixin.c b/src/examples/eo/simple/simple_mixin.c
new file mode 100644
index 0000000000..389b0891f9
--- /dev/null
+++ b/src/examples/eo/simple/simple_mixin.c
@@ -0,0 +1,53 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "simple_mixin.h"
7#include "simple_simple.h"
8
9EAPI Eo_Op MIXIN_BASE_ID = 0;
10
11#define MY_CLASS MIXIN_CLASS
12
13static void
14_a_square_get(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
15{
16 int a;
17 eo_do(obj, simple_a_get(&a));
18 int *ret = va_arg(*list, int *);
19 if (ret)
20 *ret = a * a;
21 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
22}
23
24static void
25_class_constructor(Eo_Class *klass)
26{
27 const Eo_Op_Func_Description func_desc[] = {
28 EO_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_A_SQUARE_GET), _a_square_get),
29 EO_OP_FUNC_SENTINEL
30 };
31
32 eo_class_funcs_set(klass, func_desc);
33}
34
35
36static const Eo_Op_Description op_desc[] = {
37 EO_OP_DESCRIPTION(MIXIN_SUB_ID_A_SQUARE_GET, "Get the value of A^2"),
38 EO_OP_DESCRIPTION_SENTINEL
39};
40
41static const Eo_Class_Description class_desc = {
42 EO_VERSION,
43 "Mixin",
44 EO_CLASS_TYPE_MIXIN,
45 EO_CLASS_DESCRIPTION_OPS(&MIXIN_BASE_ID, op_desc, MIXIN_SUB_ID_LAST),
46 NULL,
47 0,
48 _class_constructor,
49 NULL
50};
51
52EO_DEFINE_CLASS(mixin_class_get, &class_desc, NULL, NULL)
53
diff --git a/src/examples/eo/simple/simple_mixin.h b/src/examples/eo/simple/simple_mixin.h
new file mode 100644
index 0000000000..539504d3ad
--- /dev/null
+++ b/src/examples/eo/simple/simple_mixin.h
@@ -0,0 +1,26 @@
1#ifndef MIXIN_H
2#define MIXIN_H
3
4#include "Eo.h"
5
6extern EAPI Eo_Op MIXIN_BASE_ID;
7
8enum {
9 MIXIN_SUB_ID_A_SQUARE_GET,
10 MIXIN_SUB_ID_LAST
11};
12
13#define MIXIN_ID(sub_id) (MIXIN_BASE_ID + sub_id)
14
15
16/**
17 * @def mixin_a_square_get(ret)
18 * @brief Get the square of a.
19 * @param[out] ret the square of a
20 */
21#define mixin_a_square_get(ret) MIXIN_ID(MIXIN_SUB_ID_A_SQUARE_GET), EO_TYPECHECK(int *, ret)
22
23#define MIXIN_CLASS mixin_class_get()
24const Eo_Class *mixin_class_get(void);
25
26#endif
diff --git a/src/examples/eo/simple/simple_simple.c b/src/examples/eo/simple/simple_simple.c
new file mode 100644
index 0000000000..a172bce3fc
--- /dev/null
+++ b/src/examples/eo/simple/simple_simple.c
@@ -0,0 +1,78 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Eo.h"
6#include "simple_simple.h"
7
8EAPI Eo_Op SIMPLE_BASE_ID = 0;
9
10typedef struct
11{
12 int a;
13} Private_Data;
14
15#define MY_CLASS SIMPLE_CLASS
16
17static void
18_a_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
19{
20 const Private_Data *pd = class_data;
21 int *a;
22 a = va_arg(*list, int *);
23 *a = pd->a;
24 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
25}
26
27static void
28_a_set(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
29{
30 Private_Data *pd = class_data;
31 int a;
32 a = va_arg(*list, int);
33 pd->a = a;
34 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
35}
36
37static void
38_a_power_3_get(Eo *obj EINA_UNUSED, void *class_data, va_list *list)
39{
40 const Private_Data *pd = class_data;
41 int *ret;
42 ret = va_arg(*list, int *);
43 if (ret)
44 *ret = pd->a * pd->a * pd->a;
45 printf("%s %s\n", eo_class_name_get(MY_CLASS), __func__);
46}
47
48static void
49_class_constructor(Eo_Class *klass)
50{
51 const Eo_Op_Func_Description func_desc[] = {
52 EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set),
53 EO_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get),
54 EO_OP_FUNC(INTERFACE_ID(INTERFACE_SUB_ID_A_POWER_3_GET), _a_power_3_get),
55 EO_OP_FUNC_SENTINEL
56 };
57
58 eo_class_funcs_set(klass, func_desc);
59}
60
61static const Eo_Op_Description op_desc[] = {
62 EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "Set property A"),
63 EO_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "Get property A"),
64 EO_OP_DESCRIPTION_SENTINEL
65};
66
67static const Eo_Class_Description class_desc = {
68 EO_VERSION,
69 "Simple",
70 EO_CLASS_TYPE_REGULAR,
71 EO_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST),
72 NULL,
73 sizeof(Private_Data),
74 _class_constructor,
75 NULL
76};
77
78EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_BASE_CLASS, INTERFACE_CLASS, MIXIN_CLASS, NULL);
diff --git a/src/examples/eo/simple/simple_simple.h b/src/examples/eo/simple/simple_simple.h
new file mode 100644
index 0000000000..36d4a00713
--- /dev/null
+++ b/src/examples/eo/simple/simple_simple.h
@@ -0,0 +1,35 @@
1#ifndef SIMPLE_H
2#define SIMPLE_H
3
4#include "Eo.h"
5#include "simple_interface.h"
6#include "simple_mixin.h"
7
8extern EAPI Eo_Op SIMPLE_BASE_ID;
9
10enum {
11 SIMPLE_SUB_ID_A_SET,
12 SIMPLE_SUB_ID_A_GET,
13 SIMPLE_SUB_ID_LAST
14};
15
16#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id)
17
18/**
19 * @def simple_a_set(a)
20 * @brief Set value to a-property
21 * @param[in] a integer value to set
22 */
23#define simple_a_set(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EO_TYPECHECK(int, a)
24
25/**
26 * @def simple_a_get(a)
27 * @brief Get value of a-property
28 * @param[out] integer pointer to a-value
29 */
30#define simple_a_get(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EO_TYPECHECK(int *, a)
31
32#define SIMPLE_CLASS simple_class_get()
33const Eo_Class *simple_class_get(void);
34
35#endif
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 24591e5676..e715faa107 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -15,3 +15,9 @@ if EFL_BUILD_EET
15SUBDIRS += eet 15SUBDIRS += eet
16 16
17endif 17endif
18
19if EFL_BUILD_EO
20
21SUBDIRS += eo
22
23endif
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
new file mode 100644
index 0000000000..ffb46fbeac
--- /dev/null
+++ b/src/lib/eo/Eo.h
@@ -0,0 +1,1200 @@
1#ifndef EO_H
2#define EO_H
3
4#include <stdarg.h>
5#include <Eina.h>
6
7#ifdef EAPI
8# undef EAPI
9#endif
10
11#ifdef _WIN32
12# ifdef EFL_EO_BUILD
13# ifdef DLL_EXPORT
14# define EAPI __declspec(dllexport)
15# else
16# define EAPI
17# endif /* ! DLL_EXPORT */
18# else
19# define EAPI __declspec(dllimport)
20# endif /* ! EFL_EO_BUILD */
21#else
22# ifdef __GNUC__
23# if __GNUC__ >= 4
24# define EAPI __attribute__ ((visibility("default")))
25# else
26# define EAPI
27# endif
28# else
29# define EAPI
30# endif
31#endif /* ! _WIN32 */
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/**
38 * @var _eo_class_creation_lock
39 * This variable is used for locking purposes in the class_get function
40 * defined in #EO_DEFINE_CLASS.
41 * This is just to work around the fact that we need to init locks before
42 * using them.
43 * Don't touch it if you don't know what you are doing.
44 * @internal
45 */
46EAPI extern Eina_Lock _eo_class_creation_lock;
47
48/**
49 * @internal
50 * An enum representing the possible types of an Op.
51 */
52enum _Eo_Op_Type
53{
54 EO_OP_TYPE_INVALID = -1, /**< Invalid op. */
55 EO_OP_TYPE_REGULAR = 0, /**< Regular op. */
56 EO_OP_TYPE_CLASS, /**< Class op - a class op. Like static in Java/C++. */
57};
58
59/**
60 * @internal
61 * @typedef Eo_Op_Type
62 * A convenience typedef for #_Eo_Op_Type.
63 */
64typedef enum _Eo_Op_Type Eo_Op_Type;
65
66/**
67 * @defgroup Eo Eo Generic Object System
68 *
69 * The Eo generic object system. It was designed to be the base object
70 * system for the EFL.
71 *
72 * @{
73 */
74
75/**
76 * @def EO_TYPECHECK(type, x)
77 *
78 * Checks x is castable to type "type" and casts it to it.
79 * @param type The C type to check against.
80 * @param x the variable to test and cast.
81 */
82#define EO_TYPECHECK(type, x) \
83 ({ \
84 type __x; \
85 __x = x; \
86 (type) __x; \
87 })
88
89/**
90 * @typedef Eo
91 * The basic Object type.
92 */
93typedef struct _Eo Eo;
94/**
95 * @typedef Eo_Op
96 * The Eo operation type id.
97 */
98typedef unsigned int Eo_Op;
99
100/**
101 * @typedef Eo_Class
102 * The basic Object class type.
103 * @ingroup Eo_Class
104 */
105typedef struct _Eo_Class Eo_Class;
106
107/**
108 * @typedef Eo_Class_Id
109 * An Id of a class.
110 * @ingroup Eo_Class
111 */
112typedef size_t Eo_Class_Id;
113
114/**
115 * @def EO_NOOP
116 * A special #Eo_Op meaning "No operation".
117 */
118#define EO_NOOP ((Eo_Op) 0)
119
120/**
121 * @typedef eo_op_func_type
122 * The type of the Op functions. This is the type of the functions used by
123 * Eo.
124 *
125 * @see eo_op_func_type_class
126 */
127typedef void (*eo_op_func_type)(Eo *, void *class_data, va_list *list);
128
129/**
130 * @typedef eo_op_func_type_class
131 * The type of the class Op functions. This is the same as #eo_op_func_type,\
132 * exepct that it's for usage with class functions, and not with object
133 * functions.
134 *
135 * @see eo_op_func_type
136 */
137typedef void (*eo_op_func_type_class)(const Eo_Class *, va_list *list);
138
139/**
140 * @addtogroup Eo_Events Eo's Event Handling
141 * @{
142 */
143
144/**
145 * @struct _Eo_Event_Description
146 * This struct holds the description of a specific event.
147 */
148struct _Eo_Event_Description
149{
150 const char *name; /**< name of the event. */
151 const char *doc; /**< Explanation about the event. */
152};
153
154/**
155 * @typedef Eo_Event_Description
156 * A convenience typedef for #_Eo_Event_Description
157 */
158typedef struct _Eo_Event_Description Eo_Event_Description;
159
160/**
161 * @def EO_EVENT_DESCRIPTION(name, doc)
162 * An helper macro to help populating #Eo_Event_Description
163 * @param name The name of the event.
164 * @param doc Additional doc for the event.
165 * @see Eo_Event_Description
166 */
167#define EO_EVENT_DESCRIPTION(name, doc) { name, doc }
168
169/**
170 * @}
171 */
172
173/**
174 * @addtogroup Eo_Class Eo Class
175 * @{
176 */
177
178/**
179 * @def EO_DEFINE_CLASS(class_get_func_name, class_desc, parent_class, ...)
180 * A convenience macro to be used for creating the class_get function. This
181 * macro is fairly simple but should still be used as it'll let us improve
182 * things easily.
183 * @param class_get_func_name the name of the wanted class_get function name.
184 * @param class_desc the class description.
185 * @param parent_class The parent class for the function. Look at eo_class_new() for more information.
186 * @param ... List of etxensions. Look at eo_class_new() for more information.
187 *
188 * You must use this macro if you want thread safety in class creation.
189 */
190#define EO_DEFINE_CLASS(class_get_func_name, class_desc, parent_class, ...) \
191EAPI const Eo_Class * \
192class_get_func_name(void) \
193{ \
194 const Eo_Class *_tmp_parent_class; \
195 static volatile char lk_init = 0; \
196 static Eina_Lock _my_lock; \
197 static const Eo_Class * volatile _my_class = NULL; \
198 if (EINA_LIKELY(!!_my_class)) return _my_class; \
199 \
200 eina_lock_take(&_eo_class_creation_lock); \
201 if (!lk_init) \
202 eina_lock_new(&_my_lock); \
203 if (lk_init < 2) eina_lock_take(&_my_lock); \
204 if (!lk_init) \
205 lk_init = 1; \
206 else \
207 { \
208 if (lk_init < 2) eina_lock_release(&_my_lock); \
209 eina_lock_release(&_eo_class_creation_lock); \
210 return _my_class; \
211 } \
212 eina_lock_release(&_eo_class_creation_lock); \
213 _tmp_parent_class = parent_class; \
214 _my_class = eo_class_new(class_desc, _tmp_parent_class, __VA_ARGS__); \
215 eina_lock_release(&_my_lock); \
216 \
217 eina_lock_take(&_eo_class_creation_lock); \
218 eina_lock_free(&_my_lock); \
219 lk_init = 2; \
220 eina_lock_release(&_eo_class_creation_lock); \
221 return _my_class; \
222}
223
224
225/**
226 * An enum representing the possible types of an Eo class.
227 */
228enum _Eo_Class_Type
229{
230 EO_CLASS_TYPE_REGULAR = 0, /**< Regular class. */
231 EO_CLASS_TYPE_REGULAR_NO_INSTANT, /**< Regular non instant-able class. */
232 EO_CLASS_TYPE_INTERFACE, /**< Interface */
233 EO_CLASS_TYPE_MIXIN /**< Mixin */
234};
235
236/**
237 * @typedef Eo_Class_Type
238 * A convenience typedef for #_Eo_Class_Type.
239 */
240typedef enum _Eo_Class_Type Eo_Class_Type;
241
242/**
243 * @struct _Eo_Op_Func_Description
244 * Used to associate an Op with a func.
245 * @see eo_class_funcs_set
246 */
247struct _Eo_Op_Func_Description
248{
249 Eo_Op op; /**< The op */
250 eo_op_func_type func; /**< The function to call for the op. */
251 Eo_Op_Type op_type; /**< The type of the op */
252};
253
254/**
255 * @typedef Eo_Op_Func_Description
256 * A convenience typedef for #_Eo_Op_Func_Description
257 */
258typedef struct _Eo_Op_Func_Description Eo_Op_Func_Description;
259
260/**
261 * @def EO_OP_FUNC(op, func)
262 * A convenience macro to be used when populating the #Eo_Op_Func_Description
263 * array.
264 */
265#define EO_OP_FUNC(op, func) { op, EO_TYPECHECK(eo_op_func_type, func), EO_OP_TYPE_REGULAR }
266
267/**
268 * @def EO_OP_FUNC_CLASS(op, func)
269 * A convenience macro to be used when populating the #Eo_Op_Func_Description
270 * array.
271 * The same as #EO_OP_FUNC but for class functions.
272 *
273 * @see EO_OP_FUNC
274 */
275#define EO_OP_FUNC_CLASS(op, func) { op, (eo_op_func_type) EO_TYPECHECK(eo_op_func_type_class, func), EO_OP_TYPE_CLASS }
276
277/**
278 * @def EO_OP_FUNC_SENTINEL
279 * A convenience macro to be used when populating the #Eo_Op_Func_Description
280 * array. It must appear at the end of the ARRAY.
281 */
282#define EO_OP_FUNC_SENTINEL { 0, NULL, EO_OP_TYPE_INVALID }
283
284/**
285 * @struct _Eo_Op_Description
286 * This struct holds the description of a specific op.
287 */
288struct _Eo_Op_Description
289{
290 Eo_Op sub_op; /**< The sub_id of the op in it's class. */
291 const char *name; /**< The name of the op. */
292 const char *doc; /**< Explanation about the Op. */
293 Eo_Op_Type op_type; /**< The type of the Op. */
294};
295
296/**
297 * @typedef Eo_Op_Description
298 * A convenience typedef for #_Eo_Op_Description
299 */
300typedef struct _Eo_Op_Description Eo_Op_Description;
301
302/**
303 * @def EO_VERSION
304 * The current version of EO.
305 */
306#define EO_VERSION 1
307
308/**
309 * @struct _Eo_Class_Description
310 * This struct holds the description of a class.
311 * This description should be passed to eo_class_new.
312 * Please use the #EO_CLASS_DESCRIPTION_OPS macro when populating it.
313 */
314struct _Eo_Class_Description
315{
316 unsigned int version; /**< The current version of eo, use #EO_VERSION */
317 const char *name; /**< The name of the class. */
318 Eo_Class_Type type; /**< The type of the class. */
319 struct {
320 Eo_Op *base_op_id;
321 const Eo_Op_Description *descs;
322 size_t count;
323 } ops; /**< The ops description, should be filled using #EO_CLASS_DESCRIPTION_OPS */
324 const Eo_Event_Description **events; /**< The event descriptions for this class. */
325 size_t data_size; /**< The size of data (private + protected + public) this class needs per object. */
326 void (*class_constructor)(Eo_Class *klass); /**< The constructor of the class. */
327 void (*class_destructor)(Eo_Class *klass); /**< The destructor of the class. */
328};
329
330/**
331 * @typedef Eo_Class_Description
332 * A convenience typedef for #_Eo_Class_Description
333 */
334typedef struct _Eo_Class_Description Eo_Class_Description;
335
336/**
337 * @def EO_CLASS_DESCRIPTION_OPS(base_op_id, op_descs, count)
338 * An helper macro to help populating #Eo_Class_Description.
339 * @param base_op_id A pointer to the base op id of the class.
340 * @param op_descs the op descriptions array.
341 * @param count the number of ops in the op descriptions array.
342 */
343#define EO_CLASS_DESCRIPTION_OPS(base_op_id, op_descs, count) { base_op_id, op_descs, count }
344
345/**
346 * @def EO_OP_DESCRIPTION(op, doc)
347 * An helper macro to help populating #Eo_Op_Description
348 * @param sub_id The sub id of the op being described.
349 * @param doc Additional doc for the op.
350 * @see Eo_Op_Description
351 * @see EO_OP_DESCRIPTION_CLASS
352 * @see EO_OP_DESCRIPTION_SENTINEL
353 */
354#define EO_OP_DESCRIPTION(sub_id, doc) { sub_id, #sub_id, doc, EO_OP_TYPE_REGULAR }
355
356/**
357 * @def EO_OP_DESCRIPTION_CLASS(op, doc)
358 * An helper macro to help populating #Eo_Op_Description
359 * This macro is the same as EO_OP_DESCRIPTION but indicates that the op's
360 * implementation is of type CLASS.
361 * @param sub_id The sub id of the op being described.
362 * @param doc Additional doc for the op.
363 * @see Eo_Op_Description
364 * @see EO_OP_DESCRIPTION
365 * @see EO_OP_DESCRIPTION_SENTINEL
366 */
367#define EO_OP_DESCRIPTION_CLASS(sub_id, doc) { sub_id, #sub_id, doc, EO_OP_TYPE_CLASS }
368
369/**
370 * @def EO_OP_DESCRIPTION_SENTINEL
371 * An helper macro to help populating #Eo_Op_Description
372 * Should be placed at the end of the array.
373 * @see Eo_Op_Description
374 * @see EO_OP_DESCRIPTION
375 */
376#define EO_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, EO_OP_TYPE_INVALID }
377
378/**
379 * @brief Create a new class.
380 * @param desc the class description to create the class with.
381 * @param parent the class to inherit from.
382 * @param ... A NULL terminated list of extensions (interfaces, mixins and the classes of any composite objects).
383 * @return The new class's handle on success, or NULL otherwise.
384 *
385 * You should use #EO_DEFINE_CLASS. It'll provide thread safety and other
386 * features easily.
387 *
388 * @see #EO_DEFINE_CLASS
389 */
390EAPI const Eo_Class *eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent, ...);
391
392/**
393 * @brief Check if an object "is a" klass.
394 * @param obj The object to check
395 * @param klass The klass to check against.
396 * @return @c EINA_TRUE if obj implements klass, @c EINA_FALSE otherwise.
397 *
398 * Notice: This function does not support composite objects.
399 */
400EAPI Eina_Bool eo_isa(const Eo *obj, const Eo_Class *klass);
401
402/**
403 * @brief Sets the OP functions for a class.
404 * @param klass the class to set the functions to.
405 * @param func_descs a NULL terminated array of #Eo_Op_Func_Description
406 *
407 * Should be called from within the class constructor.
408 */
409EAPI void eo_class_funcs_set(Eo_Class *klass, const Eo_Op_Func_Description *func_descs);
410
411/**
412 * @brief Gets the name of the passed class.
413 * @param klass the class to work on.
414 * @return The class's name.
415 *
416 * @see eo_class_get()
417 */
418EAPI const char *eo_class_name_get(const Eo_Class *klass);
419
420/**
421 * @}
422 */
423
424/**
425 * @brief Init the eo subsystem
426 * @return @c EINA_TRUE on success.
427 *
428 * @see eo_shutfown()
429 */
430EAPI Eina_Bool eo_init(void);
431
432/**
433 * @brief Shutdown the eo subsystem
434 * @return @c EINA_TRUE on success.
435 *
436 * @see eo_init()
437 */
438EAPI Eina_Bool eo_shutdown(void);
439
440/**
441 * @def eo_do
442 * A convenience wrapper around eo_do_internal()
443 * @see eo_do_internal
444 */
445#define eo_do(obj, ...) eo_do_internal(obj, EO_OP_TYPE_REGULAR, __VA_ARGS__, EO_NOOP)
446
447/**
448 * @def eo_class_do
449 * A convenience wrapper around eo_class_do_internal()
450 * @see eo_class_do_internal
451 */
452#define eo_class_do(klass, ...) eo_class_do_internal(klass, __VA_ARGS__, EO_NOOP)
453
454/**
455 * @brief Calls op functions of an object
456 * @param obj The object to work on
457 * @param op_type The type of the ops that are passed.
458 * @param ... NULL terminated list of OPs and parameters.
459 * @return @c EINA_TRUE on success.
460 *
461 * Use the helper macros, don't pass the parameters manually.
462 * Use #eo_do instead of this function.
463 *
464 * @see #eo_do
465 */
466EAPI Eina_Bool eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...);
467
468/**
469 * @brief Calls op functions of a class.
470 * @param klass The class to work on
471 * @param ... NULL terminated list of OPs and parameters.
472 * @return @c EINA_TRUE on success.
473 *
474 * Use the helper macros, don't pass the parameters manually.
475 * Use #eo_do instead of this function.
476 *
477 * @see #eo_class_do
478 */
479EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
480
481/**
482 * @brief Calls the super function for the specific op.
483 * @param obj The object to work on
484 * @param ... list of parameters.
485 * @return @c EINA_TRUE on success.
486 *
487 * Unlike eo_do(), this function only accepts one op.
488 *
489 * @see #eo_do
490 */
491#define eo_do_super(obj, ...) eo_do_super_internal(obj, EO_OP_TYPE_REGULAR, __VA_ARGS__)
492
493/**
494 * @brief Calls the super function for the specific op.
495 * @param klass The klass to work on
496 * @param ... list of parameters.
497 * @return @c EINA_TRUE on success.
498 *
499 * Unlike eo_class_do(), this function only accepts one op.
500 *
501 * @see #eo_class_do
502 */
503#define eo_class_do_super(klass, ...) eo_class_do_super_internal(klass, __VA_ARGS__)
504
505/**
506 * @brief Calls the super function for the specific op.
507 * @param obj The object to work on
508 * @param op_type The type of the ops that are passed.
509 * @param op The wanted op.
510 * @param ... list of parameters.
511 * @return @c EINA_TRUE on success.
512 *
513 * Don't use this function, use the wrapping macros instead.
514 *
515 * @see #eo_do
516 * @see #eo_do_super
517 */
518EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...);
519
520/**
521 * @brief Calls the super function for the specific op.
522 * @param klass The klass to work on
523 * @param op The wanted op.
524 * @param ... list of parameters.
525 * @return @c EINA_TRUE on success.
526 *
527 * Don't use this function, use the wrapping macros instead.
528 *
529 * @see #eo_class_do
530 * @see #eo_class_do_super
531 */
532EAPI Eina_Bool eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...);
533
534/**
535 * @brief Gets the class of the object.
536 * @param obj The object to work on
537 * @return The object's class.
538 *
539 * @see eo_class_name_get()
540 */
541EAPI const Eo_Class *eo_class_get(const Eo *obj);
542
543/**
544 * @def eo_error_set
545 * @brief Notify eo that there was an error when constructing, destructing or calling a function of the object.
546 * @param obj the object to work on.
547 *
548 * @see eo_error_get()
549 */
550#define eo_error_set(obj) eo_error_set_internal(obj, __FILE__, __LINE__)
551
552/* @cond 0 */
553EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line);
554/* @endcond */
555
556/**
557 * @def eo_add
558 * @brief Create a new object with the default constructor.
559 * @param klass the class of the object to create.
560 * @param parent the parent to set to the object.
561 * @param ... The ops to run.
562 * @return An handle to the new object on success, NULL otherwise.
563 *
564 * @see #eo_add_custom
565 */
566#define eo_add(klass, parent, ...) \
567 ({ \
568 const Eo_Class *_tmp_klass = klass; \
569 eo_add_internal(_tmp_klass, parent, eo_constructor(), ## __VA_ARGS__, EO_NOOP); \
570 })
571
572/**
573 * @def eo_add_custom
574 * @brief Create a new object with a custom constructor.
575 * @param klass the class of the object to create.
576 * @param parent the parent to set to the object.
577 * @param ... The ops to run. With the constructor being first.
578 * @return An handle to the new object on success, NULL otherwise.
579 *
580 * @see #eo_add
581 */
582#define eo_add_custom(klass, parent, ...) \
583 ({ \
584 const Eo_Class *_tmp_klass = klass; \
585 eo_add_internal(_tmp_klass, parent, ## __VA_ARGS__, EO_NOOP); \
586 })
587
588/**
589 * @brief Create a new object.
590 * @param klass the class of the object to create.
591 * @param parent the parent to set to the object.
592 * @param ... The ops to run. With the constructor being first.
593 * @return An handle to the new object on success, NULL otherwise.
594 *
595 * Use the helper macros, don't pass the parameters manually.
596 * Use #eo_add or #eo_add_custom instead of this function.
597 *
598 * @see #eo_add
599 */
600EAPI Eo *eo_add_internal(const Eo_Class *klass, Eo *parent, ...);
601
602/**
603 * @brief Get the parent of an object
604 * @param obj the object to get the parent of.
605 * @return a pointer to the parent object.
606 *
607 * @see eo_parent_set()
608 */
609EAPI Eo *eo_parent_get(const Eo *obj);
610
611/**
612 * @brief Set the parent of an object
613 * @param obj the object to get the parent of.
614 * @param parent the new parent.
615 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
616 *
617 * Parents keep references to their children so in order to delete objects
618 * that have parents you need to set parent to NULL or use eo_del() that
619 * does that for you (and also unrefs the object).
620 *
621 * @see eo_del()
622 * @see eo_parent_get()
623 */
624EAPI Eina_Bool eo_parent_set(Eo *obj, const Eo *parent);
625
626/**
627 * @brief Get a pointer to the data of an object for a specific class.
628 * @param obj the object to work on.
629 * @param klass the klass associated with the data.
630 * @return a pointer to the data.
631 */
632EAPI void *eo_data_get(const Eo *obj, const Eo_Class *klass);
633
634/**
635 * @brief Increment the object's reference count by 1.
636 * @param obj the object to work on.
637 * @return The object passed.
638 *
639 * It's very easy to get a refcount leak and start leaking memory because
640 * of a forgotten unref or an extra ref. That is why there are eo_xref
641 * and eo_xunref that will make debugging easier in such a case.
642 * Therefor, these functions should only be used in small scopes, i.e at the
643 * start of some section in which the object may get freed, or if you know
644 * what you are doing.
645 *
646 * @see eo_unref()
647 * @see eo_ref_get()
648 */
649EAPI Eo *eo_ref(const Eo *obj);
650
651/**
652 * @brief Decrement the object's reference count by 1 and free it if needed.
653 * @param obj the object to work on.
654 *
655 * @see eo_ref()
656 * @see eo_ref_get()
657 */
658EAPI void eo_unref(const Eo *obj);
659
660/**
661 * @brief Return the ref count of the object passed.
662 * @param obj the object to work on.
663 * @return the ref count of the object.
664 *
665 * @see eo_ref()
666 * @see eo_unref()
667 */
668EAPI int eo_ref_get(const Eo *obj);
669
670/**
671 * @brief Unrefs the object and reparents it to NULL.
672 * @param obj the object to work on.
673 *
674 * Because eo_del() unrefs and reparents to NULL, it doesn't really delete the
675 * object.
676 *
677 * @see eo_unref()
678 * @see eo_parent_set()
679 */
680EAPI void eo_del(const Eo *obj);
681
682/**
683 * @def eo_xref(obj, ref_obj)
684 * Convenience macro around eo_xref_internal()
685 * @see eo_xref()
686 */
687#define eo_xref(obj, ref_obj) eo_xref_internal(obj, ref_obj, __FILE__, __LINE__)
688
689/**
690 * @brief Increment the object's reference count by 1 (and associate the ref with ref_obj)
691 * @param obj the object to work on.
692 * @param ref_obj the object that references obj.
693 * @param file the call's filename.
694 * @param line the call's line number.
695 * @return The object passed (obj)
696 *
697 * People should not use this function, use #eo_xref instead.
698 * A compile flag my make it and eobj_xunref() behave the same as eobj_ref()
699 * and eobj_unref() respectively. So this should be used wherever possible.
700 *
701 * @see eo_xunref()
702 */
703EAPI Eo *eo_xref_internal(Eo *obj, const Eo *ref_obj, const char *file, int line);
704
705/**
706 * @brief Decrement the object's reference count by 1 and free it if needed. Will free the ref associated with ref_obj).
707 * @param obj the object to work on.
708 * @param ref_obj the object that references obj.
709 *
710 * This function only enforces the checks for object association. I.e don't rely
711 * on it. If such enforces are compiled out, this function behaves the same as
712 * eo_unref().
713 *
714 * @see eo_xref_internal()
715 */
716EAPI void eo_xunref(Eo *obj, const Eo *ref_obj);
717
718/**
719 * @brief Enable or disable the manual free feature.
720 * @param obj the object to work on.
721 * @param manual_free indicates if the free is manual (EINA_TRUE) or automatic (EINA_FALSE).
722 *
723 * The developer is in charge to call the function eo_manual_free to free the memory allocated for this object.
724 *
725 * Do not use, unless you really know what you are doing. It's used by Evas
726 * because evas wants to keep its private data available even after the object
727 * is deleted. Setting this to true makes Eo destruct the object but not free
728 * the private data or the object itself.
729 *
730 * @see eo_manual_free()
731 */
732EAPI void eo_manual_free_set(Eo *obj, Eina_Bool manual_free);
733
734/**
735 * @brief Frees the object.
736 * @param obj the object to work on.
737 * This function must be called by the developer if the function
738 * eo_manual_free_set has been called before with the parameter EINA_TRUE.
739 * An error will be printed if this function is called when the manual
740 * free option is not set to EINA_TRUE or the number of refs is not 0.
741 *
742 * @see eo_manual_free_set()
743 */
744EAPI void eo_manual_free(Eo *obj);
745
746/**
747 * @brief Checks if the object was already descructed (only relevant for manual_free objects).
748 * @param obj the object to check.
749 * This function checks if the object was already destructed (but not alraedy
750 * freed). It should only be used with objects that are supposed to be manually
751 * freed, but not yet freed (but possibly destructed).
752 *
753 * @see eo_manual_free_set()
754 */
755EAPI Eina_Bool eo_destructed_is(const Eo *obj);
756
757/**
758 * @addtogroup Eo_Composite_Objects Composite Objects.
759 * @{
760 */
761
762/**
763 * @brief Make an object a composite object of another.
764 * @param comp_obj the object that will be used to composite parent.
765 * @param parent the "parent" object.
766 *
767 * This functions also sets the parent of comp_obj to parent.
768 *
769 * @see eo_composite_detach()
770 * @see eo_composite_is()
771 */
772EAPI void eo_composite_attach(Eo *comp_obj, Eo *parent);
773
774/**
775 * @brief Detach a composite object from another object.
776 * @param comp_obj the object attached to parent.
777 * @param parent the "parent" object.
778 *
779 * This functions also sets the parent of comp_obj to @c NULL.
780 *
781 * @see eo_composite_attach()
782 * @see eo_composite_is()
783 */
784EAPI void eo_composite_detach(Eo *comp_obj, Eo *parent);
785
786/**
787 * @brief Check if an object is a composite object.
788 * @param comp_obj the object to be checked.
789 * @return @c EINA_TRUE if it is, @c EINA_FALSE otherwise.
790 *
791 * @see eo_composite_attach()
792 * @see eo_composite_detach()
793 */
794EAPI Eina_Bool eo_composite_is(const Eo *comp_obj);
795
796/**
797 * @}
798 */
799
800/**
801 * @addtogroup Eo_Class_Base Eo's Base class.
802 * @{
803 */
804
805/**
806 * @def EO_BASE_CLASS
807 * The class type for the Eo base class.
808 */
809#define EO_BASE_CLASS eo_base_class_get()
810/**
811 * @brief Use #EO_BASE_CLASS
812 * @internal
813 * */
814EAPI const Eo_Class *eo_base_class_get(void);
815
816/**
817 * @typedef eo_base_data_free_func
818 * Data free func prototype.
819 */
820typedef void (*eo_base_data_free_func)(void *);
821
822/**
823 * @var EO_BASE_BASE_ID
824 * #EO_BASE_CLASS 's base id.
825 */
826extern EAPI Eo_Op EO_BASE_BASE_ID;
827
828enum {
829 EO_BASE_SUB_ID_CONSTRUCTOR,
830 EO_BASE_SUB_ID_DESTRUCTOR,
831 EO_BASE_SUB_ID_DATA_SET,
832 EO_BASE_SUB_ID_DATA_GET,
833 EO_BASE_SUB_ID_DATA_DEL,
834 EO_BASE_SUB_ID_WREF_ADD,
835 EO_BASE_SUB_ID_WREF_DEL,
836 EO_BASE_SUB_ID_EVENT_CALLBACK_PRIORITY_ADD,
837 EO_BASE_SUB_ID_EVENT_CALLBACK_DEL,
838 EO_BASE_SUB_ID_EVENT_CALLBACK_CALL,
839 EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD,
840 EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL,
841 EO_BASE_SUB_ID_EVENT_FREEZE,
842 EO_BASE_SUB_ID_EVENT_THAW,
843 EO_BASE_SUB_ID_EVENT_FREEZE_GET,
844 EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE,
845 EO_BASE_SUB_ID_EVENT_GLOBAL_THAW,
846 EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET,
847 EO_BASE_SUB_ID_LAST
848};
849
850/**
851 * @def EO_BASE_ID(sub_id)
852 * Helper macro to get the full Op ID out of the sub_id for EO_BASE.
853 * @param sub_id the sub id inside EO_BASE.
854 */
855#define EO_BASE_ID(sub_id) (EO_BASE_BASE_ID + (sub_id))
856
857/**
858 * @def eo_base_data_set(key, data, free_func)
859 * Set generic data to object.
860 * @param[in] key the key associated with the data
861 * @param[in] data the data to set.
862 * @param[in] free_func the func to free data with (NULL means "do nothing").
863 *
864 * @see #eo_base_data_get
865 * @see #eo_base_data_del
866 */
867#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)
868
869/**
870 * @def eo_base_data_get(key, data)
871 * Get generic data from object.
872 * @param[in] key the key associated with the data
873 * @param[out] data the data for the key
874 *
875 * @see #eo_base_data_set
876 * @see #eo_base_data_del
877 */
878#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)
879
880/**
881 * @def eo_base_data_del(key)
882 * Del generic data from object.
883 * @param[in] key the key associated with the data
884 *
885 * @see #eo_base_data_set
886 * @see #eo_base_data_get
887 */
888#define eo_base_data_del(key) EO_BASE_ID(EO_BASE_SUB_ID_DATA_DEL), EO_TYPECHECK(const char *, key)
889
890/**
891 * @def eo_wref_add
892 * @brief Add a new weak reference to obj.
893 * @param wref The pointer to use for the weak ref.
894 *
895 * This function registers the object handle pointed by wref to obj so when
896 * obj is deleted it'll be updated to NULL. This functions should be used
897 * when you want to keep track of an object in a safe way, but you don't want
898 * to prevent it from being freed.
899 *
900 * @see #eo_wref_del
901 */
902#define eo_wref_add(wref) EO_BASE_ID(EO_BASE_SUB_ID_WREF_ADD), EO_TYPECHECK(Eo **, wref)
903
904/**
905 * @def eo_wref_del
906 * @brief Delete the weak reference passed.
907 * @param wref the weak reference to free.
908 *
909 * @see #eo_wref_add
910 */
911#define eo_wref_del(wref) EO_BASE_ID(EO_BASE_SUB_ID_WREF_DEL), EO_TYPECHECK(Eo **, wref)
912
913/**
914 * @def eo_wref_del_safe
915 * @brief Delete the weak reference passed.
916 * @param wref the weak reference to free.
917 *
918 * Same as eo_wref_del(), with the different that it's not called from eobj_do()
919 * so you don't need to check if *wref is not NULL.
920 *
921 * @see #eo_wref_del
922 */
923#define eo_wref_del_safe(wref) \
924 do { \
925 if (*wref) eo_do(*wref, eo_wref_del(wref)); \
926 } while (0)
927
928/**
929 * @def eo_constructor
930 * @brief Call the object's constructor.
931 *
932 * Should not be used with #eo_do. Only use it with #eo_do_super.
933 *
934 * @see #eo_destructor
935 */
936#define eo_constructor() EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR)
937
938/**
939 * @def eo_destructor
940 * @brief Call the object's destructor.
941 *
942 * Should not be used with #eo_do. Only use it with #eo_do_super.
943 *
944 * @see #eo_constructor
945 */
946#define eo_destructor() EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR)
947
948/**
949 * @addtogroup Eo_Events Eo's Event Handling
950 * @{
951 */
952
953/**
954 * @def EO_CALLBACK_PRIORITY_BEFORE
955 * Slightly more prioritized than default.
956 */
957#define EO_CALLBACK_PRIORITY_BEFORE -100
958/**
959 * @def EO_CALLBACK_PRIORITY_DEFAULT
960 * Default callback priority level
961 */
962#define EO_CALLBACK_PRIORITY_DEFAULT 0
963/**
964 * @def EO_CALLBACK_PRIORITY_AFTER
965 * Slightly less prioritized than default.
966 */
967#define EO_CALLBACK_PRIORITY_AFTER 100
968
969/**
970 * @typedef Eo_Callback_Priority
971 *
972 * Callback priority value. Range is -32k - 32k. The lower the number, the
973 * higher the priority.
974 *
975 * @see EO_CALLBACK_PRIORITY_AFTER
976 * @see EO_CALLBACK_PRIORITY_BEFORE
977 * @see EO_CALLBACK_PRIORITY_DEFAULT
978 */
979typedef short Eo_Callback_Priority;
980
981/**
982 * @def EO_CALLBACK_STOP
983 * Stop calling callbacks for the even of which the callback was called for.
984 * @see EO_CALLBACK_CONTINUE
985 */
986#define EO_CALLBACK_STOP EINA_FALSE
987
988/**
989 * @def EO_CALLBACK_CONTINUE
990 * Continue calling callbacks for the even of which the callback was called for.
991 * @see EO_CALLBACK_STOP
992 */
993#define EO_CALLBACK_CONTINUE EINA_TRUE
994
995/**
996 * @typedef Eo_Event_Cb
997 *
998 * An event callback prototype.
999 *
1000 * @param data The user data registered with the callback.
1001 * @param obj The object which initiated the event.
1002 * @param desc The event's description.
1003 * @param event_info additional data passed with the event.
1004 * @return #EO_CALLBACK_STOP to stop calling additional callbacks for the event, #EO_CALLBACK_CONTINUE to continue.
1005 */
1006typedef Eina_Bool (*Eo_Event_Cb)(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
1007
1008/**
1009 * @def eo_event_callback_forwarder_add
1010 * @brief Add an event callback forwarder for an event and an object.
1011 * @param[in] desc The description of the event to listen to.
1012 * @param[in] new_obj The object to emit events from.
1013 *
1014 * @see eo_event_callback_forwarder_del()
1015 */
1016#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)
1017
1018/**
1019 * @def eo_event_callback_forwarder_del
1020 * @brief Remove an event callback forwarder for an event and an object.
1021 * @param[in] desc The description of the event to listen to.
1022 * @param[in] new_obj The object to emit events from.
1023 *
1024 * @see eo_event_callback_forwarder_add()
1025 */
1026#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)
1027
1028/**
1029 * @def eo_event_freeze
1030 * @brief freeze events of object.
1031 *
1032 * Prevents event callbacks from being called for the object.
1033 *
1034 * @see #eo_event_thaw
1035 */
1036#define eo_event_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE)
1037
1038/**
1039 * @def eo_event_thaw
1040 * @brief thaw events of object.
1041 *
1042 * Lets event callbacks be called for the object.
1043 *
1044 * @see #eo_event_freeze
1045 */
1046#define eo_event_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW)
1047
1048/**
1049 * @def eo_event_freeze_get
1050 * @brief return freeze events of object.
1051 *
1052 * @param[out] fcount The event freeze count of the object.
1053 *
1054 * Return event freeze count.
1055 *
1056 * @see #eo_event_freeze
1057 * @see #eo_event_thaw
1058 */
1059#define eo_event_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), EO_TYPECHECK(int *, fcount)
1060
1061/**
1062 * @def eo_event_global_freeze
1063 * @brief freeze events of object.
1064 *
1065 * Prevents event callbacks from being called for the object.
1066 *
1067 * @see #eo_event_freeze
1068 * @see #eo_event_global_thaw
1069 */
1070#define eo_event_global_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE)
1071
1072/**
1073 * @def eo_event_global_thaw
1074 * @brief thaw events of object.
1075 *
1076 * Lets event callbacks be called for the object.
1077 *
1078 * @see #eo_event_thaw
1079 * @see #eo_event_global_freeze
1080 */
1081#define eo_event_global_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW)
1082
1083/**
1084 * @def eo_event_global_freeze_get
1085 * @brief return freeze events of object.
1086 *
1087 * @param[out] fcount The event freeze count of the object.
1088 *
1089 * Return event freeze count.
1090 *
1091 * @see #eo_event_freeze_get
1092 * @see #eo_event_global_freeze
1093 * @see #eo_event_global_thaw
1094 */
1095#define eo_event_global_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET), EO_TYPECHECK(int *, fcount)
1096
1097/**
1098 * @def eo_event_callback_add(obj, desc, cb, data)
1099 * Add a callback for an event.
1100 * @param[in] desc The description of the event to listen to.
1101 * @param[in] cb the callback to call.
1102 * @param[in] data additional data to pass to the callback.
1103 *
1104 * callbacks of the same priority are called in reverse order of creation.
1105 *
1106 * @see eo_event_callback_priority_add()
1107 */
1108#define eo_event_callback_add(desc, cb, data) \
1109 eo_event_callback_priority_add(desc, \
1110 EO_CALLBACK_PRIORITY_DEFAULT, cb, data)
1111
1112/**
1113 * @def eo_event_callback_priority_add
1114 * @brief Add a callback for an event with a specific priority.
1115 * @param[in] desc The description of the event to listen to.
1116 * @param[in] priority The priority of the callback.
1117 * @param[in] cb the callback to call.
1118 * @param[in] data additional data to pass to the callback.
1119 *
1120 * callbacks of the same priority are called in reverse order of creation.
1121 *
1122 * @see #eo_event_callback_add
1123 */
1124#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)
1125
1126
1127/**
1128 * @def eo_event_callback_del
1129 * @brief Del a callback with a specific data associated to it for an event.
1130 * @param[in] desc The description of the event to listen to.
1131 * @param[in] func the callback to delete.
1132 * @param[in] user_data The data to compare.
1133 *
1134 */
1135#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)
1136
1137/**
1138 * @def eo_event_callback_call
1139 * @brief Call the callbacks for an event of an object.
1140 * @param[in] desc The description of the event to call.
1141 * @param[in] event_info Extra event info to pass to the callbacks.
1142 * @param[out] aborted @c EINA_TRUE if one of the callbacks aborted the call, @c EINA_FALSE otherwise.
1143 */
1144#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)
1145
1146/**
1147 * @}
1148 */
1149
1150/**
1151 * @var _EO_EV_CALLBACK_ADD
1152 * see EO_EV_CALLBACK_ADD
1153 */
1154EAPI extern const Eo_Event_Description _EO_EV_CALLBACK_ADD;
1155
1156/**
1157 * @def EO_EV_CALLBACK_ADD
1158 * The event description (of type #Eo_Event_Description) for
1159 * The "Callback listener added" event.
1160 */
1161#define EO_EV_CALLBACK_ADD (&(_EO_EV_CALLBACK_ADD))
1162
1163/**
1164 * @var _EO_EV_CALLBACK_DEL
1165 * see EO_EV_CALLBACK_DEL
1166 */
1167EAPI extern const Eo_Event_Description _EO_EV_CALLBACK_DEL;
1168
1169/**
1170 * @def EO_EV_CALLBACK_DEL
1171 * The event description (of type #Eo_Event_Description) for
1172 * The "Callback listener deleted" event.
1173 */
1174#define EO_EV_CALLBACK_DEL (&(_EO_EV_CALLBACK_DEL))
1175
1176/**
1177 * @var _EO_EV_DEL
1178 * see #EO_EV_DEL
1179 */
1180EAPI extern const Eo_Event_Description _EO_EV_DEL;
1181
1182/**
1183 * @def EO_EV_DEL
1184 * Object is being deleted.
1185 */
1186#define EO_EV_DEL (&(_EO_EV_DEL))
1187
1188/**
1189 * @}
1190 */
1191
1192/**
1193 * @}
1194 */
1195
1196#ifdef __cplusplus
1197}
1198#endif
1199
1200#endif
diff --git a/src/lib/eo/Makefile.am b/src/lib/eo/Makefile.am
new file mode 100644
index 0000000000..0580bc0482
--- /dev/null
+++ b/src/lib/eo/Makefile.am
@@ -0,0 +1,21 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/include/eina \
5-I$(top_srcdir)/src/lib/eo \
6-I$(top_builddir)/src/include/eina \
7-I$(top_builddir)/src/lib/eo \
8@EFL_EO_BUILD@ \
9@EO_CFLAGS@
10
11installed_headerdir = $(includedir)/eo-@VMAJ@
12dist_installed_header_DATA = Eo.h
13
14lib_LTLIBRARIES = libeo.la
15
16libeo_la_SOURCES = eo.c eo_base_class.c eo_private.h
17libeo_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EO_LIBS@
18libeo_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
19
20clean-local:
21 rm -rf *.gcno
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
new file mode 100644
index 0000000000..b2d8b82886
--- /dev/null
+++ b/src/lib/eo/eo.c
@@ -0,0 +1,1582 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eina.h>
6
7#include "Eo.h"
8#include "eo_private.h"
9
10/* The last id that should be reserved for statically allocated classes. */
11#define EO_CLASS_IDS_FIRST 1
12#define EO_OP_IDS_FIRST 1
13
14/* Used inside the class_get functions of classes, see #EO_DEFINE_CLASS */
15EAPI Eina_Lock _eo_class_creation_lock;
16int _eo_log_dom = -1;
17
18static Eo_Class **_eo_classes;
19static Eo_Class_Id _eo_classes_last_id;
20static Eina_Bool _eo_init_count = 0;
21static Eo_Op _eo_ops_last_id = 0;
22
23static void _eo_condtor_reset(Eo *obj);
24static inline void *_eo_data_get(const Eo *obj, const Eo_Class *klass);
25static inline Eo *_eo_ref(Eo *obj);
26static inline void _eo_unref(Eo *obj);
27static const Eo_Class *_eo_op_class_get(Eo_Op op);
28static const Eo_Op_Description *_eo_op_id_desc_get(Eo_Op op);
29
30typedef struct
31{
32 const Eo_Class *kls;
33} Eo_Kls_Itr;
34
35struct _Eo {
36 EINA_MAGIC
37 EINA_INLIST;
38 Eo *parent;
39 Eina_Inlist *children;
40 const Eo_Class *klass;
41 int refcount;
42#ifndef NDEBUG
43 Eina_Inlist *xrefs;
44#endif
45
46 Eina_List *composite_objects;
47
48 Eo_Kls_Itr mro_itr;
49
50 Eina_Bool do_error:1;
51 Eina_Bool condtor_done:1;
52
53 Eina_Bool composite:1;
54 Eina_Bool del:1;
55 Eina_Bool manual_free:1;
56};
57
58/* Start of Dich */
59
60/* How we search and store the implementations in classes. */
61#define DICH_CHAIN_LAST_BITS 5
62#define DICH_CHAIN_LAST_SIZE (1 << DICH_CHAIN_LAST_BITS)
63#define DICH_CHAIN1(x) ((x) / DICH_CHAIN_LAST_SIZE)
64#define DICH_CHAIN_LAST(x) ((x) % DICH_CHAIN_LAST_SIZE)
65
66#define OP_CLASS_OFFSET_GET(x) (((x) >> EO_OP_CLASS_OFFSET) & 0xffff)
67
68#define ID_CLASS_GET(id) ({ \
69 (Eo_Class *) ((id <= _eo_classes_last_id) && (id > 0)) ? \
70 (_eo_classes[id - 1]) : NULL; \
71 })
72
73#define EO_ALIGN_SIZE(size) \
74 ((size) + (sizeof(void *) - ((size) % sizeof(void *))))
75
76typedef struct _Dich_Chain1 Dich_Chain1;
77
78typedef struct
79{
80 eo_op_func_type func;
81 const Eo_Class *src;
82} op_type_funcs;
83
84struct _Dich_Chain1
85{
86 op_type_funcs *funcs;
87};
88
89typedef struct
90{
91 const Eo_Class *klass;
92 size_t offset;
93} Eo_Extension_Data_Offset;
94
95struct _Eo_Class
96{
97 EINA_MAGIC
98 Eo_Class_Id class_id;
99 const Eo_Class *parent;
100 const Eo_Class_Description *desc;
101 Dich_Chain1 *chain; /**< The size is chain size */
102 size_t chain_size;
103 size_t base_id;
104
105 const Eo_Class **extensions;
106
107 Eo_Extension_Data_Offset *extn_data_off;
108 size_t extn_data_size;
109
110 const Eo_Class **mro;
111 Eo_Kls_Itr mro_itr;
112
113 size_t data_offset; /* < Offset of the data within object data. */
114
115 Eina_Bool constructed : 1;
116};
117
118static inline void
119_dich_chain_alloc(Dich_Chain1 *chain1)
120{
121 if (!chain1->funcs)
122 {
123 chain1->funcs = calloc(DICH_CHAIN_LAST_SIZE, sizeof(*(chain1->funcs)));
124 }
125}
126
127static inline void
128_dich_copy_all(Eo_Class *dst, const Eo_Class *src)
129{
130 Eo_Op i;
131 const Dich_Chain1 *sc1 = src->chain;
132 Dich_Chain1 *dc1 = dst->chain;
133 for (i = 0 ; i < src->chain_size ; i++, sc1++, dc1++)
134 {
135 if (sc1->funcs)
136 {
137 size_t j;
138
139 _dich_chain_alloc(dc1);
140
141 const op_type_funcs *sf = sc1->funcs;
142 op_type_funcs *df = dc1->funcs;
143 for (j = 0 ; j < DICH_CHAIN_LAST_SIZE ; j++, df++, sf++)
144 {
145 if (sf->func)
146 {
147 memcpy(df, sf, sizeof(*df));
148 }
149 }
150 }
151 }
152}
153
154static inline const op_type_funcs *
155_dich_func_get(const Eo_Class *klass, Eo_Op op)
156{
157 size_t idx1 = DICH_CHAIN1(op);
158 if (EINA_UNLIKELY(idx1 >= klass->chain_size))
159 return NULL;
160 Dich_Chain1 *chain1 = &klass->chain[idx1];
161 if (EINA_UNLIKELY(!chain1->funcs))
162 return NULL;
163 return &chain1->funcs[DICH_CHAIN_LAST(op)];
164}
165
166static inline void
167_dich_func_set(Eo_Class *klass, Eo_Op op, eo_op_func_type func)
168{
169 size_t idx1 = DICH_CHAIN1(op);
170 Dich_Chain1 *chain1 = &klass->chain[idx1];
171 _dich_chain_alloc(chain1);
172 if (chain1->funcs[DICH_CHAIN_LAST(op)].src == klass)
173 {
174 const Eo_Class *op_kls = _eo_op_class_get(op);
175 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
176 ERR("Already set function for op %x (%s:%s). Overriding with func %p",
177 op, op_kls->desc->name, op_desc->name, func);
178 }
179
180 chain1->funcs[DICH_CHAIN_LAST(op)].func = func;
181 chain1->funcs[DICH_CHAIN_LAST(op)].src = klass;
182}
183
184static inline void
185_dich_func_clean_all(Eo_Class *klass)
186{
187 size_t i;
188 Dich_Chain1 *chain1 = klass->chain;
189
190 for (i = 0 ; i < klass->chain_size ; i++, chain1++)
191 {
192 if (chain1->funcs)
193 free(chain1->funcs);
194 }
195 free(klass->chain);
196 klass->chain = NULL;
197}
198
199/* END OF DICH */
200
201static const Eo_Op_Description noop_desc =
202 EO_OP_DESCRIPTION(EO_NOOP, "No operation.");
203
204static const Eo_Class *
205_eo_op_class_get(Eo_Op op)
206{
207 /* FIXME: Make it fast. */
208 Eo_Class **itr = _eo_classes;
209 int mid, max, min;
210
211 min = 0;
212 max = _eo_classes_last_id - 1;
213 while (min <= max)
214 {
215 mid = (min + max) / 2;
216
217 if (itr[mid]->base_id + itr[mid]->desc->ops.count < op)
218 min = mid + 1;
219 else if (itr[mid]->base_id > op)
220 max = mid - 1;
221 else
222 return itr[mid];
223 }
224
225 return NULL;
226}
227
228static const Eo_Op_Description *
229_eo_op_id_desc_get(Eo_Op op)
230{
231 const Eo_Class *klass;
232
233 if (op == EO_NOOP)
234 return &noop_desc;
235
236 klass = _eo_op_class_get(op);
237
238 if (klass)
239 {
240 Eo_Op sub_id = op - klass->base_id;
241 if (sub_id < klass->desc->ops.count)
242 return klass->desc->ops.descs + sub_id;
243 }
244
245 return NULL;
246}
247
248static const char *
249_eo_op_id_name_get(Eo_Op op)
250{
251 const Eo_Op_Description *desc = _eo_op_id_desc_get(op);
252 return (desc) ? desc->name : NULL;
253}
254
255static inline void
256_eo_kls_itr_init(const Eo_Class *obj_klass, Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_state)
257{
258 memcpy(prev_state, cur, sizeof(*cur));
259 cur->kls = *obj_klass->mro;
260}
261
262static inline void
263_eo_kls_itr_end(Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_state)
264{
265 memcpy(cur, prev_state, sizeof(*cur));
266}
267
268static inline const Eo_Class *
269_eo_kls_itr_get(Eo_Kls_Itr *cur)
270{
271 return cur->kls;
272}
273
274static inline void
275_eo_kls_itr_set(Eo_Kls_Itr *cur, const Eo_Class *kls)
276{
277 cur->kls = kls;
278}
279
280static inline const Eo_Class *
281_eo_kls_itr_next(const Eo_Class *orig_kls, Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_state, Eo_Op op)
282{
283 const Eo_Class **kls_itr = NULL;
284 memcpy(prev_state, cur, sizeof(*cur));
285
286 /* Find the kls itr. */
287 kls_itr = orig_kls->mro;
288 while (*kls_itr && (*kls_itr != cur->kls))
289 kls_itr++;
290
291 if (*kls_itr)
292 {
293 kls_itr++;
294 while (*kls_itr)
295 {
296 const op_type_funcs *fsrc = _dich_func_get(*kls_itr, op);
297 if (!fsrc || !fsrc->func)
298 {
299 kls_itr++;
300 continue;
301 }
302 cur->kls = fsrc->src;
303 return cur->kls;
304 }
305 }
306
307 cur->kls = NULL;
308 return NULL;
309}
310
311static inline const op_type_funcs *
312_eo_kls_itr_func_get(Eo_Kls_Itr *mro_itr, Eo_Op op)
313{
314 const Eo_Class *klass = _eo_kls_itr_get(mro_itr);
315 if (klass)
316 {
317 const op_type_funcs *func = _dich_func_get(klass, op);
318
319 if (func && func->func)
320 {
321 _eo_kls_itr_set(mro_itr, func->src);
322 return func;
323 }
324 }
325
326 _eo_kls_itr_set(mro_itr, NULL);
327 return NULL;
328}
329
330#define _EO_OP_ERR_NO_OP_PRINT(op, klass) \
331 do \
332 { \
333 const Eo_Class *op_klass = _eo_op_class_get(op); \
334 const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; \
335 ERR("Can't find func for op %x (%s:%s) for class '%s'. Aborting.", \
336 op, _dom_name, _eo_op_id_name_get(op), \
337 (klass) ? klass->desc->name : NULL); \
338 } \
339 while (0)
340
341static Eina_Bool
342_eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
343{
344#ifndef NDEBUG
345 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
346
347 if (op_desc)
348 {
349 if (op_desc->op_type == EO_OP_TYPE_CLASS)
350 {
351 ERR("Tried calling a class op '%s' (%x) from a non-class context.", (op_desc) ? op_desc->name : NULL, op);
352 return EINA_FALSE;
353 }
354 }
355#endif
356
357 {
358 const op_type_funcs *func =
359 _eo_kls_itr_func_get(&obj->mro_itr, op);
360 if (EINA_LIKELY(func != NULL))
361 {
362 void *func_data =_eo_data_get(obj, func->src);
363 func->func(obj, func_data, p_list);
364 return EINA_TRUE;
365 }
366 }
367
368 /* Try composite objects */
369 {
370 Eina_List *itr;
371 Eo *emb_obj;
372 EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
373 {
374 /* FIXME: Clean this up a bit. */
375 Eo_Kls_Itr prev_state;
376 _eo_kls_itr_init(emb_obj->klass, &emb_obj->mro_itr, &prev_state);
377 if (_eo_op_internal(emb_obj, op_type, op, p_list))
378 {
379 _eo_kls_itr_end(&emb_obj->mro_itr, &prev_state);
380 return EINA_TRUE;
381 }
382 _eo_kls_itr_end(&emb_obj->mro_itr, &prev_state);
383 }
384 }
385 return EINA_FALSE;
386}
387
388static inline Eina_Bool
389_eo_dov_internal(Eo *obj, Eo_Op_Type op_type, va_list p_list)
390{
391 Eina_Bool prev_error;
392 Eina_Bool ret = EINA_TRUE;
393 Eo_Op op = EO_NOOP;
394 Eo_Kls_Itr prev_state;
395
396 prev_error = obj->do_error;
397 _eo_ref(obj);
398
399 op = va_arg(p_list, Eo_Op);
400 while (op)
401 {
402 _eo_kls_itr_init(obj->klass, &obj->mro_itr, &prev_state);
403 if (!_eo_op_internal(obj, op_type, op, &p_list))
404 {
405 _EO_OP_ERR_NO_OP_PRINT(op, obj->klass);
406 ret = EINA_FALSE;
407 _eo_kls_itr_end(&obj->mro_itr, &prev_state);
408 break;
409 }
410 op = va_arg(p_list, Eo_Op);
411 _eo_kls_itr_end(&obj->mro_itr, &prev_state);
412 }
413
414 _eo_unref(obj);
415
416 if (obj->do_error)
417 ret = EINA_FALSE;
418
419 obj->do_error = prev_error;
420
421 return ret;
422}
423
424EAPI Eina_Bool
425eo_do_internal(Eo *obj, Eo_Op_Type op_type, ...)
426{
427 Eina_Bool ret = EINA_TRUE;
428 va_list p_list;
429
430 EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
431
432 va_start(p_list, op_type);
433
434 ret = _eo_dov_internal(obj, op_type, p_list);
435
436 va_end(p_list);
437
438 return ret;
439}
440
441EAPI Eina_Bool
442eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
443{
444 const Eo_Class *nklass;
445 Eina_Bool ret = EINA_TRUE;
446 va_list p_list;
447 Eo_Kls_Itr prev_state;
448 EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
449
450 /* Advance the kls itr. */
451 nklass = _eo_kls_itr_next(obj->klass, &obj->mro_itr, &prev_state, op);
452
453 va_start(p_list, op);
454 if (!_eo_op_internal(obj, op_type, op, &p_list))
455 {
456 _EO_OP_ERR_NO_OP_PRINT(op, nklass);
457 ret = EINA_FALSE;
458 }
459 va_end(p_list);
460
461 if (obj->do_error)
462 ret = EINA_FALSE;
463
464 _eo_kls_itr_end(&obj->mro_itr, &prev_state);
465 return ret;
466}
467
468static Eina_Bool
469_eo_class_op_internal(Eo_Class *klass, Eo_Op op, va_list *p_list)
470{
471#ifndef NDEBUG
472 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
473
474 if (op_desc)
475 {
476 if (op_desc->op_type != EO_OP_TYPE_CLASS)
477 {
478 ERR("Tried calling an instance op '%s' (%x) from a class context.", (op_desc) ? op_desc->name : NULL, op);
479 return EINA_FALSE;
480 }
481 }
482#endif
483
484 {
485 const op_type_funcs *func =
486 _eo_kls_itr_func_get(&klass->mro_itr, op);
487 if (func)
488 {
489 ((eo_op_func_type_class) func->func)(klass, p_list);
490 return EINA_TRUE;
491 }
492 }
493
494 return EINA_FALSE;
495}
496
497EAPI Eina_Bool
498eo_class_do_internal(const Eo_Class *klass, ...)
499{
500 Eina_Bool ret = EINA_TRUE;
501 Eo_Op op = EO_NOOP;
502 Eo_Kls_Itr prev_state;
503 va_list p_list;
504
505 EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
506
507 va_start(p_list, klass);
508
509 op = va_arg(p_list, Eo_Op);
510 while (op)
511 {
512 _eo_kls_itr_init(klass, &((Eo_Class *) klass)->mro_itr, &prev_state);
513 if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
514 {
515 _EO_OP_ERR_NO_OP_PRINT(op, klass);
516 ret = EINA_FALSE;
517 _eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
518 break;
519 }
520 _eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
521 op = va_arg(p_list, Eo_Op);
522 }
523
524 va_end(p_list);
525
526 return ret;
527}
528
529EAPI Eina_Bool
530eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...)
531{
532 const Eo_Class *nklass;
533 Eina_Bool ret = EINA_TRUE;
534 va_list p_list;
535 Eo_Kls_Itr prev_state;
536 EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
537
538 /* Advance the kls itr. */
539 nklass = _eo_kls_itr_next(klass, &((Eo_Class *) klass)->mro_itr, &prev_state, op);
540
541 va_start(p_list, op);
542 if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
543 {
544 _EO_OP_ERR_NO_OP_PRINT(op, nklass);
545 ret = EINA_FALSE;
546 }
547 va_end(p_list);
548
549 _eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
550 return ret;
551}
552
553EAPI const Eo_Class *
554eo_class_get(const Eo *obj)
555{
556 EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
557
558 return obj->klass;
559}
560
561EAPI const char *
562eo_class_name_get(const Eo_Class *klass)
563{
564 EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, NULL);
565
566 return klass->desc->name;
567}
568
569static void
570_eo_class_base_op_init(Eo_Class *klass)
571{
572 const Eo_Class_Description *desc = klass->desc;
573
574 klass->base_id = _eo_ops_last_id;
575
576 if (desc && desc->ops.base_op_id)
577 *(desc->ops.base_op_id) = klass->base_id;
578
579 _eo_ops_last_id += desc->ops.count + 1;
580
581 klass->chain_size = DICH_CHAIN1(_eo_ops_last_id) + 1;
582 klass->chain = calloc(klass->chain_size, sizeof(*klass->chain));
583}
584
585#ifndef NDEBUG
586static Eina_Bool
587_eo_class_mro_has(const Eo_Class *klass, const Eo_Class *find)
588{
589 const Eo_Class **itr;
590 for (itr = klass->mro ; *itr ; itr++)
591 {
592 if (*itr == find)
593 {
594 return EINA_TRUE;
595 }
596 }
597 return EINA_FALSE;
598}
599#endif
600
601static Eina_List *
602_eo_class_mro_add(Eina_List *mro, const Eo_Class *klass)
603{
604 Eina_List *extn_pos = NULL;
605 Eina_Bool check_consistency = !mro;
606 if (!klass)
607 return mro;
608
609 mro = eina_list_append(mro, klass);
610
611 /* ONLY ADD MIXINS! */
612
613 /* Recursively add extenions. */
614 {
615 const Eo_Class **extn_itr;
616
617 for (extn_itr = klass->extensions ; *extn_itr ; extn_itr++)
618 {
619 const Eo_Class *extn = *extn_itr;
620 if (extn->desc->type != EO_CLASS_TYPE_MIXIN)
621 continue;
622
623 mro = _eo_class_mro_add(mro, extn);
624 /* Not possible: if (!mro) return NULL; */
625
626 if (check_consistency)
627 {
628 extn_pos = eina_list_append(extn_pos, eina_list_last(mro));
629 }
630 }
631 }
632
633 /* Check if we can create a consistent mro. We only do it for the class
634 * we are working on (i.e no parents). */
635 if (check_consistency)
636 {
637 const Eo_Class **extn_itr;
638
639 Eina_List *itr = extn_pos;
640 for (extn_itr = klass->extensions ; *extn_itr ; extn_itr++)
641 {
642 const Eo_Class *extn = *extn_itr;
643 if (extn->desc->type != EO_CLASS_TYPE_MIXIN)
644 continue;
645
646 /* Get the first one after the extension. */
647 Eina_List *extn_list = eina_list_next(eina_list_data_get(itr));
648
649 /* If we found the extension again. */
650 if (eina_list_data_find_list(extn_list, extn))
651 {
652 eina_list_free(mro);
653 ERR("Cannot create a consistent method resolution order for class '%s' because of '%s'.", klass->desc->name, extn->desc->name);
654 return NULL;
655 }
656
657 itr = eina_list_next(itr);
658 }
659 }
660
661
662 mro = _eo_class_mro_add(mro, klass->parent);
663
664 return mro;
665}
666
667static Eina_Bool
668_eo_class_mro_init(Eo_Class *klass)
669{
670 Eina_List *mro = NULL;
671
672 DBG("Started creating MRO for class '%s'", klass->desc->name);
673 mro = _eo_class_mro_add(mro, klass);
674
675 if (!mro)
676 return EINA_FALSE;
677
678 /* Remove duplicates and make them the right order. */
679 {
680 Eina_List *itr1, *itr2, *itr2n;
681
682 itr1 = eina_list_last(mro);
683 while (itr1)
684 {
685 itr2 = eina_list_prev(itr1);
686
687 while (itr2)
688 {
689 itr2n = eina_list_prev(itr2);
690
691 if (eina_list_data_get(itr1) == eina_list_data_get(itr2))
692 {
693 mro = eina_list_remove_list(mro, itr2);
694 }
695
696 itr2 = itr2n;
697 }
698
699 itr1 = eina_list_prev(itr1);
700 }
701 }
702
703 /* Copy the mro and free the list. */
704 {
705 const Eo_Class *kls_itr;
706 const Eo_Class **mro_itr;
707 klass->mro = calloc(sizeof(*klass->mro), eina_list_count(mro) + 1);
708
709 mro_itr = klass->mro;
710
711 EINA_LIST_FREE(mro, kls_itr)
712 {
713 *(mro_itr++) = kls_itr;
714
715 DBG("Added '%s' to MRO", kls_itr->desc->name);
716 }
717 *(mro_itr) = NULL;
718 }
719
720 DBG("Finished creating MRO for class '%s'", klass->desc->name);
721
722 return EINA_TRUE;
723}
724
725static void
726_eo_class_constructor(Eo_Class *klass)
727{
728 if (klass->constructed)
729 return;
730
731 klass->constructed = EINA_TRUE;
732
733 if (klass->desc->class_constructor)
734 klass->desc->class_constructor(klass);
735}
736
737EAPI void
738eo_class_funcs_set(Eo_Class *klass, const Eo_Op_Func_Description *func_descs)
739{
740 EO_MAGIC_RETURN(klass, EO_CLASS_EINA_MAGIC);
741
742 const Eo_Op_Func_Description *itr;
743 itr = func_descs;
744 if (itr)
745 {
746 for ( ; itr->op_type != EO_OP_TYPE_INVALID ; itr++)
747 {
748 const Eo_Op_Description *op_desc = _eo_op_id_desc_get(itr->op);
749
750 if (EINA_UNLIKELY(!op_desc || (itr->op == EO_NOOP)))
751 {
752 ERR("Setting implementation for non-existent op %x for class '%s'. Func index: %d", itr->op, klass->desc->name, itr - func_descs);
753 }
754 else if (EINA_LIKELY(itr->op_type == op_desc->op_type))
755 {
756 _dich_func_set(klass, itr->op, itr->func);
757 }
758 else
759 {
760 ERR("Set function's op type (%x) is different than the one in the op description (%d) for op '%s:%s'. Func index: %d",
761 itr->op_type,
762 (op_desc) ? op_desc->op_type : EO_OP_TYPE_REGULAR,
763 klass->desc->name,
764 (op_desc) ? op_desc->name : NULL,
765 itr - func_descs);
766 }
767 }
768 }
769}
770
771static void
772eo_class_free(Eo_Class *klass)
773{
774 if (klass->constructed)
775 {
776 if (klass->desc->class_destructor)
777 klass->desc->class_destructor(klass);
778
779 _dich_func_clean_all(klass);
780 }
781
782 free(klass->extensions);
783
784 if (klass->mro)
785 free(klass->mro);
786
787 if (klass->extn_data_off)
788 free(klass->extn_data_off);
789
790 free(klass);
791}
792
793/* DEVCHECK */
794static Eina_Bool
795_eo_class_check_op_descs(const Eo_Class *klass)
796{
797 const Eo_Class_Description *desc = klass->desc;
798 const Eo_Op_Description *itr;
799 size_t i;
800
801 if (desc->ops.count > 0)
802 {
803 if (!desc->ops.base_op_id)
804 {
805 ERR("Class '%s' has a non-zero ops count, but base_id is NULL.",
806 desc->name);
807 return EINA_FALSE;
808 }
809
810 if (!desc->ops.descs)
811 {
812 ERR("Class '%s' has a non-zero ops count, but there are no descs.",
813 desc->name);
814 return EINA_FALSE;
815 }
816 }
817
818 itr = desc->ops.descs;
819 for (i = 0 ; i < desc->ops.count ; i++, itr++)
820 {
821 if (itr->sub_op != i)
822 {
823 if (itr->name)
824 {
825 ERR("Wrong order in Ops description for class '%s'. Expected %x and got %x", desc->name, i, itr->sub_op);
826 }
827 else
828 {
829 ERR("Found too few Ops description for class '%s'. Expected %x descriptions, but found %x.", desc->name, desc->ops.count, i);
830 }
831 return EINA_FALSE;
832 }
833 }
834
835 if (itr && itr->name)
836 {
837 ERR("Found extra Ops description for class '%s'. Expected %d descriptions, but found more.", desc->name, desc->ops.count);
838 return EINA_FALSE;
839 }
840
841 return EINA_TRUE;
842}
843
844/* Not really called, just used for the ptr... */
845static void
846_eo_class_isa_func(Eo *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
847{
848 /* Do nonthing. */
849}
850
851EAPI const Eo_Class *
852eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent, ...)
853{
854 Eo_Class *klass;
855 va_list p_list;
856
857 if (parent && !EINA_MAGIC_CHECK(parent, EO_CLASS_EINA_MAGIC))
858 {
859 EINA_MAGIC_FAIL(parent, EO_CLASS_EINA_MAGIC);
860 return NULL;
861 }
862
863 va_start(p_list, parent);
864
865 EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL);
866 EINA_SAFETY_ON_NULL_RETURN_VAL(desc->name, NULL);
867
868 /* Check restrictions on Interface types. */
869 if (desc->type == EO_CLASS_TYPE_INTERFACE)
870 {
871 EINA_SAFETY_ON_FALSE_RETURN_VAL(!desc->data_size, NULL);
872 }
873
874 klass = calloc(1, sizeof(Eo_Class));
875 klass->parent = parent;
876
877 /* Handle class extensions */
878 {
879 Eina_List *extn_list = NULL;
880 const Eo_Class *extn = NULL;
881 const Eo_Class **extn_itr = NULL;
882
883 extn = va_arg(p_list, Eo_Class *);
884 while (extn)
885 {
886 switch (extn->desc->type)
887 {
888 case EO_CLASS_TYPE_REGULAR:
889 case EO_CLASS_TYPE_REGULAR_NO_INSTANT:
890 case EO_CLASS_TYPE_INTERFACE:
891 case EO_CLASS_TYPE_MIXIN:
892 extn_list = eina_list_append(extn_list, extn);
893 break;
894 }
895
896 extn = va_arg(p_list, Eo_Class *);
897 }
898
899 klass->extensions = calloc(sizeof(*klass->extensions),
900 eina_list_count(extn_list) + 1);
901
902 extn_itr = klass->extensions;
903 EINA_LIST_FREE(extn_list, extn)
904 {
905 *(extn_itr++) = extn;
906 }
907 }
908
909 klass->desc = desc;
910
911 /* Handle the inheritance */
912 if (klass->parent)
913 {
914 /* Verify the inheritance is allowed. */
915 switch (klass->desc->type)
916 {
917 case EO_CLASS_TYPE_REGULAR:
918 case EO_CLASS_TYPE_REGULAR_NO_INSTANT: