summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCedric Bail <cedric@osg.samsung.com>2017-10-25 18:05:41 -0700
committerCedric BAIL <cedric@osg.samsung.com>2018-04-30 14:21:11 -0700
commit3edb4ca6975946b7cfd3b261f5c1c7a46d681710 (patch)
tree3bc25f720b7a4ea86d462522ede9563be01594f4 /src/lib
parentddcf8d8b9712e744cc4247eb219ad1f11d1bb455 (diff)
eldbus: migrate and refactor eldbus.model to new efl.model API.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/eldbus/Eldbus.h1
-rw-r--r--src/lib/eldbus/eldbus_model.c16
-rw-r--r--src/lib/eldbus/eldbus_model.eo1
-rw-r--r--src/lib/eldbus/eldbus_model_arguments.c118
-rw-r--r--src/lib/eldbus/eldbus_model_arguments.eo10
-rw-r--r--src/lib/eldbus/eldbus_model_connection.c323
-rw-r--r--src/lib/eldbus/eldbus_model_connection.eo45
-rw-r--r--src/lib/eldbus/eldbus_model_connection_private.h18
-rw-r--r--src/lib/eldbus/eldbus_model_method.c32
-rw-r--r--src/lib/eldbus/eldbus_model_method.eo21
-rw-r--r--src/lib/eldbus/eldbus_model_method_private.h4
-rw-r--r--src/lib/eldbus/eldbus_model_object.c487
-rw-r--r--src/lib/eldbus/eldbus_model_object.eo64
-rw-r--r--src/lib/eldbus/eldbus_model_object_private.h22
-rw-r--r--src/lib/eldbus/eldbus_model_private.h31
-rw-r--r--src/lib/eldbus/eldbus_model_proxy.c803
-rw-r--r--src/lib/eldbus/eldbus_model_proxy.eo32
-rw-r--r--src/lib/eldbus/eldbus_model_proxy_private.h23
18 files changed, 752 insertions, 1299 deletions
diff --git a/src/lib/eldbus/Eldbus.h b/src/lib/eldbus/Eldbus.h
index 15f8293..ac88fd5 100644
--- a/src/lib/eldbus/Eldbus.h
+++ b/src/lib/eldbus/Eldbus.h
@@ -225,6 +225,7 @@ typedef void (*Eldbus_Signal_Cb)(void *data, const Eldbus_Message *msg);
225 225
226#ifdef EFL_BETA_API_SUPPORT 226#ifdef EFL_BETA_API_SUPPORT
227 227
228#include "eldbus_model.eo.h"
228#include "eldbus_model_arguments.eo.h" 229#include "eldbus_model_arguments.eo.h"
229#include "eldbus_model_connection.eo.h" 230#include "eldbus_model_connection.eo.h"
230#include "eldbus_model_method.eo.h" 231#include "eldbus_model_method.eo.h"
diff --git a/src/lib/eldbus/eldbus_model.c b/src/lib/eldbus/eldbus_model.c
index e6d5dcc..28faa0f 100644
--- a/src/lib/eldbus/eldbus_model.c
+++ b/src/lib/eldbus/eldbus_model.c
@@ -75,6 +75,15 @@ _eldbus_model_efl_object_finalize(Eo *obj, Eldbus_Model_Data *pd)
75} 75}
76 76
77static void 77static void
78_eldbus_model_efl_object_invalidate(Eo *obj, Eldbus_Model_Data *pd)
79{
80 if (pd->connection) eldbus_connection_unref(pd->connection);
81 pd->connection = NULL;
82
83 efl_invalidate(efl_super(obj, MY_CLASS));
84}
85
86static void
78_eldbus_model_efl_object_destructor(Eo *obj, Eldbus_Model_Data *pd) 87_eldbus_model_efl_object_destructor(Eo *obj, Eldbus_Model_Data *pd)
79{ 88{
80 eina_stringshare_del(pd->unique_name); 89 eina_stringshare_del(pd->unique_name);
@@ -83,9 +92,6 @@ _eldbus_model_efl_object_destructor(Eo *obj, Eldbus_Model_Data *pd)
83 eina_stringshare_del(pd->address); 92 eina_stringshare_del(pd->address);
84 pd->address = NULL; 93 pd->address = NULL;
85 94
86 eldbus_connection_unref(pd->connection);
87 pd->connection = NULL;
88
89 efl_destructor(efl_super(obj, MY_CLASS)); 95 efl_destructor(efl_super(obj, MY_CLASS));
90} 96}
91 97
@@ -115,7 +121,7 @@ _eldbus_model_efl_model_property_set(Eo *obj,
115{ 121{
116 Eina_Error err = EFL_MODEL_ERROR_READ_ONLY; 122 Eina_Error err = EFL_MODEL_ERROR_READ_ONLY;
117 123
118 if (!strcmp(property, UNIQUE_NAME_PROPERTY)) 124 if (strcmp(property, UNIQUE_NAME_PROPERTY))
119 err = EFL_MODEL_ERROR_NOT_FOUND; 125 err = EFL_MODEL_ERROR_NOT_FOUND;
120 return eina_future_rejected(efl_loop_future_scheduler_get(obj), err); 126 return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
121} 127}
@@ -153,7 +159,7 @@ _eldbus_model_efl_model_properties_get(const Eo *obj EINA_UNUSED,
153 Eina_Array *r; 159 Eina_Array *r;
154 160
155 r = eina_array_new(1); 161 r = eina_array_new(1);
156 eina_array_push(r, UNIQUE_NAME_PROPERTY); 162 eina_array_push(r, eina_stringshare_add(UNIQUE_NAME_PROPERTY));
157 163
158 return r; 164 return r;
159} 165}
diff --git a/src/lib/eldbus/eldbus_model.eo b/src/lib/eldbus/eldbus_model.eo
index 81b0ffe..e470144 100644
--- a/src/lib/eldbus/eldbus_model.eo
+++ b/src/lib/eldbus/eldbus_model.eo
@@ -46,6 +46,7 @@ class Eldbus.Model (Efl.Object, Efl.Model) {
46 } 46 }
47 implements { 47 implements {
48 Efl.Object.finalize; 48 Efl.Object.finalize;
49 Efl.Object.invalidate;
49 Efl.Object.destructor; 50 Efl.Object.destructor;
50 Efl.Model.property { get; set; } 51 Efl.Model.property { get; set; }
51 Efl.Model.properties { get; } 52 Efl.Model.properties { get; }
diff --git a/src/lib/eldbus/eldbus_model_arguments.c b/src/lib/eldbus/eldbus_model_arguments.c
index 834296d..1d22903 100644
--- a/src/lib/eldbus/eldbus_model_arguments.c
+++ b/src/lib/eldbus/eldbus_model_arguments.c
@@ -30,8 +30,6 @@ _eldbus_model_arguments_hash_free(Eina_Value *value)
30static Efl_Object* 30static Efl_Object*
31_eldbus_model_arguments_efl_object_constructor(Eo *obj, Eldbus_Model_Arguments_Data *pd) 31_eldbus_model_arguments_efl_object_constructor(Eo *obj, Eldbus_Model_Arguments_Data *pd)
32{ 32{
33 obj = efl_constructor(efl_super(obj, MY_CLASS));
34
35 pd->obj = obj; 33 pd->obj = obj;
36 pd->properties_array = NULL; 34 pd->properties_array = NULL;
37 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free)); 35 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free));
@@ -39,7 +37,19 @@ _eldbus_model_arguments_efl_object_constructor(Eo *obj, Eldbus_Model_Arguments_D
39 pd->proxy = NULL; 37 pd->proxy = NULL;
40 pd->arguments = NULL; 38 pd->arguments = NULL;
41 pd->name = NULL; 39 pd->name = NULL;
42 return obj; 40
41 return efl_constructor(efl_super(obj, MY_CLASS));
42}
43
44static Efl_Object *
45_eldbus_model_arguments_efl_object_finalize(Eo *obj, Eldbus_Model_Arguments_Data *pd)
46{
47 if (!pd->proxy) return NULL;
48 if (!eldbus_model_connection_get(obj))
49 eldbus_model_connection_set(obj,
50 eldbus_object_connection_get(eldbus_proxy_object_get(pd->proxy)));
51
52 return efl_finalize(efl_super(obj, MY_CLASS));
43} 53}
44 54
45static void 55static void
@@ -70,9 +80,9 @@ _eldbus_model_arguments_efl_object_destructor(Eo *obj, Eldbus_Model_Arguments_Da
70 efl_destructor(efl_super(obj, MY_CLASS)); 80 efl_destructor(efl_super(obj, MY_CLASS));
71} 81}
72 82
73static Eina_Array const * 83static Eina_Array *
74_eldbus_model_arguments_efl_model_properties_get(const Eo *obj EINA_UNUSED, 84_eldbus_model_arguments_efl_model_properties_get(const Eo *obj EINA_UNUSED,
75 Eldbus_Model_Arguments_Data *pd) 85 Eldbus_Model_Arguments_Data *pd)
76{ 86{
77 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL); 87 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
78 88
@@ -113,98 +123,58 @@ _eldbus_model_arguments_properties_load(Eldbus_Model_Arguments_Data *pd)
113 } 123 }
114} 124}
115 125
116static Efl_Future* 126static Eina_Future *
117_eldbus_model_arguments_efl_model_property_set(Eo *obj EINA_UNUSED, 127_eldbus_model_arguments_efl_model_property_set(Eo *obj,
118 Eldbus_Model_Arguments_Data *pd, 128 Eldbus_Model_Arguments_Data *pd,
119 const char *property, 129 const char *property, Eina_Value *value)
120 Eina_Value const* value)
121{ 130{
122 Eina_Value *prop_value; 131 Eina_Value *prop_value;
123 Eina_Value *promise_value; 132 Eina_Error err = 0;
124 Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj); 133 Eina_Bool ret;
125 Efl_Future* future = efl_promise_future_get(promise);
126 134
127 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
128 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
129 DBG("(%p): property=%s", obj, property); 135 DBG("(%p): property=%s", obj, property);
130 136
137 err = EFL_MODEL_ERROR_NOT_FOUND;
138 if (!property || !value) goto on_error;
139
131 _eldbus_model_arguments_properties_load(pd); 140 _eldbus_model_arguments_properties_load(pd);
132 141
133 Eina_Bool ret = _eldbus_model_arguments_is_input_argument(pd, property); 142 err = EFL_MODEL_ERROR_READ_ONLY;
134 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY, future); 143 ret = _eldbus_model_arguments_is_input_argument(pd, property);
144 if (!ret) goto on_error;
135 145
146 err = EFL_MODEL_ERROR_NOT_FOUND;
136 prop_value = eina_hash_find(pd->properties_hash, property); 147 prop_value = eina_hash_find(pd->properties_hash, property);
137 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(prop_value, promise, EFL_MODEL_ERROR_NOT_FOUND, future); 148 if (!prop_value) goto on_error;
138 149
139 eina_value_flush(prop_value); 150 eina_value_flush(prop_value);
140 eina_value_copy(value, prop_value); 151 eina_value_copy(value, prop_value);
141 152
142 promise_value = eina_value_new(eina_value_type_get(value)); 153 return eina_future_resolved(efl_loop_future_scheduler_get(obj),
143 eina_value_copy(value, promise_value); 154 eina_value_reference_copy(value));
144 efl_promise_value_set(promise, promise_value, (Eina_Free_Cb)&eina_value_free); 155
145 return future; 156 on_error:
157 return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
146} 158}
147 159
148static Efl_Future* 160static Eina_Value *
149_eldbus_model_arguments_efl_model_property_get(Eo *obj EINA_UNUSED, 161_eldbus_model_arguments_efl_model_property_get(const Eo *obj, Eldbus_Model_Arguments_Data *pd, const char *property)
150 Eldbus_Model_Arguments_Data *pd,
151 const char *property)
152{ 162{
153 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj); 163 Eina_Value *value;
154 Efl_Future *future = efl_promise_future_get(promise); 164 Eina_Bool ret;
155 Eina_Value *promise_value;
156 165
157 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
158 DBG("(%p): property=%s", obj, property); 166 DBG("(%p): property=%s", obj, property);
167 if (!property) return eina_value_error_new(EFL_MODEL_ERROR_INCORRECT_VALUE);
159 168
160 _eldbus_model_arguments_properties_load(pd); 169 _eldbus_model_arguments_properties_load(pd);
161 170
162 Eina_Value* value = eina_hash_find(pd->properties_hash, property); 171 value = eina_hash_find(pd->properties_hash, property);
163 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_NOT_FOUND, future); 172 if (!value) return eina_value_error_new(EFL_MODEL_ERROR_NOT_FOUND);
164
165 Eina_Bool ret = _eldbus_model_arguments_is_output_argument(pd, property);
166 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_PERMISSION_DENIED, future);
167 173
168 promise_value = eina_value_new(eina_value_type_get(value)); 174 ret = _eldbus_model_arguments_is_output_argument(pd, property);
169 eina_value_copy(value, promise_value); 175 if (!ret) return eina_value_error_new(EFL_MODEL_ERROR_PERMISSION_DENIED);
170 efl_promise_value_set(promise, promise_value, (Eina_Free_Cb)&eina_value_free);
171 return future;
172}
173 176
174static Eo * 177 return eina_value_dup(value);
175_eldbus_model_arguments_efl_model_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd EINA_UNUSED)
176{
177 return NULL;
178}
179
180static void
181_eldbus_model_arguments_efl_model_child_del(Eo *obj EINA_UNUSED,
182 Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
183 Eo *child EINA_UNUSED)
184{
185}
186
187static Efl_Future*
188_eldbus_model_arguments_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
189 Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
190 unsigned start EINA_UNUSED,
191 unsigned count EINA_UNUSED)
192{
193 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
194 efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
195 return efl_promise_future_get(promise);
196}
197
198static Efl_Future*
199_eldbus_model_arguments_efl_model_children_count_get(Eo *obj EINA_UNUSED,
200 Eldbus_Model_Arguments_Data *pd EINA_UNUSED)
201{
202 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
203 Efl_Future* future = efl_promise_future_get(promise);
204 unsigned *count = malloc(sizeof(unsigned));
205 *count = 0;
206 efl_promise_value_set(promise, count, free);
207 return future;
208} 178}
209 179
210static const char * 180static const char *
diff --git a/src/lib/eldbus/eldbus_model_arguments.eo b/src/lib/eldbus/eldbus_model_arguments.eo
index 4dec2dc..262d782 100644
--- a/src/lib/eldbus/eldbus_model_arguments.eo
+++ b/src/lib/eldbus/eldbus_model_arguments.eo
@@ -1,6 +1,6 @@
1import eldbus_types; 1import eldbus_types;
2 2
3class Eldbus.Model.Arguments (Efl.Object, Efl.Model) { 3class Eldbus.Model.Arguments (Eldbus.Model) {
4 [[Eldbus model arguments class]] 4 [[Eldbus model arguments class]]
5 5
6 methods { 6 methods {
@@ -24,14 +24,10 @@ class Eldbus.Model.Arguments (Efl.Object, Efl.Model) {
24 } 24 }
25 implements { 25 implements {
26 Efl.Object.constructor; 26 Efl.Object.constructor;
27 Efl.Object.finalize;
27 Efl.Object.destructor; 28 Efl.Object.destructor;
28 Efl.Model.properties { get; } 29 Efl.Model.properties { get; }
29 Efl.Model.property_set; 30 Efl.Model.property { set; get; }
30 Efl.Model.property_get;
31 Efl.Model.child_add;
32 Efl.Model.child_del;
33 Efl.Model.children_slice_get;
34 Efl.Model.children_count_get;
35 } 31 }
36 constructors { 32 constructors {
37 .custom_constructor; 33 .custom_constructor;
diff --git a/src/lib/eldbus/eldbus_model_connection.c b/src/lib/eldbus/eldbus_model_connection.c
index 5fe0202..ef16f98 100644
--- a/src/lib/eldbus/eldbus_model_connection.c
+++ b/src/lib/eldbus/eldbus_model_connection.c
@@ -9,13 +9,7 @@
9#define MY_CLASS ELDBUS_MODEL_CONNECTION_CLASS 9#define MY_CLASS ELDBUS_MODEL_CONNECTION_CLASS
10#define MY_CLASS_NAME "Eldbus_Model_Connection" 10#define MY_CLASS_NAME "Eldbus_Model_Connection"
11 11
12#define UNIQUE_NAME_PROPERTY "unique_name"
13
14
15static void _eldbus_model_connection_names_list_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 12static void _eldbus_model_connection_names_list_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
16static void _eldbus_model_connection_connect(Eldbus_Model_Connection_Data *);
17static void _eldbus_model_connection_disconnect(Eldbus_Model_Connection_Data *);
18static void _eldbus_model_connection_clear(Eldbus_Model_Connection_Data *);
19 13
20static Efl_Object* 14static Efl_Object*
21_eldbus_model_connection_efl_object_constructor(Eo *obj, Eldbus_Model_Connection_Data *pd) 15_eldbus_model_connection_efl_object_constructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
@@ -23,288 +17,101 @@ _eldbus_model_connection_efl_object_constructor(Eo *obj, Eldbus_Model_Connection
23 obj = efl_constructor(efl_super(obj, MY_CLASS)); 17 obj = efl_constructor(efl_super(obj, MY_CLASS));
24 18
25 pd->obj = obj; 19 pd->obj = obj;
26 pd->is_listed = EINA_FALSE;
27 pd->connection = NULL;
28 pd->properties_array = NULL;
29 pd->children_list = NULL;
30 pd->type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
31 pd->address = NULL;
32 pd->private = false;
33 pd->unique_name = NULL;
34 pd->pending_list = NULL;
35 20
36 return obj; 21 return obj;
37} 22}
38 23
39static void 24static void
40_eldbus_model_connection_custom_constructor(Eo *obj EINA_UNUSED,
41 Eldbus_Model_Connection_Data *pd,
42 Eldbus_Connection_Type type,
43 const char* address,
44 Eina_Bool private)
45{
46 pd->type = type;
47 pd->address = eina_stringshare_add(address);
48 pd->private = private;
49}
50
51static void
52_eldbus_model_connection_efl_object_destructor(Eo *obj, Eldbus_Model_Connection_Data *pd) 25_eldbus_model_connection_efl_object_destructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
53{ 26{
54 eina_stringshare_del(pd->address); 27 Eldbus_Children_Slice_Promise *slice;
55 28 Eo *child;
56 _eldbus_model_connection_clear(pd);
57
58 efl_destructor(efl_super(obj, MY_CLASS));
59}
60
61static Eina_Array const *
62_eldbus_model_connection_efl_model_properties_get(const Eo *obj EINA_UNUSED,
63 Eldbus_Model_Connection_Data *pd)
64{
65 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
66 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, NULL);
67
68 if (pd->properties_array == NULL)
69 {
70 Eina_Bool ret;
71
72 pd->properties_array = eina_array_new(1);
73 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, NULL);
74
75 ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY);
76 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
77 }
78
79 return pd->properties_array;
80}
81
82
83static Efl_Future*
84_eldbus_model_connection_efl_model_property_set(Eo *obj EINA_UNUSED,
85 Eldbus_Model_Connection_Data *pd EINA_UNUSED,
86 const char *property,
87 Eina_Value const* value EINA_UNUSED)
88{
89 Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj);
90 Efl_Future* future = efl_promise_future_get(promise);
91 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise,
92 EFL_MODEL_ERROR_NOT_FOUND, future);
93 efl_promise_failed_set(promise, EFL_MODEL_ERROR_READ_ONLY);
94 return future;
95}
96
97static Efl_Future*
98_eldbus_model_connection_efl_model_property_get(Eo *obj EINA_UNUSED,
99 Eldbus_Model_Connection_Data *pd,
100 const char *property)
101{
102 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
103 Efl_Future *future = efl_promise_future_get(promise);
104
105 DBG("(%p): property=%s", obj, property);
106 29
107 if (!pd->connection) 30 if (pd->pending) eldbus_pending_cancel(pd->pending);
108 _eldbus_model_connection_connect(pd);
109 31
110 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, 32 EINA_LIST_FREE(pd->childrens, child)
111 EFL_MODEL_ERROR_NOT_FOUND, future); 33 efl_del(child);
112 34
113 if (pd->unique_name == NULL) 35 EINA_LIST_FREE(pd->requests, slice)
114 { 36 {
115 const char *unique_name; 37 eina_promise_reject(slice->p, EFL_MODEL_ERROR_UNKNOWN);
116 38 free(slice);
117 unique_name = eldbus_connection_unique_name_get(pd->connection);
118 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
119 pd->unique_name = strdup(unique_name);
120 } 39 }
121 40
122 Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING); 41 efl_destructor(efl_super(obj, ELDBUS_MODEL_CONNECTION_CLASS));
123 eina_value_set(v, pd->unique_name);
124 efl_promise_value_set(promise, v, (Eina_Free_Cb)&eina_value_free);
125 return future;
126}
127
128static Eo *
129_eldbus_model_connection_efl_model_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd EINA_UNUSED)
130{
131 return NULL;
132} 42}
133 43
134static void 44static void
135_eldbus_model_connection_efl_model_child_del(Eo *obj EINA_UNUSED, 45_eldbus_model_children_list(const Eo *obj, Eldbus_Model_Connection_Data *pd)
136 Eldbus_Model_Connection_Data *pd EINA_UNUSED,
137 Eo *child EINA_UNUSED)
138{ 46{
139} 47 Eldbus_Model_Data *sd;
140 48
141static Efl_Promise* 49 if (pd->pending || pd->is_listed) return ;
142_eldbus_model_connection_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
143 Eldbus_Model_Connection_Data *pd,
144 unsigned int start,
145 unsigned int count)
146{
147 Efl_Promise *promise;
148 Efl_Future *future;
149 _Eldbus_Children_Slice_Promise* data;
150 Eldbus_Pending *pending;
151 50
152 promise = efl_add(EFL_PROMISE_CLASS, obj); 51 sd = efl_data_scope_get(obj, ELDBUS_MODEL_CLASS);
153 future = efl_promise_future_get(promise);
154 52
155 if (!pd->connection) 53 pd->pending = eldbus_names_list(sd->connection,
156 _eldbus_model_connection_connect(pd); 54 &_eldbus_model_connection_names_list_cb,
157 55 pd);
158 if (pd->is_listed)
159 {
160 Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
161 efl_promise_value_set(promise, ac, (Eina_Free_Cb)&eina_accessor_free);
162 return future;
163 }
164
165 data = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
166 EINA_SAFETY_ON_NULL_RETURN_VAL(data, future);
167 data->promise = promise;
168 data->start = start;
169 data->count = count;
170
171 pd->children_promises = eina_list_prepend(pd->children_promises, data);
172
173 if (pd->pending_list == NULL)
174 {
175 pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
176 pd->pending_list = eina_list_append(pd->pending_list, pending);
177 }
178 return future;
179} 56}
180 57
181static Efl_Future* 58static Eina_Future *
182_eldbus_model_connection_efl_model_children_count_get(Eo *obj EINA_UNUSED, 59_eldbus_model_connection_efl_model_children_slice_get(Eo *obj,
183 Eldbus_Model_Connection_Data *pd) 60 Eldbus_Model_Connection_Data *pd,
61 unsigned int start,
62 unsigned int count)
184{ 63{
185 Efl_Promise *promise; 64 Eldbus_Children_Slice_Promise* slice;
186 Eldbus_Pending *pending; 65 Eina_Promise *p;
187
188 promise = efl_add(EFL_PROMISE_CLASS, obj);
189 if (!pd->connection)
190 _eldbus_model_connection_connect(pd);
191 66
192 if (pd->is_listed) 67 if (pd->is_listed)
193 { 68 {
194 unsigned int *c = calloc(sizeof(unsigned int), 1); 69 Eina_Value v;
195 *c = eina_list_count(pd->children_list);
196 efl_promise_value_set(promise, c, free);
197 return efl_promise_future_get(promise);
198 }
199 70
200 pd->count_promises = eina_list_prepend(pd->count_promises, promise); 71 v = efl_model_list_value_get(pd->childrens, start, count);
201 if (pd->pending_list == NULL) 72 return eina_future_resolved(efl_loop_future_scheduler_get(obj), v);
202 {
203 pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
204 pd->pending_list = eina_list_append(pd->pending_list, pending);
205 } 73 }
206 return efl_promise_future_get(promise);
207}
208
209static const char *
210_eldbus_model_connection_address_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
211{
212 return pd->address;
213}
214
215static Eina_Bool
216_eldbus_model_connection_private_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
217{
218 return pd->private;
219}
220
221static Eldbus_Connection_Type
222_eldbus_model_connection_type_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
223{
224 return pd->type;
225}
226 74
227static void 75 p = eina_promise_new(efl_loop_future_scheduler_get(obj),
228_eldbus_model_connection_connect(Eldbus_Model_Connection_Data *pd) 76 _eldbus_eina_promise_cancel, NULL);
229{
230 EINA_SAFETY_ON_NULL_RETURN(pd);
231 77
232 if (ELDBUS_CONNECTION_TYPE_ADDRESS == pd->type) 78 slice = calloc(1, sizeof (Eldbus_Children_Slice_Promise));
233 { 79 slice->p = p;
234 if (pd->private) 80 slice->start = start;
235 pd->connection = eldbus_address_connection_get(pd->address); 81 slice->count = count;
236 else
237 pd->connection = eldbus_private_address_connection_get(pd->address);
238 }
239 else
240 {
241 if (pd->private)
242 pd->connection = eldbus_private_connection_get(pd->type);
243 else
244 pd->connection = eldbus_connection_get(pd->type);
245 }
246 82
247 // TODO: Register for disconnection event 83 pd->requests = eina_list_prepend(pd->requests, slice);
248 84
249 EINA_SAFETY_ON_FALSE_RETURN(pd->connection != NULL); 85 _eldbus_model_children_list(obj, pd);
86 return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));;
250} 87}
251 88
252static void 89static unsigned int
253_eldbus_model_connection_disconnect(Eldbus_Model_Connection_Data *pd) 90_eldbus_model_connection_efl_model_children_count_get(const Eo *obj,
91 Eldbus_Model_Connection_Data *pd)
254{ 92{
255 EINA_SAFETY_ON_NULL_RETURN(pd); 93 _eldbus_model_children_list(obj, pd);
256 eldbus_connection_unref(pd->connection); 94 return eina_list_count(pd->childrens);
257 pd->connection = NULL;
258}
259
260static void
261_eldbus_model_connection_clear(Eldbus_Model_Connection_Data *pd)
262{
263 Eldbus_Pending *pending;
264 Eo *child;
265
266 EINA_SAFETY_ON_NULL_RETURN(pd);
267
268 if (!pd->connection)
269 return;
270
271 free(pd->unique_name);
272 pd->unique_name = NULL;
273
274 EINA_LIST_FREE(pd->children_list, child)
275 efl_del(child);
276
277 EINA_LIST_FREE(pd->pending_list, pending)
278 eldbus_pending_cancel(pending);
279
280 if (pd->properties_array)
281 {
282 eina_array_free(pd->properties_array);
283 pd->properties_array = NULL;
284 }
285
286 _eldbus_model_connection_disconnect(pd);
287} 95}
288 96
289static void 97static void
290_eldbus_model_connection_names_list_cb(void *data, 98_eldbus_model_connection_names_list_cb(void *data,
291 const Eldbus_Message *msg, 99 const Eldbus_Message *msg,
292 Eldbus_Pending *pending) 100 Eldbus_Pending *pending EINA_UNUSED)
293{ 101{
294 Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*)data; 102 Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*) data;
295 _Eldbus_Children_Slice_Promise * p; 103 Eldbus_Model_Data *sd;
104 Eldbus_Children_Slice_Promise *slice;
296 const char *error_name, *error_text; 105 const char *error_name, *error_text;
297 Eldbus_Message_Iter *array = NULL; 106 Eldbus_Message_Iter *array = NULL;
298 const char *bus; 107 const char *bus;
299 unsigned int count; 108 unsigned int count;
300 Eina_List* i;
301 109
302 pd->pending_list = eina_list_remove(pd->pending_list, pending); 110 pd->pending = NULL;
303 111
304 if (eldbus_message_error_get(msg, &error_name, &error_text)) 112 if (eldbus_message_error_get(msg, &error_name, &error_text))
305 { 113 {
306 ERR("%s: %s", error_name, error_text); 114 ERR("%s: %s", error_name, error_text);
307 //efl_model_error_notify(pd->obj);
308 return; 115 return;
309 } 116 }
310 117
@@ -314,39 +121,37 @@ _eldbus_model_connection_names_list_cb(void *data,
314 return; 121 return;
315 } 122 }
316 123
124 sd = efl_data_scope_get(pd->obj, ELDBUS_MODEL_CLASS);
125
317 while (eldbus_message_iter_get_and_next(array, 's', &bus)) 126 while (eldbus_message_iter_get_and_next(array, 's', &bus))
318 { 127 {
128 Eo *child;
129
319 DBG("(%p): bus = %s", pd->obj, bus); 130 DBG("(%p): bus = %s", pd->obj, bus);
320 131
321 Eo *child = efl_add(ELDBUS_MODEL_OBJECT_CLASS, pd->obj, eldbus_model_object_connection_constructor(efl_added, pd->connection, bus, "/")); 132 child = efl_add(ELDBUS_MODEL_OBJECT_CLASS, pd->obj,
133 eldbus_model_connection_set(efl_added, sd->connection),
134 eldbus_model_object_bus_set(efl_added, bus),
135 eldbus_model_object_path_set(efl_added, "/"));
322 136
323 pd->children_list = eina_list_append(pd->children_list, child); 137 pd->childrens = eina_list_append(pd->childrens, child);
324 } 138 }
325 139
326 count = eina_list_count(pd->children_list);
327
328 if (count)
329 efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
330
331 pd->is_listed = EINA_TRUE; 140 pd->is_listed = EINA_TRUE;
332 141
333 EINA_LIST_FOREACH(pd->children_promises, i, p) 142 count = eina_list_count(pd->childrens);
334 { 143 efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
335 Eina_Accessor *ac = efl_model_list_slice(pd->children_list, p->start, p->count);
336 efl_promise_value_set(p->promise, ac, (Eina_Free_Cb)&eina_accessor_free);
337 free(p);
338 }
339 eina_list_free(pd->children_promises);
340 144
341 Efl_Promise *ep; 145 EINA_LIST_FREE(pd->requests, slice)
342 EINA_LIST_FOREACH(pd->count_promises, i, ep)
343 { 146 {
344 unsigned *c = calloc(sizeof(unsigned), 1); 147 Eina_Value v;
345 *c = eina_list_count(pd->children_list); 148
346 efl_promise_value_set(ep, c, free); 149 v = efl_model_list_value_get(pd->childrens,
150 slice->start, slice->count);
151 eina_promise_resolve(slice->p, v);
152
153 free(slice);
347 } 154 }
348 eina_list_free(pd->count_promises);
349} 155}
350 156
351
352#include "eldbus_model_connection.eo.c" 157#include "eldbus_model_connection.eo.c"
diff --git a/src/lib/eldbus/eldbus_model_connection.eo b/src/lib/eldbus/eldbus_model_connection.eo
index b1f9a1d..5d13cd9 100644
--- a/src/lib/eldbus/eldbus_model_connection.eo
+++ b/src/lib/eldbus/eldbus_model_connection.eo
@@ -1,53 +1,12 @@
1import eldbus_types; 1import eldbus_types;
2 2
3class Eldbus.Model.Connection (Efl.Object, Efl.Model) { 3class Eldbus.Model.Connection (Eldbus.Model) {
4 [[Eldbus model connection class]] 4 [[Eldbus model connection class]]
5 5
6 methods {
7 custom_constructor {
8 [[Custom Eldbus_Model_Connection constructor.
9
10 @since 1.16]]
11 params {
12 @in type: Eldbus.Connection.Type; [[The connection type]]
13 @in address: string; [[Remote address of DBus]]
14 @in private_: bool; [[Non shared dbus connection]]
15 }
16 }
17 @property type {
18 [[Connection type]]
19 get { }
20 values {
21 type: Eldbus.Connection.Type; [[Connection type]]
22 }
23 }
24 @property address {
25 [[Remote DBus address]]
26 get { }
27 values {
28 address: string; [[Address]]
29 }
30 }
31 @property private {
32 [[Indicate if the DBus connection is shared or private]]
33 get { }
34 values {
35 private_: bool; [[Private DBus connection]]
36 }
37 }
38 }
39 implements { 6 implements {
40 Efl.Object.constructor; 7 Efl.Object.constructor;
41 Efl.Object.destructor; 8 Efl.Object.destructor;
42 Efl.Model.properties { get; }
43 Efl.Model.property_set;
44 Efl.Model.property_get;
45 Efl.Model.child_add;
46 Efl.Model.child_del;
47 Efl.Model.children_slice_get; 9 Efl.Model.children_slice_get;
48 Efl.Model.children_count_get; 10 Efl.Model.children_count { get; }
49 }
50 constructors {
51 .custom_constructor;
52 } 11 }
53} 12}
diff --git a/src/lib/eldbus/eldbus_model_connection_private.h b/src/lib/eldbus/eldbus_model_connection_private.h
index a1636b9..829ddd9 100644
--- a/src/lib/eldbus/eldbus_model_connection_private.h
+++ b/src/lib/eldbus/eldbus_model_connection_private.h
@@ -13,18 +13,20 @@ typedef struct _Eldbus_Model_Connection_Data Eldbus_Model_Connection_Data;
13struct _Eldbus_Model_Connection_Data 13struct _Eldbus_Model_Connection_Data
14{ 14{
15 Eo *obj; 15 Eo *obj;
16 Eina_Bool is_listed : 1; 16
17 Eldbus_Connection *connection; 17 Eldbus_Connection *connection;
18 Eina_Array *properties_array; 18 Eldbus_Pending *pending;
19 Eina_List *children_list;
20 Eina_List *children_promises;
21 Eina_List *count_promises;
22 Eldbus_Connection_Type type; 19 Eldbus_Connection_Type type;
20
21 Eina_List *childrens;
22 Eina_List *requests;
23
23 Eina_Stringshare *address; 24 Eina_Stringshare *address;
24 bool private;
25 char *unique_name; 25 char *unique_name;
26 Eina_List *pending_list; 26
27 bool private;
28
29 Eina_Bool is_listed : 1;
27}; 30};
28 31
29#endif 32#endif
30
diff --git a/src/lib/eldbus/eldbus_model_method.c b/src/lib/eldbus/eldbus_model_method.c
index caafddd..8e7e87b 100644
--- a/src/lib/eldbus/eldbus_model_method.c
+++ b/src/lib/eldbus/eldbus_model_method.c
@@ -26,17 +26,33 @@ _eldbus_model_method_efl_object_constructor(Eo *obj, Eldbus_Model_Method_Data *p
26 return obj; 26 return obj;
27} 27}
28 28
29static void 29static Efl_Object*
30_eldbus_model_method_method_constructor(Eo *obj EINA_UNUSED, 30_eldbus_model_method_efl_object_finalize(Eo *obj, Eldbus_Model_Method_Data *pd)
31 Eldbus_Model_Method_Data *pd,
32 Eldbus_Proxy *proxy,
33 const Eldbus_Introspection_Method *method)
34{ 31{
35 EINA_SAFETY_ON_NULL_RETURN(proxy); 32 if (!pd->proxy ||
36 EINA_SAFETY_ON_NULL_RETURN(method); 33 !pd->method)
34 return NULL;
35
36 eldbus_model_arguments_custom_constructor(obj,
37 pd->proxy,
38 pd->method->name, pd->method->arguments);
37 39
38 eldbus_model_arguments_custom_constructor(efl_super(obj, MY_CLASS), proxy, method->name, method->arguments); 40 return obj;
41}
39 42
43static void
44_eldbus_model_method_proxy_set(Eo *obj EINA_UNUSED,
45 Eldbus_Model_Method_Data *pd,
46 Eldbus_Proxy *proxy)
47{
48 pd->proxy = proxy;
49}
50
51static void
52_eldbus_model_method_method_set(Eo *obj EINA_UNUSED,
53 Eldbus_Model_Method_Data *pd,
54 const Eldbus_Introspection_Method *method)
55{
40 pd->method = method; 56 pd->method = method;
41} 57}
42 58
diff --git a/src/lib/eldbus/eldbus_model_method.eo b/src/lib/eldbus/eldbus_model_method.eo
index 015ebc7..ef5ab10 100644
--- a/src/lib/eldbus/eldbus_model_method.eo
+++ b/src/lib/eldbus/eldbus_model_method.eo
@@ -3,13 +3,20 @@ import eldbus_types;
3class Eldbus.Model.Method (Eldbus.Model.Arguments) { 3class Eldbus.Model.Method (Eldbus.Model.Arguments) {
4 [[Eldbus model method class]] 4 [[Eldbus model method class]]
5 methods { 5 methods {
6 method_constructor { 6 @property proxy {
7 [[Custom Eldbus_Model_Method constructor. 7 [[Custom Eldbus_Model_Method constructor.
8 8
9 @since 1.16]] 9 @since 1.21]]
10 params { 10 set {}
11 @in proxy: ptr(Eldbus.Proxy); [[Eldbus proxy]] 11 values {
12 @cref method: Eldbus.Introspection.Method; [[The introspected method]] 12 proxy: ptr(Eldbus.Proxy); [[Eldbus proxy]]
13 }
14 }
15 @property method {
16 [[Object]]
17 set {}
18 values {
19 @cref method: Eldbus.Introspection.Method; [[The introspected interface]]
13 } 20 }
14 } 21 }
15 call { 22 call {
@@ -24,9 +31,11 @@ class Eldbus.Model.Method (Eldbus.Model.Arguments) {
24 } 31 }
25 implements { 32 implements {
26 Efl.Object.constructor; 33 Efl.Object.constructor;
34 Efl.Object.finalize;
27 } 35 }
28 constructors { 36 constructors {
29 .method_constructor; 37 .proxy;
38 .method;
30 } 39 }
31 events { 40 events {
32 successful,call; [[Event dispatched for a successful method call.]] 41 successful,call; [[Event dispatched for a successful method call.]]
diff --git a/src/lib/eldbus/eldbus_model_method_private.h b/src/lib/eldbus/eldbus_model_method_private.h
index 5092b50..d3813f6 100644
--- a/src/lib/eldbus/eldbus_model_method_private.h
+++ b/src/lib/eldbus/eldbus_model_method_private.h
@@ -11,8 +11,10 @@ typedef struct _Eldbus_Model_Method_Data Eldbus_Model_Method_Data;
11struct _Eldbus_Model_Method_Data 11struct _Eldbus_Model_Method_Data
12{ 12{
13 Eo *obj; 13 Eo *obj;
14
14 const Eldbus_Introspection_Method *method; 15 const Eldbus_Introspection_Method *method;
16
17 Eldbus_Proxy *proxy;
15}; 18};
16 19
17#endif 20#endif
18
diff --git a/src/lib/eldbus/eldbus_model_object.c b/src/lib/eldbus/eldbus_model_object.c
index 04af7cf..5bb9269 100644
--- a/src/lib/eldbus/eldbus_model_object.c
+++ b/src/lib/eldbus/eldbus_model_object.c
@@ -11,15 +11,7 @@
11#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS 11#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS
12#define MY_CLASS_NAME "Eldbus_Model_Object" 12#define MY_CLASS_NAME "Eldbus_Model_Object"
13 13
14#define UNIQUE_NAME_PROPERTY "unique_name"
15
16static bool _eldbus_model_object_introspect(Eldbus_Model_Object_Data *, const char *, const char *);
17static void _eldbus_model_object_introspect_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 14static void _eldbus_model_object_introspect_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
18static void _eldbus_model_object_connect(Eldbus_Model_Object_Data *);
19static void _eldbus_model_object_disconnect(Eldbus_Model_Object_Data *);
20static void _eldbus_model_object_clear(Eldbus_Model_Object_Data *);
21static void _eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *, const char *, Eina_List *);
22static char *_eldbus_model_object_concatenate_path(const char *, const char *);
23static void _eldbus_model_object_create_children(Eldbus_Model_Object_Data *, Eldbus_Object *, Eina_List *); 15static void _eldbus_model_object_create_children(Eldbus_Model_Object_Data *, Eldbus_Object *, Eina_List *);
24 16
25static Efl_Object* 17static Efl_Object*
@@ -28,219 +20,135 @@ _eldbus_model_object_efl_object_constructor(Eo *obj, Eldbus_Model_Object_Data *p
28 obj = efl_constructor(efl_super(obj, MY_CLASS)); 20 obj = efl_constructor(efl_super(obj, MY_CLASS));
29 21
30 pd->obj = obj; 22 pd->obj = obj;
31 pd->is_listed = EINA_FALSE;
32 pd->connection = NULL;
33 pd->object_list = NULL;
34 pd->properties_array = NULL;
35 pd->children_list = NULL;
36 pd->type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
37 pd->address = NULL;
38 pd->private = false;
39 pd->bus = NULL;
40 pd->path = NULL;
41 pd->unique_name = NULL;
42 pd->pending_list = NULL;
43 pd->introspection = NULL;
44 23
45 return obj; 24 return obj;
46} 25}
47 26
48static void 27static void
49_eldbus_model_object_custom_constructor(Eo *obj EINA_UNUSED, 28_eldbus_model_object_bus_set(Eo *obj EINA_UNUSED,
50 Eldbus_Model_Object_Data *pd, 29 Eldbus_Model_Object_Data *pd,
51 Eldbus_Connection_Type type, 30 const char *bus)
52 const char* address,
53 Eina_Bool private,
54 const char* bus,
55 const char* path)
56{ 31{
57 EINA_SAFETY_ON_NULL_RETURN(bus);
58 EINA_SAFETY_ON_NULL_RETURN(path);
59
60 pd->type = type;
61 pd->address = eina_stringshare_add(address);
62 pd->private = private;
63 pd->bus = eina_stringshare_add(bus); 32 pd->bus = eina_stringshare_add(bus);
64 pd->path = eina_stringshare_add(path);
65} 33}
66 34
67static void 35static void
68_eldbus_model_object_connection_constructor(Eo *obj EINA_UNUSED, 36_eldbus_model_object_path_set(Eo *obj EINA_UNUSED,
69 Eldbus_Model_Object_Data *pd, 37 Eldbus_Model_Object_Data *pd,
70 Eldbus_Connection *connection, 38 const char *path)
71 const char* bus,
72 const char* path)
73{ 39{
74 EINA_SAFETY_ON_NULL_RETURN(connection);
75 EINA_SAFETY_ON_NULL_RETURN(bus);
76 EINA_SAFETY_ON_NULL_RETURN(path);
77
78 pd->connection = eldbus_connection_ref(connection);
79 pd->bus = eina_stringshare_add(bus);
80 pd->path = eina_stringshare_add(path); 40 pd->path = eina_stringshare_add(path);
81} 41}
82 42
83static void 43static Efl_Object*
84_eldbus_model_object_efl_object_destructor(Eo *obj, Eldbus_Model_Object_Data *pd) 44_eldbus_model_object_efl_object_finalize(Eo *obj, Eldbus_Model_Object_Data *pd)
85{
86 eina_stringshare_del(pd->address);
87 eina_stringshare_del(pd->bus);
88 eina_stringshare_del(pd->path);
89
90 _eldbus_model_object_clear(pd);
91
92 efl_destructor(efl_super(obj, MY_CLASS));
93}
94
95static Eina_Array const *
96_eldbus_model_object_efl_model_properties_get(const Eo *obj EINA_UNUSED,
97 Eldbus_Model_Object_Data *pd)
98{ 45{
99 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL); 46 if (!pd->bus || !pd->path)
100 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, NULL); 47 return NULL;
101
102 if (pd->properties_array == NULL)
103 {
104 Eina_Bool ret;
105 48
106 pd->properties_array = eina_array_new(1); 49 return efl_finalize(efl_super(obj, MY_CLASS));
107 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, NULL);
108
109 ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY);
110 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
111 }
112
113 return pd->properties_array;
114}
115
116static Efl_Future*
117_eldbus_model_object_efl_model_property_set(Eo *obj EINA_UNUSED,
118 Eldbus_Model_Object_Data *pd EINA_UNUSED,
119 const char *property,
120 const Eina_Value *value EINA_UNUSED)
121{
122 Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj);
123 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise,
124 EFL_MODEL_ERROR_NOT_FOUND, efl_promise_future_get(promise));
125 efl_promise_failed_set(promise, EFL_MODEL_ERROR_READ_ONLY);
126 return efl_promise_future_get(promise);
127} 50}
128 51
129static Efl_Future* 52static void
130_eldbus_model_object_efl_model_property_get(Eo *obj EINA_UNUSED, 53_eldbus_model_object_efl_object_invalidate(Eo *obj, Eldbus_Model_Object_Data *pd)
131 Eldbus_Model_Object_Data *pd,
132 const char *property)
133{ 54{
134 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj); 55 Eldbus_Pending *pending;
135 Efl_Future *future = efl_promise_future_get(promise); 56 Eldbus_Object *object;
57 Eo *child;
136 58
137 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future); 59 EINA_LIST_FREE(pd->childrens, child)
138 DBG("(%p): property=%s", obj, property); 60 efl_unref(child);
139 61
140 if (!pd->connection) 62 EINA_LIST_FREE(pd->pendings, pending)
141 _eldbus_model_object_connect(pd); 63 eldbus_pending_cancel(pending);
142 64
143 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, 65 EINA_LIST_FREE(pd->objects, object)
144 EFL_MODEL_ERROR_NOT_FOUND, future); 66 eldbus_object_unref(object);
145 67
146 if (pd->unique_name == NULL) 68 if (pd->introspection)
147 { 69 {
148 const char *unique_name; 70 eldbus_introspection_node_free(pd->introspection);
149 71 pd->introspection = NULL;
150 unique_name = eldbus_connection_unique_name_get(pd->connection);
151 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
152 pd->unique_name = strdup(unique_name);
153 } 72 }
154 73
155 Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING); 74 efl_invalidate(efl_super(obj, MY_CLASS));
156 eina_value_set(v, pd->unique_name);
157 efl_promise_value_set(promise, v, (Eina_Free_Cb)&eina_value_free);
158 return future;
159}
160
161static Eo *
162_eldbus_model_object_efl_model_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd EINA_UNUSED)
163{
164 return NULL;
165} 75}
166 76
167static void 77static void
168_eldbus_model_object_efl_model_child_del(Eo *obj EINA_UNUSED, 78_eldbus_model_object_efl_object_destructor(Eo *obj, Eldbus_Model_Object_Data *pd)
169 Eldbus_Model_Object_Data *pd EINA_UNUSED,
170 Eo *child EINA_UNUSED)
171{ 79{
80 eina_stringshare_del(pd->bus);
81 eina_stringshare_del(pd->path);
82
83 efl_destructor(efl_super(obj, MY_CLASS));
172} 84}
173 85
174static Efl_Future* 86static Eina_Bool
175_eldbus_model_object_efl_model_children_slice_get(Eo *obj EINA_UNUSED, 87_eldbus_model_object_introspect(const Eo *obj,
176 Eldbus_Model_Object_Data *pd, 88 Eldbus_Model_Object_Data *pd,
177 unsigned start, 89 const char *bus,
178 unsigned count) 90 const char *path)
179{ 91{
180 _Eldbus_Children_Slice_Promise* p; 92 Eldbus_Pending *pending;
181 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj); 93 Eldbus_Object *object;
182 Efl_Future *future = efl_promise_future_get(promise);
183 94
184 if (!pd->connection) 95 DBG("(%p) Introspecting: bus = %s, path = %s", pd->obj, bus, path);
185 _eldbus_model_object_connect(pd);
186 96
187 if (pd->is_listed) 97 object = eldbus_object_get(eldbus_model_connection_get(obj),
98 bus, path);
99 if (!object)
188 { 100 {
189 Eina_Accessor* ac = efl_model_list_slice(pd->children_list, start, count); 101 ERR("(%p): Cannot get object: bus=%s, path=%s", pd->obj, bus, path);
190 efl_promise_value_set(promise, ac, (Eina_Free_Cb)&eina_accessor_free); 102 return EINA_FALSE;
191 return future;
192 } 103 }
104 pd->objects = eina_list_append(pd->objects, object);
193 105
194 p = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise)); 106 // TODO: Register for interface added/removed event
195 EINA_SAFETY_ON_NULL_RETURN_VAL(p, future); 107 pending = eldbus_object_introspect(object, &_eldbus_model_object_introspect_cb, pd);
196 p->promise = promise; 108 eldbus_pending_data_set(pending, "object", object);
197 p->start = start; 109 pd->pendings = eina_list_append(pd->pendings, pending);
198 p->count = count; 110 return EINA_TRUE;
199
200 pd->children_promises = eina_list_prepend(pd->children_promises, p);
201 if (pd->pending_list == NULL)
202 _eldbus_model_object_introspect(pd, pd->bus, pd->path);
203 return future;
204} 111}
205 112
206static Efl_Future* 113static Eina_Future *
207_eldbus_model_object_efl_model_children_count_get(Eo *obj EINA_UNUSED, 114_eldbus_model_object_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
208 Eldbus_Model_Object_Data *pd) 115 Eldbus_Model_Object_Data *pd,
116 unsigned start,
117 unsigned count)
209{ 118{
210 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj); 119 Eldbus_Children_Slice_Promise *slice;
211 if (!pd->connection) 120 Eina_Promise *p;
212 _eldbus_model_object_connect(pd);
213 121
214 if (pd->is_listed) 122 if (pd->is_listed)
215 { 123 {
216 unsigned int *c = calloc(sizeof(unsigned int), 1); 124 Eina_Value v;
217 *c = eina_list_count(pd->children_list); 125
218 efl_promise_value_set(promise, c, free); 126 v = efl_model_list_value_get(pd->childrens, start, count);
219 return efl_promise_future_get(promise); 127 return eina_future_resolved(efl_loop_future_scheduler_get(obj), v);
220 } 128 }
221 129
222 pd->count_promises = eina_list_prepend(pd->count_promises, promise); 130 p = eina_promise_new(efl_loop_future_scheduler_get(obj),
223 if (pd->pending_list == NULL) 131 _eldbus_eina_promise_cancel, NULL);
224 _eldbus_model_object_introspect(pd, pd->bus, pd->path);
225 return efl_promise_future_get(promise);
226}
227 132
228static const char * 133 slice = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
229_eldbus_model_object_address_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd) 134 slice->p = p;
230{ 135 slice->start = start;
231 return pd->address; 136 slice->count = count;
232}
233 137
234static Eina_Bool 138 pd->requests = eina_list_prepend(pd->requests, slice);
235_eldbus_model_object_private_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd) 139
236{ 140 if (!pd->pendings)
237 return pd->private; 141 _eldbus_model_object_introspect(obj, pd, pd->bus, pd->path);
142 return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));;
238} 143}
239 144
240static Eldbus_Connection_Type 145static unsigned int
241_eldbus_model_object_type_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd) 146_eldbus_model_object_efl_model_children_count_get(const Eo *obj EINA_UNUSED,
147 Eldbus_Model_Object_Data *pd)
242{ 148{
243 return pd->type; 149 if (!pd->is_listed && !pd->pendings)
150 _eldbus_model_object_introspect(obj, pd, pd->bus, pd->path);
151 return eina_list_count(pd->childrens);
244} 152}
245 153
246static const char * 154static const char *
@@ -255,105 +163,71 @@ _eldbus_model_object_path_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Dat
255 return pd->path; 163 return pd->path;
256} 164}
257 165
258static void 166static char *
259_eldbus_model_object_connect(Eldbus_Model_Object_Data *pd) 167_eldbus_model_object_concatenate_path(const char *root_path,
168 const char *relative_path)
260{ 169{
261 EINA_SAFETY_ON_NULL_RETURN(pd); 170 Eina_Strbuf *buffer;
262 171 const char *format = (strcmp(root_path, "/") != 0) ? "%s/%s" : "%s%s";
263 if (ELDBUS_CONNECTION_TYPE_ADDRESS == pd->type) 172 char *absolute_path = NULL;
264 {
265 if (pd->private)
266 pd->connection = eldbus_address_connection_get(pd->address);
267 else
268 pd->connection = eldbus_private_address_connection_get(pd->address);
269 }
270 else
271 {
272 if (pd->private)
273 pd->connection = eldbus_private_connection_get(pd->type);
274 else
275 pd->connection = eldbus_connection_get(pd->type);
276 }
277
278 // TODO: Register for disconnection event
279 173
280 EINA_SAFETY_ON_FALSE_RETURN(NULL != pd->connection); 174 buffer = eina_strbuf_new();
281} 175 eina_strbuf_append_printf(buffer, format, root_path, relative_path);
176 absolute_path = eina_strbuf_string_steal(buffer);
282 177
283static void 178 eina_strbuf_free(buffer);
284_eldbus_model_object_disconnect(Eldbus_Model_Object_Data *pd) 179 return absolute_path;
285{
286 EINA_SAFETY_ON_NULL_RETURN(pd);
287 eldbus_connection_unref(pd->connection);
288 pd->connection = NULL;
289} 180}
290 181
291static void 182static void
292_eldbus_model_object_clear(Eldbus_Model_Object_Data *pd) 183_eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *pd,
184 const char *current_path,
185 Eina_List *nodes)
293{ 186{
294 Eldbus_Pending *pending; 187 Eldbus_Introspection_Node *node;
295 Eldbus_Object *object; 188 Eina_List *it;
296 Eo *child;
297
298 EINA_SAFETY_ON_NULL_RETURN(pd);
299 if (!pd->connection)
300 return;
301
302 free(pd->unique_name);
303 pd->unique_name = NULL;
304 189
305 EINA_LIST_FREE(pd->children_list, child) 190 EINA_LIST_FOREACH(nodes, it, node)
306 efl_unref(child); 191 {
192 const char *relative_path;
193 char *absolute_path;
307 194
308 EINA_LIST_FREE(pd->pending_list, pending) 195 relative_path = node->name;
309 eldbus_pending_cancel(pending); 196 if (!relative_path) continue;
310 197
311 if (pd->properties_array) 198 absolute_path = _eldbus_model_object_concatenate_path(current_path, relative_path);
312 { 199 if (!absolute_path) continue;
313 eina_array_free(pd->properties_array);
314 pd->properties_array = NULL;
315 }
316 200
317 EINA_LIST_FREE(pd->object_list, object) 201 _eldbus_model_object_introspect(pd->obj, pd, pd->bus, absolute_path);
318 eldbus_object_unref(object);
319 202
320 if (pd->introspection) 203 free(absolute_path);
321 {
322 eldbus_introspection_node_free(pd->introspection);
323 pd->introspection = NULL;
324 } 204 }
325
326 _eldbus_model_object_disconnect(pd);
327} 205}
328 206
329 207static void
330static bool 208_eldbus_model_object_create_children(Eldbus_Model_Object_Data *pd, Eldbus_Object *object, Eina_List *interfaces)
331_eldbus_model_object_introspect(Eldbus_Model_Object_Data *pd,
332 const char *bus,
333 const char *path)
334{ 209{
335 Eldbus_Object *object; 210 Eldbus_Introspection_Interface *interface;
336 Eldbus_Pending *pending; 211 const char *current_path;
337 212 Eina_List *l;
338 EINA_SAFETY_ON_NULL_RETURN_VAL(bus, false);
339 EINA_SAFETY_ON_NULL_RETURN_VAL(path, false);
340 213
341 DBG("(%p) Introspecting: bus = %s, path = %s", pd->obj, bus, path); 214 current_path = eldbus_object_path_get(object);
215 if (!current_path) return ;
342 216
343 object = eldbus_object_get(pd->connection, bus, path); 217 EINA_LIST_FOREACH(interfaces, l, interface)
344 if (!object)
345 { 218 {
346 ERR("(%p): Cannot get object: bus=%s, path=%s", pd->obj, bus, path); 219 Eo *child;
347 return false;
348 }
349 pd->object_list = eina_list_append(pd->object_list, object);
350 220
351 // TODO: Register for interface added/removed event 221 DBG("(%p) Creating child: bus = %s, path = %s, interface = %s",
222 pd->obj, pd->bus, current_path, interface->name);
352 223
353 pending = eldbus_object_introspect(object, &_eldbus_model_object_introspect_cb, pd); 224 // TODO: increment reference to keep 'interface' in memory
354 eldbus_pending_data_set(pending, "object", object); 225 child = efl_add_ref(ELDBUS_MODEL_PROXY_CLASS, pd->obj,
355 pd->pending_list = eina_list_append(pd->pending_list, pending); 226 eldbus_model_proxy_object_set(efl_added, object),
356 return true; 227 eldbus_model_proxy_interface_set(efl_added, interface));
228
229 if (child) pd->childrens = eina_list_append(pd->childrens, child);
230 }
357} 231}
358 232
359static void 233static void
@@ -362,12 +236,15 @@ _eldbus_model_object_introspect_cb(void *data,
362 Eldbus_Pending *pending) 236 Eldbus_Pending *pending)
363{ 237{
364 Eldbus_Model_Object_Data *pd = (Eldbus_Model_Object_Data*)data; 238 Eldbus_Model_Object_Data *pd = (Eldbus_Model_Object_Data*)data;
239 Eldbus_Children_Slice_Promise* slice;
365 Eldbus_Object *object; 240 Eldbus_Object *object;
366 const char *error_name, *error_text; 241 const char *error_name;
242 const char *error_text;
367 const char *xml = NULL; 243 const char *xml = NULL;
368 const char *current_path; 244 const char *current_path;
245 unsigned int count;
369 246
370 pd->pending_list = eina_list_remove(pd->pending_list, pending); 247 pd->pendings = eina_list_remove(pd->pendings, pending);
371 object = eldbus_pending_data_get(pending, "object"); 248 object = eldbus_pending_data_get(pending, "object");
372 249
373 if (eldbus_message_error_get(msg, &error_name, &error_text)) 250 if (eldbus_message_error_get(msg, &error_name, &error_text))
@@ -382,114 +259,36 @@ _eldbus_model_object_introspect_cb(void *data,
382 ERR("Error getting arguments."); 259 ERR("Error getting arguments.");
383 return; 260 return;
384 } 261 }
385 EINA_SAFETY_ON_NULL_RETURN(xml); 262
263 if (!xml)
264 {
265 ERR("No XML.");
266 return ;
267 }
386 268
387 current_path = eldbus_object_path_get(object); 269 current_path = eldbus_object_path_get(object);
388 EINA_SAFETY_ON_NULL_RETURN(current_path); 270 pd->introspection = eldbus_introspection_parse(xml);
389 271
390 DBG("(%p): introspect of bus = %s, path = %s =>\n%s", pd->obj, pd->bus, current_path, xml); 272 DBG("(%p): introspect of bus = %s, path = %s =>\n%s", pd->obj, pd->bus, current_path, xml);
391 273
392 pd->introspection = eldbus_introspection_parse(xml);
393 EINA_SAFETY_ON_NULL_RETURN(pd->introspection);
394
395 _eldbus_model_object_introspect_nodes(pd, current_path, pd->introspection->nodes); 274 _eldbus_model_object_introspect_nodes(pd, current_path, pd->introspection->nodes);
396 _eldbus_model_object_create_children(pd, object, pd->introspection->interfaces); 275 _eldbus_model_object_create_children(pd, object, pd->introspection->interfaces);
397 276
398 if (eina_list_count(pd->pending_list) == 0) 277 if (eina_list_count(pd->pendings) != 0) return ;
399 {
400 Eina_List* i;
401
402 pd->is_listed = EINA_TRUE;
403 _Eldbus_Children_Slice_Promise* p;
404 EINA_LIST_FOREACH(pd->children_promises, i, p)
405 {
406 Eina_Accessor* ac = efl_model_list_slice(pd->children_list, p->start, p->count);
407 efl_promise_value_set(p->promise, ac, (Eina_Free_Cb)&eina_accessor_free);
408 free(p);
409 }
410 pd->children_promises = eina_list_free(pd->children_promises);
411
412 Efl_Promise *ep;
413 EINA_LIST_FOREACH(pd->count_promises, i, ep)
414 {
415 unsigned *c = calloc(sizeof(unsigned), 1);
416 *c = eina_list_count(pd->children_list);
417 efl_promise_value_set(ep, c, free);
418 }
419 pd->count_promises = eina_list_free(pd->count_promises);
420 278
421 } 279 count = eina_list_count(pd->childrens);
422} 280 efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
423 281
424static void 282 pd->is_listed = EINA_TRUE;
425_eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *pd, const char *current_path, Eina_List *nodes)
426{
427 Eina_List *it;
428 Eldbus_Introspection_Node *node;
429
430 EINA_SAFETY_ON_NULL_RETURN(pd);
431 EINA_SAFETY_ON_NULL_RETURN(current_path);
432
433 EINA_LIST_FOREACH(nodes, it, node)
434 {
435 const char *relative_path;
436 char *absolute_path;
437
438 relative_path = node->name;
439 if (!relative_path) continue;
440
441 absolute_path = _eldbus_model_object_concatenate_path(current_path, relative_path);
442 if (!absolute_path) continue;
443
444 _eldbus_model_object_introspect(pd, pd->bus, absolute_path);
445
446 free(absolute_path);
447 }
448}
449
450static char *
451_eldbus_model_object_concatenate_path(const char *root_path, const char *relative_path)
452{
453 Eina_Strbuf *buffer;
454 char *absolute_path = NULL;
455 Eina_Bool ret;
456
457 buffer = eina_strbuf_new();
458 EINA_SAFETY_ON_NULL_RETURN_VAL(buffer, NULL);
459
460 ret = eina_strbuf_append(buffer, root_path);
461 if (strcmp(root_path, "/") != 0)
462 ret = ret && eina_strbuf_append_char(buffer, '/');
463 ret = ret && eina_strbuf_append(buffer, relative_path);
464 EINA_SAFETY_ON_FALSE_GOTO(ret, free_buffer);
465
466 absolute_path = eina_strbuf_string_steal(buffer);
467
468free_buffer:
469 eina_strbuf_free(buffer);
470 return absolute_path;
471}
472 283
473static void 284 EINA_LIST_FREE(pd->requests, slice)
474_eldbus_model_object_create_children(Eldbus_Model_Object_Data *pd, Eldbus_Object *object, Eina_List *interfaces)
475{
476 Eldbus_Introspection_Interface *interface;
477 Eina_List *it;
478 const char *current_path;
479
480 current_path = eldbus_object_path_get(object);
481 EINA_SAFETY_ON_NULL_RETURN(current_path);
482
483 EINA_LIST_FOREACH(interfaces, it, interface)
484 { 285 {
485 Eo *child; 286 Eina_Value v;
486 287
487 DBG("(%p) Creating child: bus = %s, path = %s, interface = %s", pd->obj, pd->bus, current_path, interface->name); 288 v = efl_model_list_value_get(pd->childrens, slice->start, slice->count);
488 289 eina_promise_resolve(slice->p, v);
489 // TODO: increment reference to keep 'interface' in memory
490 child = efl_add_ref(ELDBUS_MODEL_PROXY_CLASS, pd->obj, eldbus_model_proxy_custom_constructor(efl_added, object, interface));
491 290
492 pd->children_list = eina_list_append(pd->children_list, child); 291 free(slice);
493 } 292 }
494} 293}
495 294
diff --git a/src/lib/eldbus/eldbus_model_object.eo b/src/lib/eldbus/eldbus_model_object.eo
index 6123d3a..806af54 100644
--- a/src/lib/eldbus/eldbus_model_object.eo
+++ b/src/lib/eldbus/eldbus_model_object.eo
@@ -1,63 +1,22 @@
1import eldbus_types; 1import eldbus_types;
2 2
3class Eldbus.Model.Object (Efl.Object, Efl.Model) { 3class Eldbus.Model.Object (Eldbus.Model) {
4 [[Eldbus model object class]] 4 [[Eldbus model object class]]
5 5
6 data: Eldbus_Model_Object_Data; 6 data: Eldbus_Model_Object_Data;
7 methods { 7 methods {
8 custom_constructor { 8 @property bus {
9 [[Custom Eldbus_Model_Object constructor.
10
11 @since 1.16]]
12 params {
13 @in type: Eldbus.Connection.Type; [[The connection type]]
14 @in address: string; [[Remote address of DBus]]
15 @in private_: bool; [[Non shared DBus connection]]
16 @in bus: string; [[DBus Name or unique-id]]
17 @in path: string; [[DBus path]]
18 }
19 }
20 connection_constructor {
21 [[Custom Eldbus_Model_Object connection_constructor.
22
23 @since 1.16]]
24 params {
25 @in connection: ptr(Eldbus.Connection); [[Eldbus connection]]
26 @in bus: string; [[DBus Name or unique-id]]
27 @in path: string; [[DBus path]]
28 }
29 }
30 @property type {
31 [[Connection type]]
32 get { }
33 values {
34 type: Eldbus.Connection.Type; [[Connection type]]
35 }
36 }
37 @property address {
38 [[Remote address of DBus]]
39 get { }
40 values {
41 address: string; [[Address]]
42 }
43 }
44 @property private {
45 [[Indicate if the DBus connection is shared or private]]
46 get { }
47 values {
48 private_: bool; [[Private DBus connection]]
49 }
50 }
51 @property bus {
52 [[DBus Name or unique-id]] 9 [[DBus Name or unique-id]]
53 get { } 10 get { }
11 set { }
54 values { 12 values {
55 bus: string; [[DBus name]] 13 bus: string; [[DBus name]]
56 } 14 }
57 } 15 }
58 @property path { 16 @property path {
59 [[DBus path]] 17 [[DBus path]]
60 get { } 18 get { }
19 set { }
61 values { 20 values {
62 path: string; [[DBus path]] 21 path: string; [[DBus path]]
63 } 22 }
@@ -65,17 +24,10 @@ class Eldbus.Model.Object (Efl.Object, Efl.Model) {
65 } 24 }
66 implements { 25 implements {
67 Efl.Object.constructor; 26 Efl.Object.constructor;
27 Efl.Object.finalize;
28 Efl.Object.invalidate;
68 Efl.Object.destructor; 29 Efl.Object.destructor;
69 Efl.Model.properties { get; }
70 Efl.Model.property_set;
71 Efl.Model.property_get;
72 Efl.Model.child_add;
73 Efl.Model.child_del;
74 Efl.Model.children_slice_get; 30 Efl.Model.children_slice_get;
75 Efl.Model.children_count_get; 31 Efl.Model.children_count { get; }
76 }
77 constructors {
78 .custom_constructor;
79 .connection_constructor;
80 } 32 }
81} 33}
diff --git a/src/lib/eldbus/eldbus_model_object_private.h b/src/lib/eldbus/eldbus_model_object_private.h
index 4330a2f..6ea2877 100644
--- a/src/lib/eldbus/eldbus_model_object_private.h
+++ b/src/lib/eldbus/eldbus_model_object_private.h
@@ -12,22 +12,18 @@ typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
12struct _Eldbus_Model_Object_Data 12struct _Eldbus_Model_Object_Data
13{ 13{
14 Eo *obj; 14 Eo *obj;
15 Eina_Bool is_listed : 1; 15
16 Eldbus_Connection *connection; 16 Eina_List *objects;
17 Eina_List *object_list; 17 Eina_List *childrens;
18 Eina_Array *properties_array; 18 Eina_List *requests;
19 Eina_List *children_list; 19 Eina_List *pendings;
20 Eina_List *children_promises; 20
21 Eina_List *count_promises;
22 Eldbus_Connection_Type type;
23 Eina_Stringshare *address;
24 bool private;
25 Eina_Stringshare *bus; 21 Eina_Stringshare *bus;
26 Eina_Stringshare *path; 22 Eina_Stringshare *path;
27 char *unique_name; 23
28 Eina_List *pending_list;
29 Eldbus_Introspection_Node *introspection; 24 Eldbus_Introspection_Node *introspection;
25
26 Eina_Bool is_listed : 1;
30}; 27};
31 28
32#endif 29#endif
33
diff --git a/src/lib/eldbus/eldbus_model_private.h b/src/lib/eldbus/eldbus_model_private.h
index b5f3610..5b155a1 100644
--- a/src/lib/eldbus/eldbus_model_private.h
+++ b/src/lib/eldbus/eldbus_model_private.h
@@ -8,19 +8,28 @@
8#include <Eo.h> 8#include <Eo.h>
9#include <Efl.h> 9#include <Efl.h>
10 10
11typedef struct _Eldbus_Children_Slice_Promise _Eldbus_Children_Slice_Promise; 11typedef struct _Eldbus_Children_Slice_Promise Eldbus_Children_Slice_Promise;
12typedef struct _Eldbus_Model_Data Eldbus_Model_Data;
13
12struct _Eldbus_Children_Slice_Promise 14struct _Eldbus_Children_Slice_Promise
13{ 15{
14 unsigned start; 16 Eina_Promise *p;
15 unsigned count; 17
16 Efl_Promise* promise; 18 unsigned int start;
19 unsigned int count;
17}; 20};
18 21
19typedef struct _Eldbus_Property_Promise _Eldbus_Property_Promise; 22struct _Eldbus_Model_Data
20struct _Eldbus_Property_Promise
21{ 23{
22 char *property; 24 Eldbus_Connection *connection;
23 Efl_Promise* promise; 25 Eldbus_Connection_Type type;
26
27 Eina_Stringshare *address;
28 Eina_Stringshare *unique_name;
29
30 Eina_Bool private : 1;
31
32 Eina_Bool is_listed : 1;
24}; 33};
25 34
26#define UNIQUE_NAME_PROPERTY "unique_name" 35#define UNIQUE_NAME_PROPERTY "unique_name"
@@ -28,6 +37,12 @@ struct _Eldbus_Property_Promise
28/* logging support */ 37/* logging support */
29extern int eldbus_model_log_dom; 38extern int eldbus_model_log_dom;
30 39
40static inline void
41_eldbus_eina_promise_cancel(void *data EINA_UNUSED,
42 const Eina_Promise *dead_ptr EINA_UNUSED)
43{
44}
45
31#define ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(exp, promise, err, v) \ 46#define ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(exp, promise, err, v) \
32 do \ 47 do \
33 { \ 48 { \
diff --git a/src/lib/eldbus/eldbus_model_proxy.c b/src/lib/eldbus/eldbus_model_proxy.c
index 586dfbb..229bcc0 100644
--- a/src/lib/eldbus/eldbus_model_proxy.c
+++ b/src/lib/eldbus/eldbus_model_proxy.c
@@ -10,40 +10,96 @@
10#define MY_CLASS ELDBUS_MODEL_PROXY_CLASS 10#define MY_CLASS ELDBUS_MODEL_PROXY_CLASS
11#define MY_CLASS_NAME "Eldbus_Model_Proxy" 11#define MY_CLASS_NAME "Eldbus_Model_Proxy"
12 12
13static Eina_Bool _eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *);
14static void _eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *);
15static void _eldbus_model_proxy_property_get_all_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 13static void _eldbus_model_proxy_property_get_all_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
16static void _eldbus_model_proxy_property_set_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 14static void _eldbus_model_proxy_property_set_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
17static void _eldbus_model_proxy_property_set_load_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 15static void _eldbus_model_proxy_property_set_load_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
18static void _eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *); 16static void _eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *);
19static void _eldbus_model_proxy_stop_monitor(Eldbus_Model_Proxy_Data *);
20static void _eldbus_model_proxy_property_changed_cb(void *, Eldbus_Proxy *, void *); 17static void _eldbus_model_proxy_property_changed_cb(void *, Eldbus_Proxy *, void *);
21static void _eldbus_model_proxy_property_invalidated_cb(void *, Eldbus_Proxy *, void *); 18static void _eldbus_model_proxy_property_invalidated_cb(void *, Eldbus_Proxy *, void *);
22static bool _eldbus_model_proxy_is_property_writeable(Eldbus_Model_Proxy_Data *, const char *);
23static bool _eldbus_model_proxy_has_property(Eldbus_Model_Proxy_Data *, const char *);
24static bool _eldbus_model_proxy_is_property_readable(Eldbus_Model_Proxy_Data *, const char *);
25static const char *_eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *, const char *); 19static const char *_eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *, const char *);
26static void _eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *); 20static void _eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *);
27static void _eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *); 21static void _eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *);
28 22
29 23
30typedef struct _Eldbus_Model_Proxy_Property_Set_Data Eldbus_Model_Proxy_Property_Set_Data; 24typedef struct _Eldbus_Model_Proxy_Property_Set_Data Eldbus_Model_Proxy_Property_Set_Data;
25typedef struct _Eldbus_Property_Promise Eldbus_Property_Promise;
31 26
32struct _Eldbus_Model_Proxy_Property_Set_Data 27struct _Eldbus_Model_Proxy_Property_Set_Data
33{ 28{
34 Eldbus_Model_Proxy_Data *pd; 29 Eldbus_Model_Proxy_Data *pd;
30
35 Eina_Stringshare *property; 31 Eina_Stringshare *property;
36 Eina_Value value; 32 Eina_Promise *promise;
37 Efl_Promise *promise; 33 Eina_Value *value;
34};
35
36struct _Eldbus_Property_Promise
37{
38 Eina_Promise *promise;
39 Eina_Stringshare *property;
38}; 40};
39 41
40static Eldbus_Model_Proxy_Property_Set_Data * _eldbus_model_proxy_property_set_data_new(Eldbus_Model_Proxy_Data *, const char *, const Eina_Value *, Efl_Promise *promise);
41static void _eldbus_model_proxy_property_set_data_free(Eldbus_Model_Proxy_Property_Set_Data *); 42static void _eldbus_model_proxy_property_set_data_free(Eldbus_Model_Proxy_Property_Set_Data *);
42 43
44static Eina_Bool
45_eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *pd)
46{
47 Eldbus_Introspection_Property *property;
48 Eina_List *it;
49
50 if (pd->proxy)
51 return EINA_TRUE;
52
53 pd->proxy = eldbus_proxy_get(pd->object, pd->name);
54 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->proxy, EINA_FALSE);
55
56 EINA_LIST_FOREACH(pd->interface->properties, it, property)
57 {
58 const Eina_Value_Type *type;
59 Eina_Stringshare *name;
60 Eina_Value *value;
61
62 type = _dbus_type_to_eina_value_type(property->type[0]);
63 name = eina_stringshare_add(property->name);
64 value = eina_value_new(type);
65
66 eina_hash_direct_add(pd->properties, name, value);
67 }
68
69 return EINA_TRUE;
70}
71
43static void 72static void
44_eldbus_model_proxy_hash_free(Eina_Value *value) 73_eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *pd)
45{ 74{
46 eina_value_free(value); 75 Eldbus_Pending *pending;
76
77 EINA_LIST_FREE(pd->pendings, pending)
78 eldbus_pending_cancel(pending);
79
80 if (pd->monitoring)
81 {
82 eldbus_proxy_event_callback_del(pd->proxy,
83 ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
84 _eldbus_model_proxy_property_changed_cb,
85 pd);
86 eldbus_proxy_event_callback_del(pd->proxy,
87 ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
88 _eldbus_model_proxy_property_invalidated_cb,
89 pd);
90 }
91 pd->monitoring = EINA_FALSE;
92
93 if (pd->proxy) eldbus_proxy_unref(pd->proxy);
94 pd->proxy = NULL;
95}
96
97static void
98_eldbus_model_proxy_object_del(void *data, Eldbus_Object *object EINA_UNUSED, void *event_info EINA_UNUSED)
99{
100 Eldbus_Model_Proxy_Data *pd = data;
101
102 pd->object = NULL;
47} 103}
48 104
49static Efl_Object* 105static Efl_Object*
@@ -52,241 +108,304 @@ _eldbus_model_proxy_efl_object_constructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
52 obj = efl_constructor(efl_super(obj, MY_CLASS)); 108 obj = efl_constructor(efl_super(obj, MY_CLASS));
53 109
54 pd->obj = obj; 110 pd->obj = obj;
55 pd->object = NULL; 111 pd->properties = eina_hash_stringshared_new(NULL);
56 pd->proxy = NULL;
57 pd->is_listed = pd->is_loaded = EINA_FALSE;
58 pd->properties_array = NULL;
59 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_proxy_hash_free));
60 pd->children_list = NULL;
61 pd->name = NULL;
62 pd->pending_list = NULL;
63 pd->promise_list = NULL;
64 pd->monitoring = false;
65 pd->interface = NULL;
66 112
67 return obj; 113 return obj;
68} 114}
69 115
70static void 116static Efl_Object*
71_eldbus_model_proxy_object_del(void *data, Eldbus_Object *object EINA_UNUSED, void *event_info EINA_UNUSED) 117_eldbus_model_proxy_efl_object_finalize(Eo *obj, Eldbus_Model_Proxy_Data *pd)
72{ 118{
73 Eldbus_Model_Proxy_Data *pd = data; 119 if (!pd->object ||
120 !pd->name ||
121 !pd->interface)
122 return NULL;
74 123
75 pd->object = NULL; 124 if (!_eldbus_model_proxy_load(pd)) return NULL;
125
126 if (!eldbus_model_connection_get(obj))
127 eldbus_model_connection_set(obj, eldbus_object_connection_get(pd->object));
128
129 eldbus_object_event_callback_add(pd->object, ELDBUS_OBJECT_EVENT_DEL, _eldbus_model_proxy_object_del, pd);
130
131 return efl_finalize(efl_super(obj, MY_CLASS));
76} 132}
77 133
78static void 134static void
79_eldbus_model_proxy_custom_constructor(Eo *obj EINA_UNUSED, 135_eldbus_model_proxy_object_set(Eo *obj EINA_UNUSED,
80 Eldbus_Model_Proxy_Data *pd, 136 Eldbus_Model_Proxy_Data *pd,
81 Eldbus_Object *object, 137 Eldbus_Object *object)
82 const Eldbus_Introspection_Interface *interface)
83{ 138{
84 EINA_SAFETY_ON_NULL_RETURN(object);
85 EINA_SAFETY_ON_NULL_RETURN(interface);
86
87 pd->object = eldbus_object_ref(object); 139 pd->object = eldbus_object_ref(object);
88 eldbus_object_event_callback_add(object, ELDBUS_OBJECT_EVENT_DEL, _eldbus_model_proxy_object_del, pd); 140}
141
142static void
143_eldbus_model_proxy_interface_set(Eo *obj EINA_UNUSED,
144 Eldbus_Model_Proxy_Data *pd,
145 const Eldbus_Introspection_Interface *interface)
146{
89 pd->name = eina_stringshare_add(interface->name); 147 pd->name = eina_stringshare_add(interface->name);
90 pd->interface = interface; 148 pd->interface = interface;
91} 149}
92 150
93static void 151static void
94_eldbus_model_proxy_efl_object_destructor(Eo *obj, Eldbus_Model_Proxy_Data *pd) 152_eldbus_model_proxy_efl_object_invalidate(Eo *obj, Eldbus_Model_Proxy_Data *pd)
95{ 153{
96 _eldbus_model_proxy_unload(pd); 154 Eo *child;
97 155
98 eina_hash_free(pd->properties_hash); 156 EINA_LIST_FREE(pd->childrens, child)
157 efl_unref(child);
158
159 _eldbus_model_proxy_unload(pd);
99 160
100 eina_stringshare_del(pd->name);
101 if (pd->object) 161 if (pd->object)
102 { 162 {
103 eldbus_object_event_callback_del(pd->object, ELDBUS_OBJECT_EVENT_DEL, _eldbus_model_proxy_object_del, pd); 163 eldbus_object_event_callback_del(pd->object, ELDBUS_OBJECT_EVENT_DEL, _eldbus_model_proxy_object_del, pd);
104 eldbus_object_unref(pd->object); 164 eldbus_object_unref(pd->object);
105 } 165 }
106 166
167 efl_invalidate(efl_super(obj, MY_CLASS));
168}
169
170static void
171_eldbus_model_proxy_efl_object_destructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
172{
173 Eina_Hash_Tuple *tuple;
174 Eina_Iterator *it;
175
176 it = eina_hash_iterator_tuple_new(pd->properties);
177 EINA_ITERATOR_FOREACH(it, tuple)
178 {
179 Eina_Stringshare *property = tuple->key;
180 Eina_Value *value = tuple->data;
181
182 eina_stringshare_del(property);
183 eina_value_free(value);
184 }
185 eina_iterator_free(it);
186 eina_hash_free(pd->properties);
187
188 eina_stringshare_del(pd->name);
189
107 efl_destructor(efl_super(obj, MY_CLASS)); 190 efl_destructor(efl_super(obj, MY_CLASS));
108} 191}
109 192
110static Eina_Array const * 193static Eina_Array *
111_eldbus_model_proxy_efl_model_properties_get(const Eo *obj EINA_UNUSED, 194_eldbus_model_proxy_efl_model_properties_get(const Eo *obj EINA_UNUSED,
112 Eldbus_Model_Proxy_Data *pd) 195 Eldbus_Model_Proxy_Data *pd)
113{ 196{
114 Eina_Bool ret; 197 Eina_Iterator *it;
198 Eina_Array *r;
199 Eina_Stringshare *property;
200
201 r = eina_array_new(4);
115 202
116 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL); 203 it = eina_hash_iterator_key_new(pd->properties);
204 EINA_ITERATOR_FOREACH(it, property)
205 eina_array_push(r, property);
206 eina_iterator_free(it);
117 207
118 ret = _eldbus_model_proxy_load(pd); 208 return r;
119 if (!ret) return NULL; 209}
210
211#define PROPERTY_EXIST 1
212#define PROPERTY_READ 2
213#define PROPERTY_WRITE 4
214
215static unsigned char
216eldbus_model_proxy_property_check(Eldbus_Model_Proxy_Data *pd,
217 const char *property)
218{
219 Eldbus_Introspection_Property *property_introspection =
220 eldbus_introspection_property_find(pd->interface->properties, property);
221 unsigned char r = 0;
222
223 if (property_introspection == NULL)
224 {
225 WRN("Property not found: %s", property);
226 return 0;
227 }
228
229 r = PROPERTY_EXIST;
230 // Check read access
231 if (property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READ ||
232 property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE)
233 r |= PROPERTY_READ;
234 // Check write access
235 if (property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_WRITE ||
236 property_introspection->access == ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE)
237 r |= PROPERTY_WRITE;
238
239 return r;
240}
120 241
121 return pd->properties_array; 242static void
243_eldbus_model_proxy_cancel_cb(void *data,
244 const Eina_Promise *dead_promise EINA_UNUSED)
245{
246 Eldbus_Model_Proxy_Property_Set_Data *sd = data;
247
248 sd->promise = NULL;
249}
250
251static Eldbus_Pending *
252_eldbus_model_proxy_load_all(Eldbus_Model_Proxy_Data *pd,
253 Eina_Promise *promise, const char *property,
254 Eldbus_Message_Cb callback,
255 void *data)
256{
257 Eldbus_Property_Promise *p;
258 Eldbus_Pending *pending = NULL;
259
260 p = calloc(1, sizeof(Eldbus_Property_Promise));
261 if (!p)
262 {
263 if (promise) eina_promise_reject(promise, ENOMEM);
264 return NULL;
265 }
266
267 p->promise = promise;
268 p->property = eina_stringshare_add(property);
269 pd->promises = eina_list_append(pd->promises, p);
270
271 if (!pd->pendings)
272 {
273 pending = eldbus_proxy_property_get_all(pd->proxy, callback, data);
274 }
275 return pending;
122} 276}
123 277
124static Efl_Future* 278static Eina_Future *
125_eldbus_model_proxy_efl_model_property_set(Eo *obj EINA_UNUSED, 279_eldbus_model_proxy_efl_model_property_set(Eo *obj EINA_UNUSED,
126 Eldbus_Model_Proxy_Data *pd, 280 Eldbus_Model_Proxy_Data *pd,
127 const char *property, 281 const char *property,
128 Eina_Value const* value) 282 Eina_Value *value)
129{ 283{
130 Eldbus_Model_Proxy_Property_Set_Data *data; 284 Eldbus_Model_Proxy_Property_Set_Data *data;
131 const char *signature; 285 const char *signature;
132 Eldbus_Pending *pending; 286 Eldbus_Pending *pending;
133 Eina_Bool ret; 287 unsigned char access;
134 Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj); 288 Eina_Error err = 0;
135 Efl_Future* future = efl_promise_future_get(promise);
136
137 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
138 289
139 DBG("(%p): property=%s", obj, property); 290 DBG("(%p): property=%s", obj, property);
140 ret = _eldbus_model_proxy_load(pd);
141 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED, future);
142
143 ret = _eldbus_model_proxy_has_property(pd, property);
144 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
145 291
146 ret = _eldbus_model_proxy_is_property_writeable(pd, property); 292 access = eldbus_model_proxy_property_check(pd, property);
147 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY, future); 293 err = EFL_MODEL_ERROR_NOT_FOUND;
294 if (!access) goto on_error;
295 err = EFL_MODEL_ERROR_READ_ONLY;
296 if (!(access & PROPERTY_WRITE)) goto on_error;
148 297
298 err = EFL_MODEL_ERROR_UNKNOWN;
149 signature = _eldbus_model_proxy_property_type_get(pd, property); 299 signature = _eldbus_model_proxy_property_type_get(pd, property);
150 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(signature, promise, EFL_MODEL_ERROR_UNKNOWN, future); 300 if (!signature) goto on_error;
151 301
152 data = _eldbus_model_proxy_property_set_data_new(pd, property, value, promise); 302 err = ENOMEM;
153 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(data, promise, EFL_MODEL_ERROR_UNKNOWN, future); 303 data = calloc(1, sizeof (Eldbus_Model_Proxy_Property_Set_Data));
304 if (!data) goto on_error;
305
306 data->pd = pd;
307 data->promise = eina_promise_new(efl_loop_future_scheduler_get(obj),
308 _eldbus_model_proxy_cancel_cb, data);
309 data->property = eina_stringshare_add(property);
310 if (!(data->value = eina_value_dup(value))) goto on_error;
154 311
155 if (!pd->is_loaded) 312 if (!pd->is_loaded)
156 { 313 {
157 _Eldbus_Property_Promise *p = calloc(1, sizeof(_Eldbus_Property_Promise)); 314 pending = _eldbus_model_proxy_load_all(pd, data->promise, property,
158 EINA_SAFETY_ON_NULL_RETURN_VAL(p, future); 315 _eldbus_model_proxy_property_set_load_cb, data);
159 316 }
160 p->promise = promise; 317 else
161 p->property = strdup(property); 318 {
162 pd->promise_list = eina_list_append(pd->promise_list, p); 319 pending = eldbus_proxy_property_value_set(pd->proxy, property, signature, (Eina_Value*)value,
163 320 _eldbus_model_proxy_property_set_cb, data);
164 if (!pd->pending_list)
165 {
166 pending = eldbus_proxy_property_get_all(pd->proxy, _eldbus_model_proxy_property_set_load_cb, data);
167 pd->pending_list = eina_list_append(pd->pending_list, pending);
168 }
169 return future;
170 } 321 }
171 322
172 pending = eldbus_proxy_property_value_set 323 if (pending) pd->pendings = eina_list_append(pd->pendings, pending);
173 (pd->proxy, property, signature, (Eina_Value*)value, _eldbus_model_proxy_property_set_cb, data); 324 return efl_future_Eina_FutureXXX_then(obj, eina_future_new(data->promise));
174 pd->pending_list = eina_list_append(pd->pending_list, pending); 325
175 return future; 326 on_error:
327 return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
176} 328}
177 329
178static Efl_Future* 330static Eina_Value *
179_eldbus_model_proxy_efl_model_property_get(Eo *obj EINA_UNUSED, 331_eldbus_model_proxy_efl_model_property_get(const Eo *obj EINA_UNUSED,
180 Eldbus_Model_Proxy_Data *pd, 332 Eldbus_Model_Proxy_Data *pd,
181 const char *property) 333 const char *property)
182{ 334{
183 Eina_Bool ret; 335 Eldbus_Pending *pending;
184 Eina_Value *promise_value; 336 unsigned char access;
185 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj); 337 Eina_Error err = 0;
186 Efl_Future *future = efl_promise_future_get(promise);
187 338
188 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future); 339 access = eldbus_model_proxy_property_check(pd, property);
340 err = EFL_MODEL_ERROR_NOT_FOUND;
341 if (!access) goto on_error;
342 if (!(access & PROPERTY_READ)) goto on_error;
189 343
190 ret = _eldbus_model_proxy_load(pd); 344 if (pd->is_loaded)
191 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED, future); 345 {
346 Eina_Stringshare *tmp;
347 Eina_Value *value;
192 348
193 ret = _eldbus_model_proxy_has_property(pd, property); 349 err = EFL_MODEL_ERROR_NOT_FOUND;
194 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_NOT_FOUND, future); 350 tmp = eina_stringshare_add(property);
351 value = eina_hash_find(pd->properties, tmp);
352 eina_stringshare_del(tmp);
353 if (!value) goto on_error;
195 354
196 if (!pd->is_loaded) 355 return eina_value_dup(value);
197 {
198 Eldbus_Pending *pending;
199 _Eldbus_Property_Promise *p = calloc(1, sizeof(_Eldbus_Property_Promise));
200 EINA_SAFETY_ON_NULL_RETURN_VAL(p, future);
201
202 p->promise = promise;
203 p->property = strdup(property);
204 pd->promise_list = eina_list_append(pd->promise_list, p);
205
206 if (!pd->pending_list)
207 {
208 pending = eldbus_proxy_property_get_all(pd->proxy, _eldbus_model_proxy_property_get_all_cb, pd);
209 pd->pending_list = eina_list_append(pd->pending_list, pending);
210 }
211 return future;
212 } 356 }
213 357
214 Eina_Value* value = eina_hash_find(pd->properties_hash, property); 358 err = ENOMEM;
215 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
216 359
217 ret = _eldbus_model_proxy_is_property_writeable(pd, property); 360 pending = _eldbus_model_proxy_load_all(pd, NULL, property,
218 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY, future); 361 _eldbus_model_proxy_property_get_all_cb, pd);
362 if (pending) pd->pendings = eina_list_append(pd->pendings, pending);
363 else goto on_error;
219 364
220 promise_value = eina_value_new(eina_value_type_get(value)); 365 return eina_value_error_new(EAGAIN);
221 eina_value_copy(value, promise_value);
222 efl_promise_value_set(promise, promise_value, (Eina_Free_Cb)&eina_value_free);
223 return future;
224}
225 366
226static Eo * 367 on_error:
227_eldbus_model_proxy_efl_model_child_add(Eo *obj EINA_UNUSED, 368 return eina_value_error_new(err);
228 Eldbus_Model_Proxy_Data *pd EINA_UNUSED)
229{
230 return NULL;
231} 369}
232 370
233static void 371static void
234_eldbus_model_proxy_efl_model_child_del(Eo *obj EINA_UNUSED, 372_eldbus_model_proxy_listed(Eldbus_Model_Proxy_Data *pd)
235 Eldbus_Model_Proxy_Data *pd EINA_UNUSED,
236 Eo *child EINA_UNUSED)
237{ 373{
238}
239
240static Efl_Future*
241_eldbus_model_proxy_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
242 Eldbus_Model_Proxy_Data *pd,
243 unsigned start,
244 unsigned count)
245{
246 Eina_Bool ret = _eldbus_model_proxy_load(pd);
247 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
248 Efl_Future *future = efl_promise_future_get(promise);
249 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED, future);
250
251 if (!pd->is_listed) 374 if (!pd->is_listed)
252 { 375 {
253 _eldbus_model_proxy_create_methods_children(pd); 376 _eldbus_model_proxy_create_methods_children(pd);
254 _eldbus_model_proxy_create_signals_children(pd); 377 _eldbus_model_proxy_create_signals_children(pd);
255 pd->is_listed = EINA_TRUE; 378 pd->is_listed = EINA_TRUE;
256 } 379 }
257
258 Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
259 efl_promise_value_set(promise, ac, (Eina_Free_Cb)&eina_accessor_free);
260 return future;
261} 380}
262 381
263static Efl_Future* 382static Eina_Future*
264_eldbus_model_proxy_efl_model_children_count_get(Eo *obj EINA_UNUSED, 383_eldbus_model_proxy_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
265 Eldbus_Model_Proxy_Data *pd) 384 Eldbus_Model_Proxy_Data *pd,
385 unsigned start,
386 unsigned count)
266{ 387{
267 Eina_Bool ret = _eldbus_model_proxy_load(pd); 388 Eina_Value v;
268 Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
269 Efl_Future *future = efl_promise_future_get(promise);
270 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED, future);
271 389
272 if (!pd->is_listed) 390 _eldbus_model_proxy_listed(pd);
273 {
274 _eldbus_model_proxy_create_methods_children(pd);
275 _eldbus_model_proxy_create_signals_children(pd);
276 pd->is_listed = EINA_TRUE;
277 }
278 391
279 unsigned int *c = calloc(sizeof(unsigned int), 1); 392 v = efl_model_list_value_get(pd->childrens, start, count);
280 *c = eina_list_count(pd->children_list); 393 return eina_future_resolved(efl_loop_future_scheduler_get(obj), v);
281 efl_promise_value_set(promise, c, free); 394}
282 return future; 395
396static unsigned int
397_eldbus_model_proxy_efl_model_children_count_get(const Eo *obj EINA_UNUSED,
398 Eldbus_Model_Proxy_Data *pd)
399{
400 _eldbus_model_proxy_listed(pd);
401 return eina_list_count(pd->childrens);
283} 402}
284 403
285static void 404static void
286_eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *pd) 405_eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *pd)
287{ 406{
288 Eina_List *it;
289 Eldbus_Introspection_Method *method; 407 Eldbus_Introspection_Method *method;
408 Eina_List *it;
290 409
291 EINA_LIST_FOREACH(pd->interface->methods, it, method) 410 EINA_LIST_FOREACH(pd->interface->methods, it, method)
292 { 411 {
@@ -311,9 +430,13 @@ _eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *pd)
311 INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s", 430 INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s",
312 pd->obj, bus, path, interface_name, method_name); 431 pd->obj, bus, path, interface_name, method_name);
313 432
314 child = efl_add(ELDBUS_MODEL_METHOD_CLASS, pd->obj, eldbus_model_method_constructor(efl_added, pd->proxy, method)); 433 child = efl_add_ref(ELDBUS_MODEL_METHOD_CLASS, pd->obj,
434 eldbus_model_method_proxy_set(efl_added, pd->proxy),
435 eldbus_model_method_set(efl_added, method));
315 436
316 pd->children_list = eina_list_append(pd->children_list, child); 437 if (child) pd->childrens = eina_list_append(pd->childrens, child);
438 else ERR("Could not create method child: bus = %s, path = %s method = %s::%s.",
439 bus, path, interface_name, method_name);
317 } 440 }
318} 441}
319 442
@@ -346,9 +469,11 @@ _eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *pd)
346 DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s", 469 DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s",
347 pd->obj, bus, path, interface_name, signal_name); 470 pd->obj, bus, path, interface_name, signal_name);
348 471
349 child = efl_add(ELDBUS_MODEL_SIGNAL_CLASS, pd->obj, eldbus_model_signal_constructor(efl_added, pd->proxy, signal)); 472 child = efl_add_ref(ELDBUS_MODEL_SIGNAL_CLASS, pd->obj, eldbus_model_signal_constructor(efl_added, pd->proxy, signal));
350 473
351 pd->children_list = eina_list_append(pd->children_list, child); 474 if (child) pd->childrens = eina_list_append(pd->childrens, child);
475 else ERR("Could not create signal child: bus = %s, path = %s signal = %s::%s.",
476 bus, path, interface_name, signal_name);
352 } 477 }
353} 478}
354 479
@@ -358,90 +483,13 @@ _eldbus_model_proxy_proxy_name_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Proxy
358 return pd->name; 483 return pd->name;
359} 484}
360 485
361static Eina_Bool
362_eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *pd)
363{
364 Eldbus_Introspection_Property *property;
365 Eina_List *it;
366
367 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EINA_FALSE);
368
369 if (pd->proxy)
370 return EINA_TRUE;
371
372 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->object, EINA_FALSE);
373 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->name, EINA_FALSE);
374 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->interface, EINA_FALSE);
375
376 pd->proxy = eldbus_proxy_get(pd->object, pd->name);
377 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->proxy, EINA_FALSE);
378
379 const unsigned int properties_count = eina_list_count(pd->interface->properties);
380
381 pd->properties_array = eina_array_new(properties_count);
382 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, EINA_FALSE);
383
384 if (!properties_count) return EINA_TRUE;
385
386 EINA_LIST_FOREACH(pd->interface->properties, it, property)
387 {
388 Eina_Stringshare *name;
389 Eina_Bool ret;
390
391 name = eina_stringshare_add(property->name);
392 ret = eina_array_push(pd->properties_array, name);
393 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EINA_FALSE);
394 }
395
396 return EINA_TRUE;
397}
398
399static void
400_eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *pd)
401{
402 Eldbus_Pending *pending;
403 Eo *child;
404
405 EINA_SAFETY_ON_NULL_RETURN(pd);
406
407 EINA_LIST_FREE(pd->children_list, child)
408 efl_unref(child);
409
410 EINA_LIST_FREE(pd->pending_list, pending)
411 {
412 eldbus_pending_cancel(pending);
413 }
414
415 if (pd->properties_array)
416 {
417 unsigned int i;
418 Eina_Stringshare *property;
419 Eina_Array_Iterator it;
420
421 EINA_ARRAY_ITER_NEXT(pd->properties_array, i, property, it)
422 eina_stringshare_del(property);
423 eina_array_free(pd->properties_array);
424 pd->properties_array = NULL;
425 }
426
427 eina_hash_free_buckets(pd->properties_hash);
428
429 _eldbus_model_proxy_stop_monitor(pd);
430
431 if (pd->proxy)
432 {
433 eldbus_proxy_unref(pd->proxy);
434 pd->proxy = NULL;
435 }
436}
437
438static void 486static void
439_eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *pd) 487_eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *pd)
440{ 488{
441 if (pd->monitoring) 489 if (pd->monitoring)
442 return; 490 return;
443 491
444 pd->monitoring = true; 492 pd->monitoring = EINA_TRUE;
445 493
446 eldbus_proxy_event_callback_add(pd->proxy, 494 eldbus_proxy_event_callback_add(pd->proxy,
447 ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, 495 ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
@@ -455,25 +503,6 @@ _eldbus_model_proxy_start_monitor(Eldbus_Model_Proxy_Data *pd)
455} 503}
456 504
457static void 505static void
458_eldbus_model_proxy_stop_monitor(Eldbus_Model_Proxy_Data *pd)
459{
460 if (!pd->monitoring)
461 return;
462
463 pd->monitoring = false;
464
465 eldbus_proxy_event_callback_del(pd->proxy,
466 ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
467 _eldbus_model_proxy_property_changed_cb,
468 pd);
469
470 eldbus_proxy_event_callback_del(pd->proxy,
471 ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
472 _eldbus_model_proxy_property_invalidated_cb,
473 pd);
474}
475
476static void
477_eldbus_model_proxy_property_changed_cb(void *data, 506_eldbus_model_proxy_property_changed_cb(void *data,
478 Eldbus_Proxy *proxy EINA_UNUSED, 507 Eldbus_Proxy *proxy EINA_UNUSED,
479 void *event_info) 508 void *event_info)
@@ -483,13 +512,13 @@ _eldbus_model_proxy_property_changed_cb(void *data,
483 Eina_Value *prop_value; 512 Eina_Value *prop_value;
484 Eina_Bool ret; 513 Eina_Bool ret;
485 514
486 prop_value = eina_hash_find(pd->properties_hash, event->name); 515 prop_value = eina_hash_find(pd->properties, event->name);
487 if (!prop_value) return ; 516 if (!prop_value) return ;
488 517
489 ret = eina_value_copy(event->value, prop_value); 518 ret = eina_value_copy(event->value, prop_value);
490 if (!ret) return ; 519 if (!ret) return ;
491 520
492 efl_model_property_changed_notify(pd->obj, event->name); 521 efl_model_properties_changed(pd->obj, event->name);
493} 522}
494 523
495static void 524static void
@@ -506,11 +535,9 @@ _eldbus_model_proxy_property_invalidated_cb(void *data,
506static Eina_Array * 535static Eina_Array *
507_eldbus_model_proxy_property_get_all_load(const Eldbus_Message *msg, Eldbus_Model_Proxy_Data *pd) 536_eldbus_model_proxy_property_get_all_load(const Eldbus_Message *msg, Eldbus_Model_Proxy_Data *pd)
508{ 537{
509 Eldbus_Introspection_Property *prop;
510 Eldbus_Message_Iter *values = NULL; 538 Eldbus_Message_Iter *values = NULL;
511 Eldbus_Message_Iter *entry; 539 Eldbus_Message_Iter *entry;
512 Eina_Array *changed_properties; 540 Eina_Array *changed_properties;
513 Eina_List *it;
514 const char *error_name, *error_text; 541 const char *error_name, *error_text;
515 542
516 if (eldbus_message_error_get(msg, &error_name, &error_text)) 543 if (eldbus_message_error_get(msg, &error_name, &error_text))
@@ -525,20 +552,10 @@ _eldbus_model_proxy_property_get_all_load(const Eldbus_Message *msg, Eldbus_Mode
525 return NULL; 552 return NULL;
526 } 553 }
527 554
528 EINA_LIST_FOREACH(pd->interface->properties, it, prop)
529 {
530 const Eina_Value_Type *type;
531 Eina_Value *value;
532
533 type = _dbus_type_to_eina_value_type(prop->type[0]);
534 value = eina_value_new(type);
535
536 eina_hash_add(pd->properties_hash, prop->name, value);
537 }
538
539 changed_properties = eina_array_new(1); 555 changed_properties = eina_array_new(1);
540 while (eldbus_message_iter_get_and_next(values, 'e', &entry)) 556 while (eldbus_message_iter_get_and_next(values, 'e', &entry))
541 { 557 {
558 Eina_Stringshare *tmp;
542 const char *property; 559 const char *property;
543 Eldbus_Message_Iter *variant; 560 Eldbus_Message_Iter *variant;
544 Eina_Value *struct_value; 561 Eina_Value *struct_value;
@@ -550,22 +567,24 @@ _eldbus_model_proxy_property_get_all_load(const Eldbus_Message *msg, Eldbus_Mode
550 continue; 567 continue;
551 568
552 struct_value = eldbus_message_iter_struct_like_to_eina_value(variant); 569 struct_value = eldbus_message_iter_struct_like_to_eina_value(variant);
553 EINA_SAFETY_ON_NULL_GOTO(struct_value, on_error); 570 if (!struct_value) goto on_error;
554 571
555 ret = eina_value_struct_value_get(struct_value, "arg0", &arg0); 572 ret = eina_value_struct_value_get(struct_value, "arg0", &arg0);
556 eina_value_free(struct_value); 573 eina_value_free(struct_value);
557 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error); 574 if (!ret) goto on_error;
558 575
559 prop_value = eina_hash_find(pd->properties_hash, property); 576 tmp = eina_stringshare_add(property);
560 EINA_SAFETY_ON_NULL_GOTO(prop_value, on_error); 577 prop_value = eina_hash_find(pd->properties, tmp);
578 eina_stringshare_del(tmp);
579 if (!prop_value) goto on_error;
561 580
562 ret = eina_value_copy(&arg0, prop_value); 581 ret = eina_value_copy(&arg0, prop_value);
563 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error); 582 if (!ret) goto on_error;
564 583
565 eina_value_flush(&arg0); 584 eina_value_flush(&arg0);
566 585
567 ret = eina_array_push(changed_properties, property); 586 ret = eina_array_push(changed_properties, property);
568 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error); 587 if (!ret) goto on_error;
569 } 588 }
570 589
571 pd->is_loaded = EINA_TRUE; 590 pd->is_loaded = EINA_TRUE;
@@ -577,97 +596,73 @@ _eldbus_model_proxy_property_get_all_load(const Eldbus_Message *msg, Eldbus_Mode
577} 596}
578 597
579static void 598static void
599_eldbus_model_proxy_promise_clean(Eldbus_Property_Promise* p,
600 Eina_Error err)
601{
602 if (p->promise) eina_promise_reject(p->promise, err);
603 eina_stringshare_del(p->property);
604 free(p);
605}
606
607static void
580_eldbus_model_proxy_property_get_all_cb(void *data, 608_eldbus_model_proxy_property_get_all_cb(void *data,
581 const Eldbus_Message *msg, 609 const Eldbus_Message *msg,
582 Eldbus_Pending *pending) 610 Eldbus_Pending *pending)
583{ 611{
584 Eina_Value *promise_value;
585 Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data; 612 Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
613 Eldbus_Property_Promise* p;
614 Eina_Array *properties;
615 Efl_Model_Property_Event evt;
586 616
587 pd->pending_list = eina_list_remove(pd->pending_list, pending); 617 pd->pendings = eina_list_remove(pd->pendings, pending);
588 Eina_Array *changed_properties = _eldbus_model_proxy_property_get_all_load(msg, pd);
589 if (changed_properties == NULL)
590 {
591 Eina_List* i;
592 _Eldbus_Property_Promise* p;
593 EINA_LIST_FOREACH(pd->promise_list, i, p)
594 {
595 efl_promise_failed_set(p->promise, EFL_MODEL_ERROR_NOT_FOUND);
596 free(p->property);
597 }
598 eina_list_free(pd->promise_list);
599 return;
600 }
601 618
602 Eina_List* i; 619 properties = _eldbus_model_proxy_property_get_all_load(msg, pd);
603 _Eldbus_Property_Promise* p; 620 if (!properties)
604 EINA_LIST_FOREACH(pd->promise_list, i, p)
605 { 621 {
606 Eina_Value* value = eina_hash_find(pd->properties_hash, p->property); 622 EINA_LIST_FREE(pd->promises, p)
607 if (!value) 623 _eldbus_model_proxy_promise_clean(p, EFL_MODEL_ERROR_NOT_FOUND);
608 { 624 return ;
609 efl_promise_failed_set(p->promise, EFL_MODEL_ERROR_NOT_FOUND);
610 free(p->property);
611 continue;
612 }
613
614 if (!_eldbus_model_proxy_is_property_readable(pd, p->property))
615 {
616 efl_promise_failed_set(p->promise, EFL_MODEL_ERROR_READ_ONLY);
617 free(p->property);
618 continue;
619 }
620
621 free(p->property);
622
623 promise_value = eina_value_new(eina_value_type_get(value));
624 eina_value_copy(value, promise_value);
625 efl_promise_value_set(p->promise, promise_value, (Eina_Free_Cb)&eina_value_free);
626 } 625 }
627 eina_list_free(pd->promise_list);
628 626
627 EINA_LIST_FREE(pd->promises, p)
628 _eldbus_model_proxy_promise_clean(p, EFL_MODEL_ERROR_READ_ONLY);
629 629
630 _eldbus_model_proxy_start_monitor(pd); 630 _eldbus_model_proxy_start_monitor(pd);
631 631
632 if (eina_array_count(changed_properties)) 632 evt.changed_properties = properties;
633 { 633 efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_PROPERTIES_CHANGED, &evt);
634 Efl_Model_Property_Event evt = { 634 eina_array_free(properties);
635 .changed_properties = changed_properties
636 };
637
638 efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_PROPERTIES_CHANGED, &evt);
639 }
640
641 eina_array_free(changed_properties);
642} 635}
643 636
644 637
645static void 638static void
646_eldbus_model_proxy_property_set_load_cb(void *data, 639_eldbus_model_proxy_property_set_load_cb(void *data,
647 const Eldbus_Message *msg, 640 const Eldbus_Message *msg,
648 Eldbus_Pending *pending) 641 Eldbus_Pending *pending)
649{ 642{
650 Eldbus_Model_Proxy_Property_Set_Data *set_data = (Eldbus_Model_Proxy_Property_Set_Data *)data; 643 Eldbus_Model_Proxy_Property_Set_Data *set_data = (Eldbus_Model_Proxy_Property_Set_Data *)data;
651 Eldbus_Model_Proxy_Data *pd = set_data->pd; 644 Eldbus_Model_Proxy_Data *pd = set_data->pd;
645 Eina_Array *properties;
652 const char *signature; 646 const char *signature;
653 647
654 pd->pending_list = eina_list_remove(pd->pending_list, pending); 648 pd->pendings = eina_list_remove(pd->pendings, pending);
649
655 signature = _eldbus_model_proxy_property_type_get(pd, set_data->property); 650 signature = _eldbus_model_proxy_property_type_get(pd, set_data->property);
656 651
657 Eina_Array *changed_properties = _eldbus_model_proxy_property_get_all_load(msg, pd); 652 properties = _eldbus_model_proxy_property_get_all_load(msg, pd);
658 if (signature == NULL || changed_properties == NULL) 653 if (!signature || !properties)
659 { 654 {
660 efl_promise_failed_set(set_data->promise, EFL_MODEL_ERROR_UNKNOWN); 655 eina_promise_reject(set_data->promise, EFL_MODEL_ERROR_UNKNOWN);
661 656 eina_array_free(properties);
662 eina_array_free(changed_properties); 657 _eldbus_model_proxy_property_set_data_free(set_data);
663 _eldbus_model_proxy_property_set_data_free(set_data);
664 return; 658 return;
665 } 659 }
666 660
667 eina_array_free(changed_properties); 661 eina_array_free(properties);
668 pending = eldbus_proxy_property_value_set 662 pending = eldbus_proxy_property_value_set(pd->proxy, set_data->property,
669 (pd->proxy, set_data->property, signature, &set_data->value, _eldbus_model_proxy_property_set_cb, set_data); 663 signature, set_data->value,
670 pd->pending_list = eina_list_append(pd->pending_list, pending); 664 _eldbus_model_proxy_property_set_cb, set_data);
665 pd->pendings = eina_list_append(pd->pendings, pending);
671} 666}
672 667
673 668
@@ -676,95 +671,42 @@ _eldbus_model_proxy_property_set_cb(void *data,
676 const Eldbus_Message *msg, 671 const Eldbus_Message *msg,
677 Eldbus_Pending *pending) 672 Eldbus_Pending *pending)
678{ 673{
679 Eldbus_Model_Proxy_Property_Set_Data *property_set_data = (Eldbus_Model_Proxy_Property_Set_Data *)data; 674 Eldbus_Model_Proxy_Property_Set_Data *sd = (Eldbus_Model_Proxy_Property_Set_Data *)data;
680 Eldbus_Model_Proxy_Data *pd = property_set_data->pd; 675 Eldbus_Model_Proxy_Data *pd = sd->pd;
681 const char *error_name, *error_text; 676 const char *error_name, *error_text;
682 Eina_Value *prop_value; 677 Eina_Value *value;
683 Eina_Value *promise_value;
684 678
685 pd->pending_list = eina_list_remove(pd->pending_list, pending); 679 pd->pendings = eina_list_remove(pd->pendings, pending);
686 680
687 if (eldbus_message_error_get(msg, &error_name, &error_text)) 681 if (eldbus_message_error_get(msg, &error_name, &error_text))
688 { 682 {
689 ERR("%s: %s", error_name, error_text); 683 ERR("%s: %s", error_name, error_text);
690 efl_promise_failed_set(property_set_data->promise, EFL_MODEL_ERROR_UNKNOWN); 684 eina_promise_reject(sd->promise, EFL_MODEL_ERROR_UNKNOWN);
691 _eldbus_model_proxy_property_set_data_free(property_set_data); 685 goto end;
692 return;
693 } 686 }
694 687
695 prop_value = eina_hash_find(pd->properties_hash, property_set_data->property); 688 value = eina_hash_find(pd->properties, sd->property);
696 if (prop_value != NULL) 689 if (value)
697 { 690 {
698 if (eina_value_copy(&property_set_data->value, prop_value)) 691 efl_model_properties_changed(pd->obj, sd->property);
699 { 692 if (sd->promise)
700 Efl_Model_Property_Event evt = { 693 eina_promise_resolve(sd->promise,
701 .changed_properties = pd->properties_array 694 eina_value_reference_copy(value));
702 };
703
704 efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_PROPERTIES_CHANGED, &evt);
705 efl_model_property_changed_notify(pd->obj, property_set_data->property);
706
707 }
708 promise_value = eina_value_new(eina_value_type_get(prop_value));
709 eina_value_copy(prop_value, promise_value);
710 efl_promise_value_set(property_set_data->promise, promise_value, (Eina_Free_Cb)&eina_value_free);
711 } 695 }
712 else 696 else
713 { 697 {
714 efl_promise_failed_set(property_set_data->promise, EFL_MODEL_ERROR_NOT_FOUND); 698 if (sd->promise)
715 } 699 eina_promise_reject(sd->promise,
716 700 EFL_MODEL_ERROR_NOT_FOUND);
717 _eldbus_model_proxy_property_set_data_free(property_set_data);
718}
719
720static bool
721_eldbus_model_proxy_has_property(Eldbus_Model_Proxy_Data *pd, const char *property)
722{
723 Eldbus_Introspection_Property *property_introspection =
724 eldbus_introspection_property_find(pd->interface->properties, property);
725
726 if (property_introspection == NULL)
727 {
728 return false;
729 }
730
731 return true;
732}
733
734static bool
735_eldbus_model_proxy_is_property_writeable(Eldbus_Model_Proxy_Data *pd, const char *property)
736{
737 Eldbus_Introspection_Property *property_introspection =
738 eldbus_introspection_property_find(pd->interface->properties, property);
739
740 if (property_introspection == NULL)
741 {
742 WRN("Property not found: %s", property);
743 return false;
744 }
745
746 return ELDBUS_INTROSPECTION_PROPERTY_ACCESS_WRITE == property_introspection->access
747 || ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE == property_introspection->access;
748}
749
750static bool
751_eldbus_model_proxy_is_property_readable(Eldbus_Model_Proxy_Data *pd, const char *property)
752{
753 Eldbus_Introspection_Property *property_introspection =
754 eldbus_introspection_property_find(pd->interface->properties, property);
755
756 if (property_introspection == NULL)
757 {
758 WRN("Property not found: %s", property);
759 return false;
760 } 701 }
761 702
762 return ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READ == property_introspection->access 703 end:
763 || ELDBUS_INTROSPECTION_PROPERTY_ACCESS_READWRITE == property_introspection->access; 704 _eldbus_model_proxy_property_set_data_free(sd);
764} 705}
765 706
766static const char * 707static const char *
767_eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *pd, const char *property) 708_eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *pd,
709 const char *property)
768{ 710{
769 Eldbus_Introspection_Property *property_introspection = 711 Eldbus_Introspection_Property *property_introspection =
770 eldbus_introspection_property_find(pd->interface->properties, property); 712 eldbus_introspection_property_find(pd->interface->properties, property);
@@ -778,35 +720,12 @@ _eldbus_model_proxy_property_type_get(Eldbus_Model_Proxy_Data *pd, const char *p
778 return property_introspection->type; 720 return property_introspection->type;
779} 721}
780 722
781static Eldbus_Model_Proxy_Property_Set_Data *
782_eldbus_model_proxy_property_set_data_new(Eldbus_Model_Proxy_Data *pd,
783 const char *property,
784 const Eina_Value *value,
785 Efl_Promise *promise)
786{
787 Eldbus_Model_Proxy_Property_Set_Data *data = calloc(1, sizeof(Eldbus_Model_Proxy_Property_Set_Data));
788 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
789
790 data->pd = pd;
791 data->promise = promise;
792 data->property = eina_stringshare_add(property);
793 if (!eina_value_copy(value, &data->value))
794 goto error;
795
796 return data;
797
798 error:
799 eina_stringshare_del(data->property);
800 free(data);
801 return NULL;
802}
803
804static void 723static void
805_eldbus_model_proxy_property_set_data_free(Eldbus_Model_Proxy_Property_Set_Data *data) 724_eldbus_model_proxy_property_set_data_free(Eldbus_Model_Proxy_Property_Set_Data *data)
806{ 725{
807 EINA_SAFETY_ON_NULL_RETURN(data); 726 EINA_SAFETY_ON_NULL_RETURN(data);
808 eina_stringshare_del(data->property); 727 eina_stringshare_del(data->property);
809 eina_value_flush(&data->value); 728 eina_value_free(data->value);
810 free(data); 729 free(data);
811} 730}
812 731
diff --git a/src/lib/eldbus/eldbus_model_proxy.eo b/src/lib/eldbus/eldbus_model_proxy.eo
index 00521e6..0bb8b3e 100644
--- a/src/lib/eldbus/eldbus_model_proxy.eo
+++ b/src/lib/eldbus/eldbus_model_proxy.eo
@@ -1,19 +1,24 @@
1import eldbus_types; 1import eldbus_types;
2 2
3class Eldbus.Model.Proxy (Efl.Object, Efl.Model) { 3class Eldbus.Model.Proxy (Eldbus.Model) {
4 [[Eldbus model proxy class]] 4 [[Eldbus model proxy class]]
5 5
6 methods { 6 methods {
7 custom_constructor { 7 @property object {
8 [[Custom Eldbus_Model_Proxy constructor. 8 [[Object]]
9 9 set {}
10 @since 1.16]] 10 values {
11 params { 11 object: ptr(Eldbus.Object); [[Eldbus object]]
12 @in object: ptr(Eldbus.Object); [[Eldbus object]] 12 }
13 }
14 @property interface {
15 [[Object]]
16 set {}
17 values {
13 @cref interface: Eldbus.Introspection.Interface; [[The introspected interface]] 18 @cref interface: Eldbus.Introspection.Interface; [[The introspected interface]]
14 } 19 }
15 } 20 }
16 @property proxy_name { 21 @property proxy_name {
17 [[Proxy name]] 22 [[Proxy name]]
18 get {} 23 get {}
19 values { 24 values {
@@ -23,16 +28,15 @@ class Eldbus.Model.Proxy (Efl.Object, Efl.Model) {
23 } 28 }
24 implements { 29 implements {
25 Efl.Object.constructor; 30 Efl.Object.constructor;
31 Efl.Object.finalize;
32 Efl.Object.invalidate;
26 Efl.Object.destructor; 33 Efl.Object.destructor;
27 Efl.Model.properties { get; } 34 Efl.Model.properties { get; }
28 Efl.Model.property_set; 35 Efl.Model.property { set; get; }
29 Efl.Model.property_get;
30 Efl.Model.child_add;
31 Efl.Model.child_del;
32 Efl.Model.children_slice_get; 36 Efl.Model.children_slice_get;
33 Efl.Model.children_count_get; 37 Efl.Model.children_count { get; }
34 } 38 }
35 constructors { 39 constructors {
36 .custom_constructor; 40 .interface;
37 } 41 }
38} 42}
diff --git a/src/lib/eldbus/eldbus_model_proxy_private.h b/src/lib/eldbus/eldbus_model_proxy_private.h
index 293a1f5..940f778 100644
--- a/src/lib/eldbus/eldbus_model_proxy_private.h
+++ b/src/lib/eldbus/eldbus_model_proxy_private.h
@@ -13,20 +13,21 @@ typedef struct _Eldbus_Model_Proxy_Data Eldbus_Model_Proxy_Data;
13struct _Eldbus_Model_Proxy_Data 13struct _Eldbus_Model_Proxy_Data
14{ 14{
15 Eo *obj; 15 Eo *obj;
16 Eina_Bool is_listed : 1; 16
17 Eina_Bool is_loaded : 1; 17 const Eldbus_Introspection_Interface *interface;
18
18 Eldbus_Object *object; 19 Eldbus_Object *object;
19 Eldbus_Proxy *proxy; 20 Eldbus_Proxy *proxy;
20 Eina_Array *properties_array; 21 Eina_Hash *properties;
21 Eina_Hash *properties_hash; 22 Eina_List *childrens;
22 Eina_List *children_list; 23 Eina_List *pendings;
24 Eina_List *promises;
25
23 Eina_Stringshare *name; 26 Eina_Stringshare *name;
24 Eina_List *pending_list; 27
25 Eina_List *promise_list; 28 Eina_Bool monitoring : 1;
26 bool monitoring; 29 Eina_Bool is_listed : 1;
27 const Eldbus_Introspection_Interface *interface; 30 Eina_Bool is_loaded : 1;
28 Eina_Value tmp_value;
29}; 31};
30 32
31#endif 33#endif
32