summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLarry Jr <larry.olj@gmail.com>2016-04-20 17:07:53 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-04-29 13:21:24 -0300
commit0c76f82a31b1ad06a4da4c12f1a02139e0d0c6fa (patch)
tree254f0542b8fc5ea1af14936da8e6806262f3f8a6
parent42346e22f4c06634e180c44cf63924dbc50a5184 (diff)
Efl, Eio, Eldbus, Elementary: new model API use eina_promise
Efl - efl_model_base changed to use eina_promise Eio - eio_model use efl_model_base with promise Eldbus - elddbus models use promise now Elementary - elm_view_list and elm_view_form use new models with promise updated all related examples and tests
-rw-r--r--src/examples/eldbus/dbusmodel.c144
-rw-r--r--src/examples/elementary/filemvc.c35
-rw-r--r--src/examples/elementary/fileviewlist.c2
-rw-r--r--src/lib/efl/Efl_Model_Common.h31
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c2
-rw-r--r--src/lib/efl/interfaces/efl_model_base.eo231
-rw-r--r--src/lib/efl/interfaces/efl_model_common.c120
-rw-r--r--src/lib/eio/eio_model.c450
-rw-r--r--src/lib/eio/eio_model.eo15
-rw-r--r--src/lib/eio/eio_model_private.h33
-rw-r--r--src/lib/eldbus/eldbus_model_arguments.c144
-rw-r--r--src/lib/eldbus/eldbus_model_arguments.eo13
-rw-r--r--src/lib/eldbus/eldbus_model_arguments_private.h1
-rw-r--r--src/lib/eldbus/eldbus_model_connection.c194
-rw-r--r--src/lib/eldbus/eldbus_model_connection.eo13
-rw-r--r--src/lib/eldbus/eldbus_model_connection_private.h6
-rw-r--r--src/lib/eldbus/eldbus_model_method.c5
-rw-r--r--src/lib/eldbus/eldbus_model_method.eo2
-rw-r--r--src/lib/eldbus/eldbus_model_object.c195
-rw-r--r--src/lib/eldbus/eldbus_model_object.eo13
-rw-r--r--src/lib/eldbus/eldbus_model_object_private.h9
-rw-r--r--src/lib/eldbus/eldbus_model_private.h30
-rw-r--r--src/lib/eldbus/eldbus_model_proxy.c304
-rw-r--r--src/lib/eldbus/eldbus_model_proxy.eo13
-rw-r--r--src/lib/eldbus/eldbus_model_proxy_private.h5
-rw-r--r--src/lib/eldbus/eldbus_model_signal.c22
-rw-r--r--src/lib/eldbus/eldbus_model_signal.eo2
-rw-r--r--src/lib/elementary/elm_view_form.c112
-rw-r--r--src/lib/elementary/elm_view_list.c211
-rw-r--r--src/tests/eio/eio_model_test_file.c170
-rw-r--r--src/tests/eio/eio_model_test_monitor_add.c139
-rw-r--r--src/tests/eio/eio_suite.c12
-rw-r--r--src/tests/eldbus/eldbus_fake_server.c1
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model.c275
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model.h10
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model_connection.c122
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model_method.c101
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model_object.c125
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model_proxy.c99
-rw-r--r--src/tests/eldbus/eldbus_test_eldbus_model_signal.c104
-rw-r--r--src/tests/eldbus/eldbus_test_fake_server_eldbus_model_proxy.c98
41 files changed, 1499 insertions, 2114 deletions
diff --git a/src/examples/eldbus/dbusmodel.c b/src/examples/eldbus/dbusmodel.c
index f2c5e87..a7c8ee7 100644
--- a/src/examples/eldbus/dbusmodel.c
+++ b/src/examples/eldbus/dbusmodel.c
@@ -1,7 +1,9 @@
1//Compile with: 1//Compile with:
2// gcc -o busmodel busmodel.c `pkg-config --cflags --libs eldbus ecore eina` 2// gcc -o busmodel busmodel.c `pkg-config --cflags --libs eldbus ecore eina`
3 3
4#ifdef HAVE_CONFIG_H
4# include <config.h> 5# include <config.h>
6#endif
5 7
6#include <Eldbus.h> 8#include <Eldbus.h>
7#include <Eldbus_Model.h> 9#include <Eldbus_Model.h>
@@ -11,77 +13,113 @@
11#define DEFAULT_BUS "org.freedesktop.DBus" 13#define DEFAULT_BUS "org.freedesktop.DBus"
12#define DEFAULT_PATH "/" 14#define DEFAULT_PATH "/"
13 15
14static unsigned int children_count = 0; 16static int prop_count = 0;
15 17
16static Eina_Bool 18struct eina_iterator
17_event_interface_load_status_cb(void *data EINA_UNUSED, const Eo_Event *event)
18{ 19{
19 Efl_Model_Load *actual_load = (Efl_Model_Load*)event->info; 20 Eina_Iterator* success_iterator;
20 Eina_Array *properties_list; 21 Eina_Iterator* failure_iterator;
21 Eina_Array_Iterator iterator; 22};
22 Eina_Value const* property_value; 23
24static void
25promise_then_prop_c(Eo* obj, struct eina_iterator* it_struct)
26{
27 Eina_Value * property_value;
28 const Eina_Array *properties_list;
29 Eina_Array_Iterator a_it;
23 char *property, *prop_str; 30 char *property, *prop_str;
24 const char *name; 31 const char *name;
25 unsigned int i; 32 Eina_Iterator* it = it_struct->success_iterator;
26
27 if (EFL_MODEL_LOAD_STATUS_LOADED != actual_load->status)
28 return EINA_TRUE;
29
30 name = eldbus_model_proxy_name_get(event->obj);
31 efl_model_properties_get(event->obj, &properties_list);
32 33
33 printf(" -> %s\n", name); 34 name = eldbus_model_proxy_name_get(obj);
34 if (eina_array_count(properties_list)) 35 properties_list = efl_model_properties_get(obj);
35 printf(" Properties:\n");
36 36
37 EINA_ARRAY_ITER_NEXT(properties_list, i, property, iterator) 37 printf(" -> %s\n Properties:\n", name);
38 unsigned i = 0;
39 EINA_ARRAY_ITER_NEXT(properties_list, i, property, a_it)
38 { 40 {
39 efl_model_property_get(event->obj, property, &property_value); 41 if (eina_iterator_next(it, (void **)&property_value) && property_value)
40 if (property_value)
41 { 42 {
42 prop_str = eina_value_to_string(property_value); 43 prop_str = eina_value_to_string(property_value);
44 printf(" * %s=%s \n", property, prop_str);
45 free(prop_str);
43 } 46 }
44 printf(" * %s: %s \n", property, prop_str);
45 free(prop_str);
46 prop_str = NULL;
47 } 47 }
48 48
49 children_count--; 49 prop_count--;
50 50 if (prop_count == 0)
51 if (!children_count)
52 ecore_main_loop_quit(); 51 ecore_main_loop_quit();
53
54 return EINA_FALSE;
55} 52}
56 53
57static Eina_Bool 54static void
58_event_load_status_cb(void *data EINA_UNUSED, const Eo_Event *event) 55error_cb(void* data EINA_UNUSED, const Eina_Error *error EINA_UNUSED)
59{ 56{
60 Efl_Model_Load *actual_load = (Efl_Model_Load*)event->info; 57 printf(" ERROR\n");
61 Eina_Accessor *accessor; 58 ecore_main_loop_quit();
62 Eo *child = NULL; 59}
63 unsigned int i;
64 60
65 if (EFL_MODEL_LOAD_STATUS_LOADED != actual_load->status) 61static void
66 return EINA_TRUE; 62promise_then_a(Eo* obj EINA_UNUSED, Eina_Accessor **accessor)
63{
64 const Eina_Array *properties_list;
65 Eina_Array_Iterator a_it;
66 Eina_Promise **promises;
67 const char *name;
68 char *property;
69 Eo* child;
70 int i = 0;
67 71
68 efl_model_children_count_get(event->obj, &children_count); 72 EINA_ACCESSOR_FOREACH(*accessor, i, child)
69 if (children_count == 0)
70 { 73 {
71 printf("Don't find Interfaces\n"); 74 properties_list = efl_model_properties_get(child);
72 ecore_main_loop_quit(); 75 name = eldbus_model_proxy_name_get(child);
73 return EINA_FALSE; 76
77 unsigned p_count = eina_array_count(properties_list);
78
79 if (p_count)
80 {
81 promises = (Eina_Promise **)calloc(p_count + 1, sizeof(Eina_Promise *));
82 promises[p_count] = NULL;
83
84 unsigned j = 0;
85 EINA_ARRAY_ITER_NEXT(properties_list, j, property, a_it)
86 {
87 efl_model_property_get(child, property, &promises[j]);
88 }
89 eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
90 (Eina_Promise_Cb)&promise_then_prop_c, &error_cb, child);
91 prop_count++;
92 }
93 else
94 {
95 printf(" -> %s\n", name);
96 }
74 } 97 }
75 98
76 efl_model_children_slice_get(event->obj, 0, 0, &accessor); 99 if (prop_count == 0)
77 printf("\nInterfaces:\n"); 100 ecore_main_loop_quit();
78 EINA_ACCESSOR_FOREACH(accessor, i, child) 101}
102static void
103promise_then(Eo* obj EINA_UNUSED, struct eina_iterator* it_struct)
104{
105 Eina_Accessor **accessor;
106 unsigned int* count;
107
108 Eina_Iterator* iterator = it_struct->success_iterator;
109
110 if (!eina_iterator_next(iterator, (void **)&accessor))
79 { 111 {
80 eo_event_callback_add(child, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_interface_load_status_cb, NULL); 112 printf("bye\n");
81 efl_model_load(child); 113 ecore_main_loop_quit();
114 return;
82 } 115 }
83 116
84 return EINA_FALSE; 117 eina_iterator_next(iterator, (void **)&count);
118
119 printf("efl_model_loaded count %d\n", (int)*count); fflush(stdout);
120 printf("efl_model_loaded accessor %p\n", accessor); fflush(stdout);
121
122 promise_then_a(NULL, accessor);
85} 123}
86 124
87int 125int
@@ -90,6 +128,7 @@ main(int argc, char **argv EINA_UNUSED)
90 const char *bus, *path; 128 const char *bus, *path;
91 Eo *root; 129 Eo *root;
92 130
131 ecore_init();
93 eldbus_init(); 132 eldbus_init();
94 133
95 bus = DEFAULT_BUS; 134 bus = DEFAULT_BUS;
@@ -100,12 +139,15 @@ main(int argc, char **argv EINA_UNUSED)
100 139
101 root = eo_add_ref(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(eo_self, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, bus, path)); 140 root = eo_add_ref(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(eo_self, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, bus, path));
102 141
103 eo_event_callback_add(root, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_load_status_cb, NULL); 142 Eina_Promise *promises[] = { NULL, NULL, NULL};
104 efl_model_load(root); 143 efl_model_children_slice_get(root, 0, 0, &promises[0]);
144 efl_model_children_count_get(root, &promises[1]);
105 145
106 ecore_main_loop_begin(); 146 eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
147 (Eina_Promise_Cb)&promise_then, &error_cb, root);
107 148
108 eo_event_callback_del(root, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_load_status_cb, NULL); 149 ecore_main_loop_begin();
109 150
110 eo_unref(root); 151 eo_unref(root);
152 eldbus_shutdown();
111} 153}
diff --git a/src/examples/elementary/filemvc.c b/src/examples/elementary/filemvc.c
index 3b4fe5a..f33b200 100644
--- a/src/examples/elementary/filemvc.c
+++ b/src/examples/elementary/filemvc.c
@@ -51,29 +51,41 @@ _list_selected_cb(void *data EINA_UNUSED, const Eo_Event *event)
51{ 51{
52 Efl_Model_Test_Filemvc_Data *priv = data; 52 Efl_Model_Test_Filemvc_Data *priv = data;
53 Eo *child = event->info; 53 Eo *child = event->info;
54 ethumb_client_file_free(elm_thumb_ethumb_client_get()); 54// ethumb_client_file_free(elm_thumb_ethumb_client_get());
55 55
56 printf("LIST selected model\n"); 56 printf("LIST selected model\n");
57 elm_view_form_model_set(priv->formview, child); 57 elm_view_form_model_set(priv->formview, child);
58 return EINA_TRUE; 58 return EINA_TRUE;
59} 59}
60 60
61static void
62_promise_then(void *data, void *value)
63{
64 Efl_Model_Test_Filemvc_Data *priv = data;
65 char *path;
66 Eo *model;
67
68 eina_value_get((Eina_Value *)value, &path);
69 model = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, path));
70 elm_view_list_model_set(priv->fileview, model);
71}
72
73static void
74_promise_error(void *data, const Eina_Error *err)
75{
76}
77
61static Eina_Bool 78static Eina_Bool
62_tree_selected_cb(void *data, const Eo_Event *event) 79_tree_selected_cb(void *data, const Eo_Event *event)
63{ 80{
64 Efl_Model_Test_Filemvc_Data *priv = data; 81 Efl_Model_Test_Filemvc_Data *priv = data;
65 Eo *child = event->info; 82 Eo *child = event->info;
66 const Eina_Value *vpath; 83 Eina_Promise *promise;
67 Eo *model;
68 char *path;
69 84
70 printf("TREE selected model\n"); 85 printf("TREE selected model\n");
71 86
72 efl_model_property_get(child, "path", &vpath); 87 efl_model_property_get(child, "path", &promise);
73 eina_value_get(vpath, &path); 88 eina_promise_then(promise, &_promise_then, &_promise_error, priv);
74 model = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, path));
75 efl_model_load(model);
76 elm_view_list_model_set(priv->fileview, model);
77 return EINA_TRUE; 89 return EINA_TRUE;
78} 90}
79 91
@@ -130,16 +142,12 @@ elm_main(int argc, char **argv)
130 evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 142 evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
131 elm_win_resize_object_add(win, panes); 143 elm_win_resize_object_add(win, panes);
132 144
133 ecore_init();
134 eio_init();
135
136 if(argv[1] != NULL) dirname = argv[1]; 145 if(argv[1] != NULL) dirname = argv[1];
137 else dirname = EFL_MODEL_TEST_FILENAME_PATH; 146 else dirname = EFL_MODEL_TEST_FILENAME_PATH;
138 147
139 //treemodel 148 //treemodel
140 priv.treemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname)); 149 priv.treemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname));
141 eio_model_children_filter_set(priv.treemodel, _filter_cb, NULL); 150 eio_model_children_filter_set(priv.treemodel, _filter_cb, NULL);
142 efl_model_load(priv.treemodel);
143 151
144 //treeview 152 //treeview
145 genlist = elm_genlist_add(win); 153 genlist = elm_genlist_add(win);
@@ -155,6 +163,7 @@ elm_main(int argc, char **argv)
155 _widget_init(vpanes); 163 _widget_init(vpanes);
156 elm_object_part_content_set(panes, "right", vpanes); 164 elm_object_part_content_set(panes, "right", vpanes);
157 eo_event_callback_add(priv.treeview, ELM_VIEW_LIST_EVENT_MODEL_SELECTED, _tree_selected_cb, &priv); 165 eo_event_callback_add(priv.treeview, ELM_VIEW_LIST_EVENT_MODEL_SELECTED, _tree_selected_cb, &priv);
166
158 //listview 167 //listview
159 genlist = elm_genlist_add(win); 168 genlist = elm_genlist_add(win);
160 priv.fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_NONE, "double_label")); 169 priv.fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_NONE, "double_label"));
diff --git a/src/examples/elementary/fileviewlist.c b/src/examples/elementary/fileviewlist.c
index 2d765ac..a3a434e 100644
--- a/src/examples/elementary/fileviewlist.c
+++ b/src/examples/elementary/fileviewlist.c
@@ -42,7 +42,6 @@ elm_main(int argc, char **argv)
42 memset(&priv, 0, sizeof(Efl_Model_Test_Fileview_Data)); 42 memset(&priv, 0, sizeof(Efl_Model_Test_Fileview_Data));
43 43
44 ecore_init(); 44 ecore_init();
45 eio_init();
46 45
47 if(argv[1] != NULL) dirname = argv[1]; 46 if(argv[1] != NULL) dirname = argv[1];
48 else dirname = EFL_MODEL_TEST_FILENAME_PATH; 47 else dirname = EFL_MODEL_TEST_FILENAME_PATH;
@@ -58,7 +57,6 @@ elm_main(int argc, char **argv)
58 priv.filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname)); 57 priv.filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname));
59 priv.fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_TREE, "double_label")); 58 priv.fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_TREE, "double_label"));
60 elm_view_list_model_set(priv.fileview, priv.filemodel); 59 elm_view_list_model_set(priv.fileview, priv.filemodel);
61 efl_model_load(priv.filemodel);
62 evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, &priv); 60 evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, &priv);
63 61
64 elm_view_list_property_connect(priv.fileview, "filename", "elm.text"); 62 elm_view_list_property_connect(priv.fileview, "filename", "elm.text");
diff --git a/src/lib/efl/Efl_Model_Common.h b/src/lib/efl/Efl_Model_Common.h
index 1440e81..0ccccc1 100644
--- a/src/lib/efl/Efl_Model_Common.h
+++ b/src/lib/efl/Efl_Model_Common.h
@@ -1,6 +1,18 @@
1#ifndef EFL_MODEL_COMMON_H__ 1#ifndef EFL_MODEL_COMMON_H__
2# define EFL_MODEL_COMMON_H__ 2# define EFL_MODEL_COMMON_H__
3 3
4#include <Eina.h>
5
6EAPI extern Eina_Error EFL_MODEL_ERROR_UNKNOWN;
7EAPI extern Eina_Error EFL_MODEL_ERROR_NOT_SUPPORTED;
8EAPI extern Eina_Error EFL_MODEL_ERROR_NOT_FOUND;
9EAPI extern Eina_Error EFL_MODEL_ERROR_READ_ONLY;
10EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED;
11EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE;
12EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED;
13
14typedef struct _Eina_Promise Eina_Promise;
15
4/** 16/**
5 * @struct _Efl_Model_Children_Event 17 * @struct _Efl_Model_Children_Event
6 * Every time a child id added the event 18 * Every time a child id added the event
@@ -29,16 +41,7 @@ typedef struct _Efl_Model_Children_Event Efl_Model_Children_Event;
29 41
30#include "interfaces/efl_model_base.eo.h" 42#include "interfaces/efl_model_base.eo.h"
31 43
32 /** 44EAPI int efl_model_init(void);
33 * @brief Sets the new load status signaling an event if changed
34 *
35 * @param model The model to call the event @c EFL_MODEL_EVENT_LOAD_STATUS
36 * @param load The load status to be changed
37 * @param status The new status
38 *
39 * @since 1.17
40 */
41EAPI void efl_model_load_set(Efl_Model_Base *model, Efl_Model_Load *load, Efl_Model_Load_Status status) EINA_ARG_NONNULL(1, 2);
42 45
43/** 46/**
44 * @brief Slices a list 47 * @brief Slices a list
@@ -54,14 +57,6 @@ EAPI void efl_model_load_set(Efl_Model_Base *model, Efl_Model_Load *load, Efl_Mo
54 */ 57 */
55EAPI Eina_Accessor *efl_model_list_slice(Eina_List *list, unsigned start, unsigned count) EINA_ARG_NONNULL(1); 58EAPI Eina_Accessor *efl_model_list_slice(Eina_List *list, unsigned start, unsigned count) EINA_ARG_NONNULL(1);
56 59
57/**
58 * @brief Notifies an error with an @c EFL_MODEL_EVENT_LOAD_STATUS
59 *
60 * @param model The model to be notified
61 *
62 * @since 1.17
63 */
64EAPI void efl_model_error_notify(Efl_Model_Base *model) EINA_ARG_NONNULL(1);
65 60
66/** 61/**
67 * @brief Notifies a property changed event with an @c EFL_MODEL_EVENT_PROPERTIES_CHANGED 62 * @brief Notifies a property changed event with an @c EFL_MODEL_EVENT_PROPERTIES_CHANGED
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index 8cf69b9..116c2d3 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -48,5 +48,5 @@ EAPI const Eo_Event_Description _EFL_GFX_PATH_CHANGED =
48EAPI void 48EAPI void
49__efl_internal_init(void) 49__efl_internal_init(void)
50{ 50{
51 /* nothing to do, the symbol only is required for link to work */ 51 efl_model_init();
52} 52}
diff --git a/src/lib/efl/interfaces/efl_model_base.eo b/src/lib/efl/interfaces/efl_model_base.eo
index 494c131..a8a993c 100644
--- a/src/lib/efl/interfaces/efl_model_base.eo
+++ b/src/lib/efl/interfaces/efl_model_base.eo
@@ -1,47 +1,13 @@
1enum Efl.Model.Load_Status {
2 error = 0,
3 loading_properties = (1 << 0),
4 loading_children = (1 << 1),
5 loading = (1 << 0) | (1 << 1),
6
7 loaded_properties = (1 << 2),
8 loaded_children = (1 << 3),
9 loaded = (1 << 2) | (1 << 3),
10
11 unloading = (1 << 4),
12 unloaded = (1 << 5)
13}
14
15struct Efl.Model.Property_Event { 1struct Efl.Model.Property_Event {
16 changed_properties: array<const(char) *> *; [[List of changed properties]] 2 changed_properties: array<const(char) *> *; [[List of changed properties]]
17 invalidated_properties: array<const(char) *> *; [[Removed properties identified by name]] 3 invalidated_properties: array<const(char) *> *; [[Removed properties identified by name]]
18} 4}
19 5
20struct Efl.Model.Load {
21 [[Structure to hold Efl_Model_Load_Status enum (and possible other data) to avoid ABI break.]]
22
23 status: Efl.Model.Load_Status;
24}
25
26interface Efl.Model.Base () 6interface Efl.Model.Base ()
27{ 7{
28 legacy_prefix: null; 8 legacy_prefix: null;
29 eo_prefix: efl_model; 9 eo_prefix: efl_model;
30 methods { 10 methods {
31 @property load_status {
32 get {
33 [[Get a load emodel current status.
34
35 By convention this means get the current model status.
36 Possible values are defined Efl_Model_Load_Status enumerator.
37
38 See also \@ref Efl_Model_Load_Status, @.load
39
40 @since 1.14
41 ]]
42 return: Efl.Model.Load_Status;
43 }
44 }
45 @property properties { 11 @property properties {
46 get { 12 get {
47 [[Get properties from model. 13 [[Get properties from model.
@@ -55,91 +21,58 @@ interface Efl.Model.Base ()
55 21
56 @since 1.14 22 @since 1.14
57 ]] 23 ]]
58 return: Efl.Model.Load_Status;
59 } 24 }
60 values { 25 values {
61 properties: const(array<const(char)*>*); [[array of current properties]] 26 properties: const(array<const(char)*>)*; [[array of current properties]]
62 } 27 }
63 } 28 }
64 @property property { 29 property_set {
65 set { 30 [[Set a property value of a given property name.
66 [[Set a property value of a given property name.
67 31
68 The caller must ensure to call at least efl_model_prop_list 32 The caller must ensure to call at least efl_model_prop_list
69 before being able to see/set properties. This function sets 33 before being able to see/set properties. This function sets
70 a new property value into given property name. Once the 34 a new property value into given property name. Once the
71 operation is completed the concrete implementation should 35 operation is completed the concrete implementation should
72 raise EFL_MODEL_EVENT_PROPERTIES_CHANGE event in order to 36 raise EFL_MODEL_EVENT_PROPERTIES_CHANGE event in order to
73 notify listeners of the new value of the property. 37 notify listeners of the new value of the property.
74 38
75 If the model doesn't have the property then there are two 39 If the model doesn't have the property then there are two
76 possibilities, either raise an error or create the new 40 possibilities, either raise an error or create the new
77 property in model 41 property in model
78 42
79 See @.property.get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE 43 See @.property_get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
80 44
81 @since 1.14 45 @since 1.14
82 ]] 46 ]]
83 return: Efl.Model.Load_Status; 47 params {
84 } 48 @in property: const(char)*; [[Property name]]
85 get { 49 @in value: const(generic_value)*; [[New value]]
86 [[Retrieve the value of a given property name. 50 @inout promise: promise<generic_value>*; [[Promise returning the recorded value or error]]
87 51 }
88 property_get will only be available when load status is equal 52 }
89 to EFL_MODEL_LOAD_STATUS_LOADED. 53 property_get {
90 54 [[Retrieve the value of a given property name.
91 At this point the caller is free to get values from properties.
92 The event EFL_MODEL_EVENT_PROPERTIES_CHANGE may be raised to
93 notify listeners of the property/value.
94
95 See @.properties.get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
96
97 @since 1.14
98 ]]
99 return: Efl.Model.Load_Status;
100 }
101 keys {
102 property: const(char)*; [[Property name]]
103 }
104 values {
105 value: const(generic_value)*; [[New value]]
106 }
107 }
108 @property children_slice {
109 get {
110 /* doc FIXME: example
111 Below are examples of both usage types: slices and full ranges.
112 @code
113 55
114 // Returns full list 56 At this point the caller is free to get values from properties.
115 eo_do(obj, efl_model_children_slice_get(0, 0, &children_accessor)); 57 The event EFL_MODEL_EVENT_PROPERTIES_CHANGE may be raised to
58 notify listeners of the property/value.
116 59
117 // Returns 5 items, counting from item #5 60 See @.properties.get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
118 eo_do(obj, efl_model_children_slice_get(5, 5, &children_accessor));
119 61
120 @endcode 62 @since 1.14
121 */ 63 ]]
64 params {
65 @in property: const(char)*; [[Property name]]
66 @inout value: promise<generic_value>*; [[Promise of the value that was got]]
67 }
68 }
69 children_slice_get {
122 [[Get children slice OR full range. 70 [[Get children slice OR full range.
123 71
124 Before being able to get the children list the model status
125 must be on loaded status (EFL_MODEL_LOAD_STATUS_LOADED).
126 However there may be circunstancies where the model could be
127 in a different state, in such cases it is advisable to simply
128 return: its current state, which will be of course, different
129 than EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN.
130
131 When children accessor is returned as NULL one should then
132 test the current load status return:ed by @.children_slice.get
133 in order to check against an empty list or real error.
134
135 children_slice_get behaves in two different ways, it may 72 children_slice_get behaves in two different ways, it may
136 provide the slice if both $start AND $count are non-zero 73 provide the slice if both $start AND $count are non-zero
137 OR full range otherwise. 74 OR full range otherwise.
138 75
139 The return:ed Eina_Accessor must be freed when it is no longer
140 needed and eo_unref() must be invoked for children if caller
141 wants a copy.
142
143 Since 'slice' is a range, for example if we have 20 childs a 76 Since 'slice' is a range, for example if we have 20 childs a
144 slice could be the range from 3(start) to 4(count), see: 77 slice could be the range from 3(start) to 4(count), see:
145 78
@@ -155,24 +88,19 @@ interface Efl.Model.Base ()
155 Optionally the user can call children_count_get to know the 88 Optionally the user can call children_count_get to know the
156 number of children so a valid range can be known in advance. 89 number of children so a valid range can be known in advance.
157 90
158 See @.children_count.get, @.load, @.load_status.get. 91 See @.children_count_get
159 92
160 @since 1.14 93 @since 1.14
161 ]] 94 ]]
162 return: Efl.Model.Load_Status; 95 params {
163 } 96 @in start: uint; [[Range begin - start from here. If start and
164 keys {
165 start: uint; [[Range begin - start from here. If start and
166 count are 0 slice is ignored.]] 97 count are 0 slice is ignored.]]
167 count: uint; [[Range size. If count and start are 0 slice is 98 @in count: uint; [[Range size. If count and start are 0 slice is
168 ignored.]] 99 ignored.]]
169 } 100 @inout promise: promise<accessor<list<Eo.Base*>*>*>*; [[Promise of the children]]
170 values {
171 children_accessor: accessor<list<Eo.Base*>*>*;
172 } 101 }
173 } 102 }
174 @property children_count { 103 children_count_get {
175 get {
176 [[Get children count. 104 [[Get children count.
177 105
178 When efl_model_load is completed efl_model_coildren_count_get 106 When efl_model_load is completed efl_model_coildren_count_get
@@ -181,80 +109,14 @@ interface Efl.Model.Base ()
181 range is known. Event EFL_MODEL_CHILDREN_COUNT_CHANGED is 109 range is known. Event EFL_MODEL_CHILDREN_COUNT_CHANGED is
182 emitted when count is finished. 110 emitted when count is finished.
183 111
184 See also @.children_slice.get, @.load, @.load_status.get. 112 See also @.children_slice_get.
185 113
186 @since 1.14 114 @since 1.14
187 ]] 115 ]]
188 return: Efl.Model.Load_Status; 116 params {
189 } 117 @inout promise: promise<uint>*;
190 values {
191 children_count: uint;
192 } 118 }
193 } 119 }
194 load {
195 [[Load emodel.
196
197 By convention this means loading data from an external source and
198 populating the models properties and children with it. For example
199 in the case of file system backed model, this means opening the
200 relevant files and reading the data from them(creating the
201 properties and children from it). the model emit
202 EFL_MODEL_EVENT_LOAD_STATUS after end with Efl_Model_Load_Status
203
204 This convention should be followed, but no guarantees of behaviour
205 by user defined types can be given.
206
207 Alternatively is possible to use properties_load to load only
208 properties and children_load to load only children. If
209 efl_model_load is called then calling properties_load
210 and/or children_load is not necessary.
211
212 See also \@ref Efl_Model_Load_Status, @.properties_load,
213 @.children_load, @.unload, @.load_status.get
214
215 @since 1.14
216 ]]
217 }
218 unload {
219 [[Unload emodel.
220
221 By convention this means releasing data received/read from an
222 external source. For example of a database backed model this
223 might mean releasing the iterator for the currently loaded data
224 or deleting a temporary table. the model emit
225 EFL_MODEL_EVENT_LOAD_STATUS after end with model load status
226
227 This convention should be followed, but no guarantees of behaviour
228 by user defined types can be given.
229
230 See also \@ref Efl_Model_Load_Status, @.load, @.load_status.get
231
232 @since 1.14
233 ]]
234 }
235 properties_load {
236 [[Properties emodel load.
237
238 By convention this means loading data from an external source and
239 populating the models properties only. This method is a subset
240 of @.load, meaning that it won't load children, it is a hint.
241 For loadind both properties and children use
242 efl_model_load instead.
243
244 @since 1.14
245 ]]
246 }
247 children_load {
248 [[Children emodel load.
249
250 By convention this means loading data from an external source and
251 populating the models children only. This method is a subset of
252 @.load, meaning that it won't load properties. For loadind both
253 properties and children use efl_model_load instead.
254
255 @since 1.14
256 ]]
257 }
258 child_add { 120 child_add {
259 [[Add a new child. 121 [[Add a new child.
260 122
@@ -263,8 +125,6 @@ interface Efl.Model.Base ()
263 added the event \@ref EFL_MODEL_EVENT_CHILD_ADD is then raised 125 added the event \@ref EFL_MODEL_EVENT_CHILD_ADD is then raised
264 and the new child is kept along with other children. 126 and the new child is kept along with other children.
265 127
266 See also @.load_status.get.
267
268 @since 1.14 128 @since 1.14
269 ]] 129 ]]
270 return: Eo.Base *; 130 return: Eo.Base *;
@@ -279,7 +139,6 @@ interface Efl.Model.Base ()
279 139
280 @since 1.14 140 @since 1.14
281 ]] 141 ]]
282 return: Efl.Model.Load_Status;
283 params { 142 params {
284 @in child: Eo.Base*; [[Child to be removed]] 143 @in child: Eo.Base*; [[Child to be removed]]
285 } 144 }
@@ -287,8 +146,6 @@ interface Efl.Model.Base ()
287 } 146 }
288 147
289 events { 148 events {
290 load,status: Efl.Model.Load_Status; [[Event dispatch when load status
291 changes]]
292 properties,changed: Efl.Model.Property_Event; [[Event dispatched when 149 properties,changed: Efl.Model.Property_Event; [[Event dispatched when
293 properties list is 150 properties list is
294 available.]] 151 available.]]
diff --git a/src/lib/efl/interfaces/efl_model_common.c b/src/lib/efl/interfaces/efl_model_common.c
index 90d515c..d97e2c7 100644
--- a/src/lib/efl/interfaces/efl_model_common.c
+++ b/src/lib/efl/interfaces/efl_model_common.c
@@ -3,81 +3,85 @@
3#endif 3#endif
4 4
5#include "Efl.h" 5#include "Efl.h"
6 6#include "Efl_Model_Common.h"
7EAPI void 7
8efl_model_load_set(Efl_Model_Base *model, Efl_Model_Load *load, Efl_Model_Load_Status status) 8EAPI Eina_Error EFL_MODEL_ERROR_UNKNOWN = 0;
9EAPI Eina_Error EFL_MODEL_ERROR_NOT_SUPPORTED = 0;
10EAPI Eina_Error EFL_MODEL_ERROR_NOT_FOUND = 0;
11EAPI Eina_Error EFL_MODEL_ERROR_READ_ONLY = 0;
12EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0;
13EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0;
14EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0;
15
16static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error";
17static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
18static const char EFL_MODEL_ERROR_NOT_FOUND_STR[] = "Value not found";
19static const char EFL_MODEL_ERROR_READ_ONLY_STR[] = "Value read only";
20static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed";
21static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied";
22static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value";
23
24EAPI int
25efl_model_init()
9{ 26{
10 Efl_Model_Load new_load = {.status = status}; 27 EFL_MODEL_ERROR_INCORRECT_VALUE = eina_error_msg_static_register(
28 EFL_MODEL_ERROR_INCORRECT_VALUE_STR);
11 29
12 if ((load->status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)) && 30 EFL_MODEL_ERROR_UNKNOWN = eina_error_msg_static_register(
13 (new_load.status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING))) 31 EFL_MODEL_ERROR_UNKNOWN_STR);
14 {
15 // Merge status
16 new_load.status = load->status | new_load.status;
17
18 // Removes incompatible statuses (LOADING vs LOADED)
19 switch (status)
20 {
21 case EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES:
22 new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES;
23 break;
24 case EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES:
25 new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
26 break;
27 case EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN:
28 new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN;
29 break;
30 case EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN:
31 new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
32 break;
33 case EFL_MODEL_LOAD_STATUS_LOADED:
34 new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING;
35 break;
36 case EFL_MODEL_LOAD_STATUS_LOADING:
37 new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED;
38 break;
39 default: break;
40 }
41 }
42 32
43 if (load->status != new_load.status) 33 EFL_MODEL_ERROR_NOT_SUPPORTED = eina_error_msg_static_register(
44 { 34 EFL_MODEL_ERROR_NOT_SUPPORTED_STR);
45 load->status = new_load.status; 35
46 eo_event_callback_call(model, EFL_MODEL_BASE_EVENT_LOAD_STATUS, load); 36 EFL_MODEL_ERROR_NOT_FOUND = eina_error_msg_static_register(
47 } 37 EFL_MODEL_ERROR_NOT_FOUND_STR);
38
39 EFL_MODEL_ERROR_READ_ONLY = eina_error_msg_static_register(
40 EFL_MODEL_ERROR_READ_ONLY_STR);
41
42 EFL_MODEL_ERROR_INIT_FAILED = eina_error_msg_static_register(
43 EFL_MODEL_ERROR_INIT_FAILED_STR);
44
45 EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register(
46 EFL_MODEL_ERROR_PERMISSION_DENIED_STR);
47
48 return EINA_TRUE;
48} 49}
49 50
50EAPI Eina_Accessor * 51EAPI Eina_Accessor*
51efl_model_list_slice(Eina_List *list, unsigned start, unsigned count) 52efl_model_list_slice(Eina_List *list, unsigned start, unsigned count)
52{ 53{
53 fprintf(stderr, "efl_model_list_slice\n"); 54 if (!list) return NULL;
54 if ((start == 0) && (count == 0)) 55
56 if ((start == 0) && (count == 0)) /* this is full data */
55 { 57 {
56 fprintf(stderr, "efl_model_list_slice start == 0 count == 0\n"); 58 /*
59 * children_accessor will be set to NULL by
60 * eina_list_accessor_new if the later fails.
61 */
57 return eina_list_accessor_new(list); 62 return eina_list_accessor_new(list);
58 } 63 }
59 64
60 Eina_List *nth_list = eina_list_nth_list(list, (start - 1)); 65 Eo *child;
61 if (!nth_list) 66 Eina_List *l, *ln, *lr = NULL;
62 return NULL; 67 ln = eina_list_nth_list(list, (start-1));
68 if (!ln)
69 {
70 return NULL;
71 }
63 72
64 Eina_List *it, *result = NULL; 73 EINA_LIST_FOREACH(ln, l, child)
65 const void *data;
66 EINA_LIST_FOREACH(nth_list, it, data)
67 { 74 {
68 result = eina_list_append(result, data); 75 eo_ref(child);
69 if (eina_list_count(result) == count) 76 lr = eina_list_append(lr, child);
77 if (eina_list_count(lr) == count)
70 break; 78 break;
71 } 79 }
72 80
73 return eina_list_accessor_new(result); 81 if (!lr) return NULL;
74}
75 82
76EAPI void 83 // This may leak the children Eina_List.
77efl_model_error_notify(Efl_Model_Base *model) 84 return eina_list_accessor_new(lr);
78{
79 Efl_Model_Load load = {.status = EFL_MODEL_LOAD_STATUS_ERROR};
80 eo_event_callback_call(model, EFL_MODEL_BASE_EVENT_LOAD_STATUS, &load);
81} 85}
82 86
83EAPI void 87EAPI void
diff --git a/src/lib/eio/eio_model.c b/src/lib/eio/eio_model.c
index 6d5dba4..c1e6ee0 100644
--- a/src/lib/eio/eio_model.c
+++ b/src/lib/eio/eio_model.c
@@ -17,42 +17,20 @@
17#define MY_CLASS_NAME "Eio_Model" 17#define MY_CLASS_NAME "Eio_Model"
18 18
19static void _eio_prop_set_error_cb(void *, Eio_File *, int); 19static void _eio_prop_set_error_cb(void *, Eio_File *, int);
20static void _eio_model_efl_model_base_properties_load(Eo *, Eio_Model_Data *); 20static void _eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat);
21static void _eio_model_efl_model_base_children_load(Eo *, Eio_Model_Data *); 21static void _eio_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error);
22 22
23static void 23static void
24_load_set(Eio_Model_Data *priv, Efl_Model_Load_Status status) 24_eio_stat_do(Eio_Model_Data *priv)
25{ 25{
26 Efl_Model_Load load; 26 priv->stat_file = eio_file_direct_stat(priv->path, _eio_stat_done_cb, _eio_error_cb, priv);
27 27}
28 load.status = status;
29 if ((priv->load.status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)) &&
30 (load.status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)))
31 {
32 load.status = priv->load.status | status;
33 switch (status)
34 {
35 case EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES:
36 load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES;
37 break;
38 case EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES:
39 load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
40 break;
41 case EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN:
42 load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN;
43 break;
44 case EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN:
45 load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
46 break;
47 default: break;
48 }
49 }
50 28
51 if (priv->load.status != load.status) 29void
52 { 30_accessor_free(void *data)
53 priv->load.status = load.status; 31{
54 eo_event_callback_call(priv->obj, EFL_MODEL_BASE_EVENT_LOAD_STATUS, &load); 32 Eina_Accessor **ac = data;
55 } 33 eina_accessor_free(*ac);
56} 34}
57 35
58/** 36/**
@@ -62,25 +40,42 @@ _load_set(Eio_Model_Data *priv, Efl_Model_Load_Status status)
62static void 40static void
63_eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat) 41_eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat)
64{ 42{
65 Efl_Model_Property_Event evt; 43 _Eio_Model_Data *priv = data;
66 Eio_Model_Data *priv = data; 44 _Eio_Property_Promise* p;
67 EINA_SAFETY_ON_FALSE_RETURN(eo_ref_get(priv->obj)); 45 Eina_List *l;
68 46 EINA_LIST_FOREACH(priv->property_promises, l, p)
69 priv->is_dir = eio_file_is_dir(stat); 47 {
70 memset(&evt, 0, sizeof(Efl_Model_Property_Event)); 48 Eina_Value* v = eina_promise_owner_buffer_get(p->promise);
71 49 switch(p->property)
72 eina_value_set(priv->properties_value[EIO_MODEL_PROP_IS_DIR], eio_file_is_dir(stat)); 50 {
73 eina_value_set(priv->properties_value[EIO_MODEL_PROP_IS_LNK], eio_file_is_lnk(stat)); 51 case EIO_MODEL_PROP_IS_DIR:
74 eina_value_set(priv->properties_value[EIO_MODEL_PROP_MTIME], eio_file_mtime(stat)); 52 eina_value_setup(v, EINA_VALUE_TYPE_CHAR);
75 eina_value_set(priv->properties_value[EIO_MODEL_PROP_SIZE], eio_file_size(stat)); 53 eina_value_set(v, eio_file_is_dir(stat) ? EINA_TRUE : EINA_FALSE);
76 54 break;
77 evt.changed_properties = priv->properties_name; 55 case EIO_MODEL_PROP_IS_LNK:
78 eo_event_callback_call(priv->obj, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, &evt); 56 eina_value_setup(v, EINA_VALUE_TYPE_CHAR);
79 57 eina_value_set(v, eio_file_is_lnk(stat) ? EINA_TRUE : EINA_FALSE);
80 _load_set(priv, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES); 58 break;
59 case EIO_MODEL_PROP_MTIME:
60 eina_value_setup(v, EINA_VALUE_TYPE_TIMEVAL);
61 eina_value_set(v, eio_file_mtime(stat));
62 break;
63 case EIO_MODEL_PROP_SIZE:
64 eina_value_setup(v, EINA_VALUE_TYPE_INT64);
65 eina_value_set(v, eio_file_size(stat));
66 break;
67 default:
68 break;
69 };
70
71 eina_promise_owner_value_set(p->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
72 free(p);
73 }
74 eina_list_free(priv->property_promises);
75 priv->property_promises = NULL;
81 76
82 if (priv->load_pending & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN) 77 eio_file_cancel(priv->stat_file);
83 _eio_model_efl_model_base_children_load(priv->obj, priv); 78 priv->stat_file = NULL;
84} 79}
85 80
86static void 81static void
@@ -94,20 +89,11 @@ _eio_move_done_cb(void *data, Eio_File *handler EINA_UNUSED)
94{ 89{
95 Efl_Model_Property_Event evt; 90 Efl_Model_Property_Event evt;
96 Eio_Model_Data *priv = data; 91 Eio_Model_Data *priv = data;
97 Eina_Array *properties; 92 Eina_Array *properties = eina_array_new(20);
98 93
99 EINA_SAFETY_ON_FALSE_RETURN(eo_ref_get(priv->obj)); 94 EINA_SAFETY_ON_FALSE_RETURN(eo_ref_get(priv->obj));
100 95
101 memset(&evt, 0, sizeof(Efl_Model_Property_Event)); 96 memset(&evt, 0, sizeof(Efl_Model_Property_Event));
102
103 /**
104 * When mv is executed we update our values and
105 * notify both path and filename properties listeners.
106 */
107 eina_value_set(priv->properties_value[EIO_MODEL_PROP_PATH], priv->path);
108 eina_value_set(priv->properties_value[EIO_MODEL_PROP_FILENAME], basename(priv->path));
109
110 properties = eina_array_new(2);
111 eina_array_push(properties, _eio_model_prop_names[EIO_MODEL_PROP_PATH]); 97 eina_array_push(properties, _eio_model_prop_names[EIO_MODEL_PROP_PATH]);
112 eina_array_push(properties, _eio_model_prop_names[EIO_MODEL_PROP_FILENAME]); 98 eina_array_push(properties, _eio_model_prop_names[EIO_MODEL_PROP_FILENAME]);
113 evt.changed_properties = properties; 99 evt.changed_properties = properties;
@@ -121,7 +107,15 @@ _eio_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error)
121{ 107{
122 if (error != 0) 108 if (error != 0)
123 { 109 {
110 _Eio_Model_Data *priv = data;
111 _Eio_Property_Promise* p;
112 Eina_List *l;
124 WRN("%d: %s.", error, strerror(error)); 113 WRN("%d: %s.", error, strerror(error));
114
115 EINA_LIST_FOREACH(priv->property_promises, l, p)
116 {
117 eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_UNKNOWN);
118 }
125 } 119 }
126} 120}
127 121
@@ -245,60 +239,102 @@ _eio_error_unlink_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int
245/** 239/**
246 * Interfaces impl. 240 * Interfaces impl.
247 */ 241 */
248static Efl_Model_Load_Status 242static Eina_Array const *
249_eio_model_efl_model_base_properties_get(Eo *obj EINA_UNUSED, 243_eio_model_efl_model_base_properties_get(Eo *obj EINA_UNUSED, Eio_Model_Data *_pd)
250 Eio_Model_Data *_pd, Eina_Array * const* properties)
251{ 244{
252 Eio_Model_Data *priv = _pd; 245 Eio_Model_Data *priv = _pd;
253 246
254 EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE); 247 EINA_SAFETY_ON_NULL_RETURN_VAL(priv, NULL);
255 EINA_SAFETY_ON_NULL_RETURN_VAL(priv->obj, EINA_FALSE); 248 EINA_SAFETY_ON_NULL_RETURN_VAL(priv->obj, NULL);
256
257 *(Eina_Array **)properties = priv->properties_name;
258 249
259 return priv->load.status; 250 return priv->properties_name;
260} 251}
261 252
262/** 253/**
263 * Property Get 254 * Property Get
264 */ 255 */
265static Efl_Model_Load_Status 256static void
266_eio_model_efl_model_base_property_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char *property, const Eina_Value **value) 257_eio_model_efl_model_base_property_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char *property, Eina_Promise_Owner *promise)
267{ 258{
268 unsigned int i; 259 _Eio_Property_Name property_name;
269 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 260 const char* value = NULL;
270 EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EFL_MODEL_LOAD_STATUS_ERROR); 261
262 EINA_SAFETY_ON_NULL_RETURN(priv);
271 263
272 *value = NULL; 264 if (property == NULL)
273 if (priv->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
274 { 265 {
275 for (i = 0; i < EIO_MODEL_PROP_LAST; ++i) 266 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
276 { 267 return;
277 if (!strcmp(property, _eio_model_prop_names[i])) 268 }
278 break;
279 }
280 269
281 if ( i < EIO_MODEL_PROP_LAST) 270 if(!strcmp("filename", property))
282 { 271 {
283 *value = priv->properties_value[i]; 272 value = basename(priv->path);
284 } 273 property_name = EIO_MODEL_PROP_FILENAME;
274 }
275 else if(!strcmp("path", property))
276 {
277 value = priv->path;
278 property_name = EIO_MODEL_PROP_PATH;
279 }
280 else if(!strcmp("mtime", property))
281 property_name = EIO_MODEL_PROP_MTIME;
282 else if(!strcmp("is_dir", property))
283 property_name = EIO_MODEL_PROP_IS_DIR;
284 else if(!strcmp("is_lnk", property))
285 property_name = EIO_MODEL_PROP_IS_LNK;
286 else if(!strcmp("size", property))
287 property_name = EIO_MODEL_PROP_SIZE;
288 else
289 {
290 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
291 return;
285 } 292 }
286 293
287 return priv->load.status; 294 switch(property_name)
295 {
296 case EIO_MODEL_PROP_FILENAME:
297 case EIO_MODEL_PROP_PATH:
298 {
299 Eina_Value* v = eina_promise_owner_buffer_get(promise);
300 eina_value_setup(v, EINA_VALUE_TYPE_STRING);
301 eina_value_set(v, value);
302 eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
303 }
304 break;
305 default:
306 {
307 _Eio_Property_Promise* p = calloc(1, sizeof(_Eio_Property_Promise));
308 p->promise = promise;
309 p->property = property_name;;
310 priv->property_promises = eina_list_prepend(priv->property_promises, p);
311
312 if(!priv->stat_file)
313 _eio_stat_do(priv);
314 }
315 break;
316 }
288} 317}
289 318
290/** 319/**
291 * Property Set 320 * Property Set
292 */ 321 */
293static Efl_Model_Load_Status 322static void
294_eio_model_efl_model_base_property_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char * property, const Eina_Value *value) 323_eio_model_efl_model_base_property_set(Eo *obj EINA_UNUSED,
324 Eio_Model_Data *priv,
325 const char * property,
326 const Eina_Value *value,
327 Eina_Promise_Owner *promise)
295{ 328{
296 char *dest; 329 char *dest;
297 330
298 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EINA_FALSE); 331 EINA_SAFETY_ON_NULL_RETURN(property);
299 332
300 if (strcmp(property, "path") != 0) 333 if (strcmp(property, "path") != 0)
301 return EINA_FALSE; 334 {
335 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
336 return;
337 }
302 338
303 dest = eina_value_to_string(value); 339 dest = eina_value_to_string(value);
304 if (priv->path == NULL) 340 if (priv->path == NULL)
@@ -307,56 +343,28 @@ _eio_model_efl_model_base_property_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv
307 343
308 INF("path '%s' with filename '%s'.", priv->path, basename(priv->path)); 344 INF("path '%s' with filename '%s'.", priv->path, basename(priv->path));
309 345
310 eina_value_set(priv->properties_value[EIO_MODEL_PROP_PATH], priv->path);
311 eina_value_set(priv->properties_value[EIO_MODEL_PROP_FILENAME], basename(priv->path));
312
313 _eio_monitors_list_load(priv); 346 _eio_monitors_list_load(priv);
314 347
315 _eio_move_done_cb(priv, NULL); 348 _eio_move_done_cb(priv, NULL);
316 349 }
317 if (priv->load_pending & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES) 350 else
318 _eio_model_efl_model_base_properties_load(obj, priv); 351 {
319 else if (priv->load_pending & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN) 352 priv->move_file = eio_file_move(priv->path, dest, _eio_progress_cb, _eio_move_done_cb, _eio_prop_set_error_cb, priv);
320 _eio_model_efl_model_base_children_load(obj, priv); 353 free(priv->path);
321 354 priv->path = dest;
322 return priv->load.status;
323 } 355 }
324 356
325 priv->file = eio_file_move(priv->path, dest, _eio_progress_cb, _eio_move_done_cb, _eio_prop_set_error_cb, priv); 357 eina_promise_owner_value_set(promise, &value, NULL);
326 free(priv->path);
327 priv->path = dest;
328
329 return priv->load.status;
330}
331/**
332 * Children Count Get
333 */
334static Efl_Model_Load_Status
335_eio_model_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, unsigned int *children_count)
336{
337 /**< eina_list_count returns 'unsigned int' */
338 *children_count = eina_list_count(priv->children_list);
339 return priv->load.status;
340} 358}
341 359
342/** 360/**
343 * Properties Load 361 * Children Count Get
344 */ 362 */
345static void 363static void
346_eio_model_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eio_Model_Data *priv) 364_eio_model_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eina_Promise_Owner *promise)
347{ 365{
348 if (priv->path == NULL) 366 unsigned int c = eina_list_count(priv->children_list);
349 { 367 eina_promise_owner_value_set(promise, &c, NULL);
350 priv->load_pending |= EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
351 return;
352 }
353 priv->load_pending &= ~EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
354
355 if (!(priv->load.status & (EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES | EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES)))
356 {
357 _load_set(priv, EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES);
358 priv->file = eio_file_direct_stat(priv->path, _eio_stat_done_cb, _eio_error_cb, priv);
359 }
360} 368}
361 369
362static void 370static void
@@ -419,14 +427,28 @@ _eio_main_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina
419static void 427static void
420_eio_done_children_load_cb(void *data, Eio_File *handler EINA_UNUSED) 428_eio_done_children_load_cb(void *data, Eio_File *handler EINA_UNUSED)
421{ 429{
422 unsigned long count;
423 Eio_Model_Data *priv = data; 430 Eio_Model_Data *priv = data;
424 EINA_SAFETY_ON_NULL_RETURN(priv); 431 EINA_SAFETY_ON_NULL_RETURN(priv);
425 432
426 count = eina_list_count(priv->children_list); 433 eio_file_cancel(priv->listing_file);
427 _load_set(priv, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN); 434 priv->listing_file = NULL;
435 priv->is_listed = EINA_TRUE;
436 priv->is_listing = EINA_FALSE;
428 437
429 eo_event_callback_call(priv->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count); 438 Eina_List* i;
439 _Eio_Children_Slice_Promise* p;
440 EINA_LIST_FOREACH(priv->children_promises, i, p)
441 {
442 Eina_Accessor* accessor = efl_model_list_slice(priv->children_list, p->start, p->count);
443 if (accessor)
444 eina_promise_owner_value_set(p->promise, &accessor, &_accessor_free);
445 else
446 eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_NOT_FOUND);
447 free(p);
448 }
449
450 eina_list_free(priv->children_promises);
451 priv->children_promises = NULL;
430} 452}
431 453
432static void 454static void
@@ -439,71 +461,6 @@ _eio_error_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, int error
439 461
440 EINA_LIST_FREE(priv->children_list, child) 462 EINA_LIST_FREE(priv->children_list, child)
441 eo_unref(child); 463 eo_unref(child);
442
443 _load_set(priv, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
444}
445
446/**
447 * Children Load
448 */
449static void
450_eio_model_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
451{
452 if (priv->path == NULL)
453 {
454 priv->load_pending |= EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
455 return;
456 }
457
458 priv->load_pending &= ~EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
459
460 if (priv->children_list == NULL && priv->is_dir &&
461 !(priv->load.status & (EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN | EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN)))
462 {
463 _eio_model_efl_model_base_monitor_add(priv);
464
465 _load_set(priv, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
466 eio_file_direct_ls(priv->path, _eio_filter_children_load_cb,
467 _eio_main_children_load_cb, _eio_done_children_load_cb,
468 _eio_error_children_load_cb, priv);
469 }
470}
471
472/**
473 * Load
474 */
475static void
476_eio_model_efl_model_base_load(Eo *obj, Eio_Model_Data *priv)
477{
478 priv->load_pending |= EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
479 _eio_model_efl_model_base_properties_load(obj, priv);
480}
481
482/**
483 * Load status get
484 */
485static Efl_Model_Load_Status
486_eio_model_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
487{
488 return priv->load.status;
489}
490
491/**
492 * Unload
493 */
494static void
495_eio_model_efl_model_base_unload(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
496{
497 if (!(priv->load.status & EFL_MODEL_LOAD_STATUS_UNLOADED))
498 {
499 Eo *child;
500 EINA_LIST_FREE(priv->children_list, child)
501 {
502 eo_unref(child);
503 }
504
505 _load_set(priv, EFL_MODEL_LOAD_STATUS_UNLOADED);
506 }
507} 464}
508 465
509static void 466static void
@@ -546,80 +503,64 @@ _eio_model_efl_model_base_child_del_stat(void* data, Eio_File* handler EINA_UNUS
546/** 503/**
547 * Child Remove 504 * Child Remove
548 */ 505 */
549static Efl_Model_Load_Status 506static void
550_eio_model_efl_model_base_child_del(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eo *child) 507_eio_model_efl_model_base_child_del(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eo *child)
551{ 508{
552 Eio_Model_Data *child_priv; 509 Eio_Model_Data *child_priv;
553 EINA_SAFETY_ON_NULL_RETURN_VAL(child, EFL_MODEL_LOAD_STATUS_ERROR); 510 EINA_SAFETY_ON_NULL_RETURN(child);
554 511
555 child_priv = eo_data_scope_get(child, MY_CLASS); 512 child_priv = eo_data_scope_get(child, MY_CLASS);
556 EINA_SAFETY_ON_NULL_RETURN_VAL(child_priv, EFL_MODEL_LOAD_STATUS_ERROR); 513 EINA_SAFETY_ON_NULL_RETURN(child_priv);
557 514
558 eio_file_direct_stat(child_priv->path, 515 priv->del_file = eio_file_direct_stat(child_priv->path,
559 &_eio_model_efl_model_base_child_del_stat, 516 &_eio_model_efl_model_base_child_del_stat,
560 &_eio_error_unlink_cb, 517 &_eio_error_unlink_cb,
561 child); 518 child);
562 eo_ref(child); 519 eo_ref(child);
563 return priv->load.status;
564} 520}
565 521
566/** 522/**
567 * Children Slice Get 523 * Children Slice Get
568 */ 524 */
569static Efl_Model_Load_Status 525static void
570_eio_model_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, 526_eio_model_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv,
571 unsigned start, unsigned count, Eina_Accessor **children_accessor) 527 unsigned start, unsigned count, Eina_Promise_Owner *promise)
572{ 528{
573 Eo *child;
574 Eina_List *l, *ln, *lr = NULL;
575
576 /** 529 /**
577 * children must be already loaded otherwise we do nothing 530 * children must be already loaded otherwise we do nothing
578 * and parameter is set to NULL. 531 * and parameter is set to NULL.
579 */ 532 */
580 533
581 if (!(priv->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)) 534 if (!(priv->is_listed))
582 { 535 {
583 /** 536 _Eio_Children_Slice_Promise* p = calloc(1, sizeof(struct _Eio_Children_Slice_Promise));
584 * Status should be in either unloaded state or unitialized 537 p->promise = promise;
585 * so we simply return without much alarm. 538 p->start = start;
586 */ 539 p->count = count;
587 *children_accessor = NULL;
588 return priv->load.status;
589 }
590 540
591 if ((start == 0) && (count == 0)) /* this is full data */ 541 priv->children_promises = eina_list_prepend(priv->children_promises, p);
592 {
593 /*
594 * children_accessor will be set to NULL by
595 * eina_list_accessor_new if the later fails.
596 */
597 *children_accessor = eina_list_accessor_new(priv->children_list);
598 }
599 else /* this is only slice */
600 {
601 ln = eina_list_nth_list(priv->children_list, (start-1));
602 if (!ln)
603 {
604 *children_accessor = NULL;
605 ERR("children not found !");
606 return priv->load.status;
607 }
608 542
609 EINA_LIST_FOREACH(ln, l, child) 543 _eio_model_efl_model_base_monitor_add(priv);
610 { 544
611 eo_ref(child); 545
612 lr = eina_list_append(lr, child); 546 if (priv->is_listing == EINA_FALSE)
613 if (eina_list_count(lr) == count) 547 {
614 break; 548 priv->is_listing = EINA_TRUE;
615 } 549 eio_file_direct_ls(priv->path, _eio_filter_children_load_cb,
616 // This may leak the children Eina_List. 550 _eio_main_children_load_cb, _eio_done_children_load_cb,
617 *children_accessor = eina_list_accessor_new(lr); 551 _eio_error_children_load_cb, priv);
552 }
553 return;
618 } 554 }
619 555
620 return priv->load.status; 556 Eina_Accessor* accessor = efl_model_list_slice(priv->children_list, start, count);
557 if (accessor)
558 eina_promise_owner_value_set(promise, &accessor, &_accessor_free);
559 else
560 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
621} 561}
622 562
563
623/** 564/**
624 * Class definitions 565 * Class definitions
625 */ 566 */
@@ -629,20 +570,13 @@ _eio_model_eo_base_constructor(Eo *obj, Eio_Model_Data *priv)
629 obj = eo_constructor(eo_super(obj, MY_CLASS)); 570 obj = eo_constructor(eo_super(obj, MY_CLASS));
630 unsigned int i; 571 unsigned int i;
631 priv->obj = obj; 572 priv->obj = obj;
573 priv->is_listed = priv->is_listing = EINA_FALSE;
632 574
633 priv->properties_name = eina_array_new(EIO_MODEL_PROP_LAST); 575 priv->properties_name = eina_array_new(EIO_MODEL_PROP_LAST);
634 EINA_SAFETY_ON_NULL_RETURN_VAL(priv->properties_name, NULL); 576 EINA_SAFETY_ON_NULL_RETURN_VAL(priv->properties_name, NULL);
635 for (i = 0; i < EIO_MODEL_PROP_LAST; ++i) 577 for (i = 0; i < EIO_MODEL_PROP_LAST; ++i)
636 eina_array_push(priv->properties_name, _eio_model_prop_names[i]); 578 eina_array_push(priv->properties_name, _eio_model_prop_names[i]);
637 579
638 priv->properties_value[EIO_MODEL_PROP_FILENAME] = eina_value_new(EINA_VALUE_TYPE_STRING);
639 priv->properties_value[EIO_MODEL_PROP_PATH] = eina_value_new(EINA_VALUE_TYPE_STRING);
640 priv->properties_value[EIO_MODEL_PROP_MTIME] = eina_value_new(EINA_VALUE_TYPE_TIMEVAL);
641 priv->properties_value[EIO_MODEL_PROP_IS_DIR] = eina_value_new(EINA_VALUE_TYPE_INT);
642 priv->properties_value[EIO_MODEL_PROP_IS_LNK] = eina_value_new(EINA_VALUE_TYPE_INT);
643 priv->properties_value[EIO_MODEL_PROP_SIZE] = eina_value_new(EINA_VALUE_TYPE_INT64);
644
645 priv->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
646 priv->monitor = NULL; 580 priv->monitor = NULL;
647 eina_spinlock_new(&priv->filter_lock); 581 eina_spinlock_new(&priv->filter_lock);
648 582
@@ -654,9 +588,6 @@ _eio_model_path_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char *path)
654{ 588{
655 priv->path = strdup(path); 589 priv->path = strdup(path);
656 590
657 eina_value_set(priv->properties_value[EIO_MODEL_PROP_PATH], priv->path);
658 eina_value_set(priv->properties_value[EIO_MODEL_PROP_FILENAME], basename(priv->path));
659
660 priv->monitor = NULL; 591 priv->monitor = NULL;
661 _eio_monitors_list_load(priv); 592 _eio_monitors_list_load(priv);
662} 593}
@@ -665,7 +596,7 @@ static void
665_eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv) 596_eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv)
666{ 597{
667 Eo *child; 598 Eo *child;
668 unsigned int i; 599 /* unsigned int i; */
669 600
670 if (priv->monitor) 601 if (priv->monitor)
671 eio_monitor_del(priv->monitor); 602 eio_monitor_del(priv->monitor);
@@ -675,11 +606,6 @@ _eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv)
675 if (priv->properties_name) 606 if (priv->properties_name)
676 eina_array_free(priv->properties_name); 607 eina_array_free(priv->properties_name);
677 608
678 for (i = 0; i < EIO_MODEL_PROP_LAST; ++i)
679 {
680 eina_value_free(priv->properties_value[i]);
681 }
682
683 EINA_LIST_FREE(priv->children_list, child) 609 EINA_LIST_FREE(priv->children_list, child)
684 eo_unref(child); 610 eo_unref(child);
685 611
diff --git a/src/lib/eio/eio_model.eo b/src/lib/eio/eio_model.eo
index d200a3f..407d79f 100644
--- a/src/lib/eio/eio_model.eo
+++ b/src/lib/eio/eio_model.eo
@@ -15,7 +15,7 @@ class Eio.Model (Eo.Base, Efl.Model.Base)
15 by returning either EINA_FALSE, to abort the notification or 15 by returning either EINA_FALSE, to abort the notification or
16 EINA_TRUE to keep it. 16 EINA_TRUE to keep it.
17 17
18 See also @Efl.Model.Base.children_slice.get. 18 See also @Efl.Model.Base.children_slice_get.
19 19
20 @since 1.11 20 @since 1.11
21 ]] 21 ]]
@@ -38,16 +38,11 @@ class Eio.Model (Eo.Base, Efl.Model.Base)
38 Eo.Base.constructor; 38 Eo.Base.constructor;
39 Eo.Base.destructor; 39 Eo.Base.destructor;
40 Efl.Model.Base.properties.get; 40 Efl.Model.Base.properties.get;
41 Efl.Model.Base.properties_load; 41 Efl.Model.Base.property_set;
42 Efl.Model.Base.property.set; 42 Efl.Model.Base.property_get;
43 Efl.Model.Base.property.get;
44 Efl.Model.Base.load;
45 Efl.Model.Base.load_status.get;
46 Efl.Model.Base.unload;
47 Efl.Model.Base.child_add; 43 Efl.Model.Base.child_add;
48 Efl.Model.Base.child_del; 44 Efl.Model.Base.child_del;
49 Efl.Model.Base.children_slice.get; 45 Efl.Model.Base.children_slice_get;
50 Efl.Model.Base.children_count.get; 46 Efl.Model.Base.children_count_get;
51 Efl.Model.Base.children_load;
52 } 47 }
53} 48}
diff --git a/src/lib/eio/eio_model_private.h b/src/lib/eio/eio_model_private.h
index adeb9cf..edf64fb 100644
--- a/src/lib/eio/eio_model_private.h
+++ b/src/lib/eio/eio_model_private.h
@@ -14,7 +14,7 @@ struct _Eio_Model_Monitor_Data
14 int mon_event_child_del[3]; /**< plus EIO_MONITOR_ERROR */ 14 int mon_event_child_del[3]; /**< plus EIO_MONITOR_ERROR */
15}; 15};
16 16
17enum { 17typedef enum _Eio_Property_Name {
18 EIO_MODEL_PROP_FILENAME = 0, 18 EIO_MODEL_PROP_FILENAME = 0,
19 EIO_MODEL_PROP_PATH, 19 EIO_MODEL_PROP_PATH,
20 EIO_MODEL_PROP_MTIME, 20 EIO_MODEL_PROP_MTIME,
@@ -22,7 +22,7 @@ enum {
22 EIO_MODEL_PROP_IS_LNK, 22 EIO_MODEL_PROP_IS_LNK,
23 EIO_MODEL_PROP_SIZE, 23 EIO_MODEL_PROP_SIZE,
24 EIO_MODEL_PROP_LAST 24 EIO_MODEL_PROP_LAST
25}; 25} _Eio_Property_Name;
26 26
27static const char* _eio_model_prop_names[] = 27static const char* _eio_model_prop_names[] =
28{ 28{
@@ -34,18 +34,37 @@ static const char* _eio_model_prop_names[] =
34 [EIO_MODEL_PROP_SIZE] = "size" 34 [EIO_MODEL_PROP_SIZE] = "size"
35}; 35};
36 36
37typedef struct _Eio_Property_Promise _Eio_Property_Promise;
38struct _Eio_Property_Promise
39{
40 _Eio_Property_Name property;
41 Eina_Promise_Owner* promise;
42};
43
44typedef struct _Eio_Children_Slice_Promise _Eio_Children_Slice_Promise;
45struct _Eio_Children_Slice_Promise
46{
47 unsigned start;
48 unsigned count;
49 Eina_Promise_Owner* promise;
50};
51
52typedef struct _Eio_Model_Data _Eio_Model_Data;
37struct _Eio_Model_Data 53struct _Eio_Model_Data
38{ 54{
39 Eo *obj; 55 Eo *obj;
40 char *path; 56 char *path;
41 Eina_Array *properties_name; 57 Eina_Array *properties_name;
42 Eina_Value *properties_value[EIO_MODEL_PROP_LAST]; 58 Eina_Bool is_listed : 1;
43 Efl_Model_Load load; 59 Eina_Bool is_listing : 1;
44 int load_pending;
45 Eina_List *children_list; 60 Eina_List *children_list;
61 Eina_List *property_promises;
62 Eina_List *children_promises;
46 /**< EIO data */ 63 /**< EIO data */
47 Eio_File *file; 64 Eio_File *stat_file;
48 Eina_Bool is_dir; 65 Eio_File *listing_file;
66 Eio_File *move_file;
67 Eio_File *del_file;
49 Eio_Monitor *monitor; 68 Eio_Monitor *monitor;
50 Eio_Model_Monitor_Data mon; 69 Eio_Model_Monitor_Data mon;
51 int cb_count_child_add; /**< monitor reference counter for child add event */ 70 int cb_count_child_add; /**< monitor reference counter for child add event */
diff --git a/src/lib/eldbus/eldbus_model_arguments.c b/src/lib/eldbus/eldbus_model_arguments.c
index 50bbc80..d3271f0 100644
--- a/src/lib/eldbus/eldbus_model_arguments.c
+++ b/src/lib/eldbus/eldbus_model_arguments.c
@@ -5,6 +5,7 @@
5#include "eldbus_model_arguments_private.h" 5#include "eldbus_model_arguments_private.h"
6#include "eldbus_model_private.h" 6#include "eldbus_model_private.h"
7 7
8#include <Ecore.h>
8#include <Eina.h> 9#include <Eina.h>
9#include <Eldbus.h> 10#include <Eldbus.h>
10 11
@@ -13,8 +14,7 @@
13 14
14#define ARGUMENT_FORMAT "arg%u" 15#define ARGUMENT_FORMAT "arg%u"
15 16
16static void _eldbus_model_arguments_efl_model_base_properties_load(Eo *, Eldbus_Model_Arguments_Data *); 17static void _eldbus_model_arguments_properties_load(Eldbus_Model_Arguments_Data *);
17static void _eldbus_model_arguments_efl_model_base_children_load(Eo *, Eldbus_Model_Arguments_Data *);
18static void _eldbus_model_arguments_unload(Eldbus_Model_Arguments_Data *); 18static void _eldbus_model_arguments_unload(Eldbus_Model_Arguments_Data *);
19static Eina_Bool _eldbus_model_arguments_is_input_argument(Eldbus_Model_Arguments_Data *, const char *); 19static Eina_Bool _eldbus_model_arguments_is_input_argument(Eldbus_Model_Arguments_Data *, const char *);
20static Eina_Bool _eldbus_model_arguments_is_output_argument(Eldbus_Model_Arguments_Data *, const char *); 20static Eina_Bool _eldbus_model_arguments_is_output_argument(Eldbus_Model_Arguments_Data *, const char *);
@@ -33,7 +33,6 @@ _eldbus_model_arguments_eo_base_constructor(Eo *obj, Eldbus_Model_Arguments_Data
33 obj = eo_constructor(eo_super(obj, MY_CLASS)); 33 obj = eo_constructor(eo_super(obj, MY_CLASS));
34 34
35 pd->obj = obj; 35 pd->obj = obj;
36 pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
37 pd->properties_array = NULL; 36 pd->properties_array = NULL;
38 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free)); 37 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free));
39 pd->pending_list = NULL; 38 pd->pending_list = NULL;
@@ -71,31 +70,23 @@ _eldbus_model_arguments_eo_base_destructor(Eo *obj, Eldbus_Model_Arguments_Data
71 eo_destructor(eo_super(obj, MY_CLASS)); 70 eo_destructor(eo_super(obj, MY_CLASS));
72} 71}
73 72
74static Efl_Model_Load_Status 73static Eina_Array const *
75_eldbus_model_arguments_efl_model_base_properties_get(Eo *obj EINA_UNUSED, 74_eldbus_model_arguments_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
76 Eldbus_Model_Arguments_Data *pd, 75 Eldbus_Model_Arguments_Data *pd)
77 Eina_Array * const* properties_array)
78{ 76{
79 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR); 77 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
80 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
81 78
82 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)) 79 _eldbus_model_arguments_properties_load(pd);
83 { 80 return pd->properties_array;
84 ERR("%s", "o not loaded.");
85 return EFL_MODEL_LOAD_STATUS_ERROR;
86 }
87
88 *(Eina_Array**)properties_array = pd->properties_array;
89 return pd->load.status;
90} 81}
91 82
92static void 83static void
93_eldbus_model_arguments_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd) 84_eldbus_model_arguments_properties_load(Eldbus_Model_Arguments_Data *pd)
94{ 85{
95 unsigned int arguments_count; 86 unsigned int arguments_count;
96 unsigned int i; 87 unsigned int i;
97 88
98 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES) 89 if (pd->properties_array)
99 return; 90 return;
100 91
101 arguments_count = eina_list_count(pd->arguments); 92 arguments_count = eina_list_count(pd->arguments);
@@ -120,86 +111,55 @@ _eldbus_model_arguments_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldb
120 value = eina_value_new(type); 111 value = eina_value_new(type);
121 eina_hash_add(pd->properties_hash, name, value); 112 eina_hash_add(pd->properties_hash, name, value);
122 } 113 }
123
124 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
125} 114}
126 115
127static Efl_Model_Load_Status 116static void
128_eldbus_model_arguments_efl_model_base_property_set(Eo *obj EINA_UNUSED, 117_eldbus_model_arguments_efl_model_base_property_set(Eo *obj EINA_UNUSED,
129 Eldbus_Model_Arguments_Data *pd, 118 Eldbus_Model_Arguments_Data *pd,
130 const char *property, 119 const char *property,
131 Eina_Value const* value) 120 Eina_Value const* value,
121 Eina_Promise_Owner *promise)
132{ 122{
133 Eina_Value *prop_value; 123 Eina_Value *prop_value;
134 Eina_Bool ret;
135 124
136 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 125 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
137 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR); 126 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
138 DBG("(%p): property=%s", obj, property); 127 DBG("(%p): property=%s", obj, property);
139 128
140 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)) 129 _eldbus_model_arguments_properties_load(pd);
141 return EFL_MODEL_LOAD_STATUS_ERROR;
142 130
143 if (!_eldbus_model_arguments_is_input_argument(pd, property)) 131 Eina_Bool ret = _eldbus_model_arguments_is_input_argument(pd, property);
144 { 132 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY);
145 WRN("Property (argument) not found or it is for output only: %s", property);
146 return EFL_MODEL_LOAD_STATUS_ERROR;
147 }
148 133
149 prop_value = eina_hash_find(pd->properties_hash, property); 134 prop_value = eina_hash_find(pd->properties_hash, property);
150 EINA_SAFETY_ON_NULL_RETURN_VAL(prop_value, EFL_MODEL_LOAD_STATUS_ERROR); 135 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(prop_value, promise, EFL_MODEL_ERROR_NOT_FOUND);
151 136
152 eina_value_flush(prop_value); 137 eina_value_flush(prop_value);
153 ret = eina_value_copy(value, prop_value); 138 eina_value_copy(value, prop_value);
154 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_MODEL_LOAD_STATUS_ERROR); 139 eina_promise_owner_value_set(promise, prop_value, NULL);
155
156 return pd->load.status;
157} 140}
158 141
159static Efl_Model_Load_Status 142static void
160_eldbus_model_arguments_efl_model_base_property_get(Eo *obj EINA_UNUSED, 143_eldbus_model_arguments_efl_model_base_property_get(Eo *obj EINA_UNUSED,
161 Eldbus_Model_Arguments_Data *pd, 144 Eldbus_Model_Arguments_Data *pd,
162 const char *property, 145 const char *property,
163 Eina_Value const ** value) 146 Eina_Promise_Owner *promise)
164{ 147{
165 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 148 EINA_SAFETY_ON_NULL_RETURN(promise);
166 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
167 DBG("(%p): property=%s", obj, property);
168 149
169 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)) 150 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
170 return EFL_MODEL_LOAD_STATUS_ERROR; 151 DBG("(%p): property=%s", obj, property);
171 152
172 if (!_eldbus_model_arguments_is_output_argument(pd, property)) 153 _eldbus_model_arguments_properties_load(pd);
173 {
174 WRN("Property (argument) not found or it is for input only: %s", property);
175 return EFL_MODEL_LOAD_STATUS_ERROR;
176 }
177 154
178 *value = eina_hash_find(pd->properties_hash, property); 155 Eina_Bool ret = _eldbus_model_arguments_is_output_argument(pd, property);
179 EINA_SAFETY_ON_NULL_RETURN_VAL(*value, EFL_MODEL_LOAD_STATUS_ERROR); 156 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_PERMISSION_DENIED);
180 157
181 return pd->load.status; 158 Eina_Value* value = eina_hash_find(pd->properties_hash, property);
182} 159 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_NOT_FOUND);
183 160
184static void 161 eina_value_copy(value, eina_promise_owner_buffer_get(promise));
185_eldbus_model_arguments_efl_model_base_load(Eo *obj, Eldbus_Model_Arguments_Data *pd EINA_UNUSED) 162 eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
186{
187 efl_model_properties_load(obj);
188 efl_model_children_load(obj);
189}
190
191static Efl_Model_Load_Status
192_eldbus_model_arguments_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd)
193{
194 return pd->load.status;
195}
196
197static void
198_eldbus_model_arguments_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd)
199{
200 _eldbus_model_arguments_unload(pd);
201
202 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED);
203} 163}
204 164
205static Eo * 165static Eo *
@@ -208,41 +168,30 @@ _eldbus_model_arguments_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Mod
208 return NULL; 168 return NULL;
209} 169}
210 170
211static Efl_Model_Load_Status 171static void
212_eldbus_model_arguments_efl_model_base_child_del(Eo *obj EINA_UNUSED, 172_eldbus_model_arguments_efl_model_base_child_del(Eo *obj EINA_UNUSED,
213 Eldbus_Model_Arguments_Data *pd EINA_UNUSED, 173 Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
214 Eo *child EINA_UNUSED) 174 Eo *child EINA_UNUSED)
215{ 175{
216 return EFL_MODEL_LOAD_STATUS_ERROR;
217} 176}
218 177
219static Efl_Model_Load_Status 178static void
220_eldbus_model_arguments_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, 179_eldbus_model_arguments_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
221 Eldbus_Model_Arguments_Data *pd, 180 Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
222 unsigned start EINA_UNUSED, 181 unsigned start EINA_UNUSED,
223 unsigned count EINA_UNUSED, 182 unsigned count EINA_UNUSED,
224 Eina_Accessor **children_accessor) 183 Eina_Promise_Owner *promise)
225{ 184{
226 *children_accessor = NULL; 185 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
227 return pd->load.status;
228}
229
230static Efl_Model_Load_Status
231_eldbus_model_arguments_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
232 Eldbus_Model_Arguments_Data *pd,
233 unsigned *children_count)
234{
235 *children_count = 0;
236 return pd->load.status;
237} 186}
238 187
239static void 188static void
240_eldbus_model_arguments_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd) 189_eldbus_model_arguments_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
190 Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
191 Eina_Promise_Owner *promise)
241{ 192{
242 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN) 193 unsigned count = 0;
243 return; 194 eina_promise_owner_value_set(promise, &count, NULL);
244
245 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
246} 195}
247 196
248static const char * 197static const char *
@@ -289,11 +238,13 @@ eldbus_model_arguments_process_arguments(Eldbus_Model_Arguments_Data *pd,
289 unsigned int i = 0; 238 unsigned int i = 0;
290 Eina_Bool result = EINA_FALSE; 239 Eina_Bool result = EINA_FALSE;
291 240
241 _eldbus_model_arguments_properties_load(pd);
242
292 pd->pending_list = eina_list_remove(pd->pending_list, pending); 243 pd->pending_list = eina_list_remove(pd->pending_list, pending);
293 if (eldbus_message_error_get(msg, &error_name, &error_text)) 244 if (eldbus_message_error_get(msg, &error_name, &error_text))
294 { 245 {
295 ERR("%s: %s", error_name, error_text); 246 ERR("%s: %s", error_name, error_text);
296 efl_model_error_notify(pd->obj); 247 //efl_model_error_notify(pd->obj);
297 return EINA_FALSE; 248 return EINA_FALSE;
298 } 249 }
299 250
@@ -350,6 +301,8 @@ _eldbus_model_arguments_property_set(Eldbus_Model_Arguments_Data *pd,
350 Eina_Value value; 301 Eina_Value value;
351 Eina_Bool ret; 302 Eina_Bool ret;
352 303
304 _eldbus_model_arguments_properties_load(pd);
305
353 prop_value = eina_hash_find(pd->properties_hash, property); 306 prop_value = eina_hash_find(pd->properties_hash, property);
354 EINA_SAFETY_ON_NULL_RETURN_VAL(prop_value, EINA_FALSE); 307 EINA_SAFETY_ON_NULL_RETURN_VAL(prop_value, EINA_FALSE);
355 308
@@ -372,6 +325,8 @@ _eldbus_model_arguments_is(Eldbus_Model_Arguments_Data *pd,
372 Eldbus_Introspection_Argument *argument_introspection; 325 Eldbus_Introspection_Argument *argument_introspection;
373 unsigned int i; 326 unsigned int i;
374 327
328 _eldbus_model_arguments_properties_load(pd);
329
375 i = _eldbus_model_arguments_argument_index_get(pd, argument); 330 i = _eldbus_model_arguments_argument_index_get(pd, argument);
376 if (i >= eina_array_count(pd->properties_array)) 331 if (i >= eina_array_count(pd->properties_array))
377 { 332 {
@@ -404,6 +359,7 @@ _eldbus_model_arguments_argument_index_get(Eldbus_Model_Arguments_Data *pd, cons
404 Eina_Stringshare *name; 359 Eina_Stringshare *name;
405 Eina_Array_Iterator it; 360 Eina_Array_Iterator it;
406 unsigned int i = 0; 361 unsigned int i = 0;
362 _eldbus_model_arguments_properties_load(pd);
407 363
408 EINA_ARRAY_ITER_NEXT(pd->properties_array, i, name, it) 364 EINA_ARRAY_ITER_NEXT(pd->properties_array, i, name, it)
409 { 365 {
diff --git a/src/lib/eldbus/eldbus_model_arguments.eo b/src/lib/eldbus/eldbus_model_arguments.eo
index 3e4e51b..e627843 100644
--- a/src/lib/eldbus/eldbus_model_arguments.eo
+++ b/src/lib/eldbus/eldbus_model_arguments.eo
@@ -27,17 +27,12 @@ class Eldbus.Model_Arguments (Eo.Base, Efl.Model.Base) {
27 Eo.Base.constructor; 27 Eo.Base.constructor;
28 Eo.Base.destructor; 28 Eo.Base.destructor;
29 Efl.Model.Base.properties.get; 29 Efl.Model.Base.properties.get;
30 Efl.Model.Base.properties_load; 30 Efl.Model.Base.property_set;
31 Efl.Model.Base.property.set; 31 Efl.Model.Base.property_get;
32 Efl.Model.Base.property.get;
33 Efl.Model.Base.load;
34 Efl.Model.Base.load_status.get;
35 Efl.Model.Base.unload;
36 Efl.Model.Base.child_add; 32 Efl.Model.Base.child_add;
37 Efl.Model.Base.child_del; 33 Efl.Model.Base.child_del;
38 Efl.Model.Base.children_slice.get; 34 Efl.Model.Base.children_slice_get;
39 Efl.Model.Base.children_count.get; 35 Efl.Model.Base.children_count_get;
40 Efl.Model.Base.children_load;
41 } 36 }
42 constructors { 37 constructors {
43 .constructor; 38 .constructor;
diff --git a/src/lib/eldbus/eldbus_model_arguments_private.h b/src/lib/eldbus/eldbus_model_arguments_private.h
index 08e65d8..06aa1ae 100644
--- a/src/lib/eldbus/eldbus_model_arguments_private.h
+++ b/src/lib/eldbus/eldbus_model_arguments_private.h
@@ -13,7 +13,6 @@ typedef struct _Eldbus_Model_Arguments_Data Eldbus_Model_Arguments_Data;
13struct _Eldbus_Model_Arguments_Data 13struct _Eldbus_Model_Arguments_Data
14{ 14{
15 Eo *obj; 15 Eo *obj;
16 Efl_Model_Load load;
17 Eldbus_Proxy *proxy; 16 Eldbus_Proxy *proxy;
18 Eina_Array *properties_array; 17 Eina_Array *properties_array;
19 Eina_Hash *properties_hash; 18 Eina_Hash *properties_hash;
diff --git a/src/lib/eldbus/eldbus_model_connection.c b/src/lib/eldbus/eldbus_model_connection.c
index e8f93fe..07da95d 100644
--- a/src/lib/eldbus/eldbus_model_connection.c
+++ b/src/lib/eldbus/eldbus_model_connection.c
@@ -2,6 +2,7 @@
2# include <config.h> 2# include <config.h>
3#endif 3#endif
4 4
5#include <Ecore.h>
5#include "eldbus_model_connection_private.h" 6#include "eldbus_model_connection_private.h"
6#include "eldbus_model_private.h" 7#include "eldbus_model_private.h"
7 8
@@ -10,8 +11,7 @@
10 11
11#define UNIQUE_NAME_PROPERTY "unique_name" 12#define UNIQUE_NAME_PROPERTY "unique_name"
12 13
13static void _eldbus_model_connection_efl_model_base_properties_load(Eo *, Eldbus_Model_Connection_Data *); 14
14static void _eldbus_model_connection_efl_model_base_children_load(Eo *, Eldbus_Model_Connection_Data *);
15static void _eldbus_model_connection_names_list_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 15static void _eldbus_model_connection_names_list_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
16static void _eldbus_model_connection_connect(Eldbus_Model_Connection_Data *); 16static void _eldbus_model_connection_connect(Eldbus_Model_Connection_Data *);
17static void _eldbus_model_connection_disconnect(Eldbus_Model_Connection_Data *); 17static void _eldbus_model_connection_disconnect(Eldbus_Model_Connection_Data *);
@@ -23,7 +23,7 @@ _eldbus_model_connection_eo_base_constructor(Eo *obj, Eldbus_Model_Connection_Da
23 obj = eo_constructor(eo_super(obj, MY_CLASS)); 23 obj = eo_constructor(eo_super(obj, MY_CLASS));
24 24
25 pd->obj = obj; 25 pd->obj = obj;
26 pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED; 26 pd->is_listed = EINA_FALSE;
27 pd->connection = NULL; 27 pd->connection = NULL;
28 pd->properties_array = NULL; 28 pd->properties_array = NULL;
29 pd->children_list = NULL; 29 pd->children_list = NULL;
@@ -58,104 +58,66 @@ _eldbus_model_connection_eo_base_destructor(Eo *obj, Eldbus_Model_Connection_Dat
58 eo_destructor(eo_super(obj, MY_CLASS)); 58 eo_destructor(eo_super(obj, MY_CLASS));
59} 59}
60 60
61static Efl_Model_Load_Status 61static Eina_Array const *
62_eldbus_model_connection_efl_model_base_properties_get(Eo *obj EINA_UNUSED, 62_eldbus_model_connection_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
63 Eldbus_Model_Connection_Data *pd, 63 Eldbus_Model_Connection_Data *pd)
64 Eina_Array * const* properties_array)
65{ 64{
66 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR); 65 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
67 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR); 66 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, NULL);
68 67
69 if (pd->properties_array == NULL) 68 if (pd->properties_array == NULL)
70 { 69 {
71 Eina_Bool ret; 70 Eina_Bool ret;
72 71
73 pd->properties_array = eina_array_new(1); 72 pd->properties_array = eina_array_new(1);
74 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, EFL_MODEL_LOAD_STATUS_ERROR); 73 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, NULL);
75 74
76 ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY); 75 ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY);
77 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_MODEL_LOAD_STATUS_ERROR); 76 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
78 } 77 }
79 78
80 *(Eina_Array**)properties_array = pd->properties_array; 79 return pd->properties_array;
81 return pd->load.status;
82} 80}
83 81
84static void
85_eldbus_model_connection_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
86{
87 const char *unique_name;
88 Eina_Bool ret;
89
90 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
91 return;
92
93 if (!pd->connection)
94 _eldbus_model_connection_connect(pd);
95
96 pd->unique_name = eina_value_new(EINA_VALUE_TYPE_STRING);
97 EINA_SAFETY_ON_NULL_RETURN(pd->unique_name);
98 82
99 unique_name = eldbus_connection_unique_name_get(pd->connection); 83static void
100 ret = eina_value_set(pd->unique_name, unique_name);
101 EINA_SAFETY_ON_FALSE_RETURN(ret);
102
103 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
104}
105
106static Efl_Model_Load_Status
107_eldbus_model_connection_efl_model_base_property_set(Eo *obj EINA_UNUSED, 84_eldbus_model_connection_efl_model_base_property_set(Eo *obj EINA_UNUSED,
108 Eldbus_Model_Connection_Data *pd EINA_UNUSED, 85 Eldbus_Model_Connection_Data *pd EINA_UNUSED,
109 const char *property EINA_UNUSED, 86 const char *property,
110 Eina_Value const* value EINA_UNUSED) 87 Eina_Value const* value EINA_UNUSED,
88 Eina_Promise_Owner *promise)
111{ 89{
112 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 90 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
113 DBG("(%p): property=%s", obj, property); 91 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_READ_ONLY);
114 return EFL_MODEL_LOAD_STATUS_ERROR;
115} 92}
116 93
117static Efl_Model_Load_Status 94static void
118_eldbus_model_connection_efl_model_base_property_get(Eo *obj EINA_UNUSED, 95_eldbus_model_connection_efl_model_base_property_get(Eo *obj EINA_UNUSED,
119 Eldbus_Model_Connection_Data *pd, 96 Eldbus_Model_Connection_Data *pd,
120 const char *property, 97 const char *property,
121 Eina_Value const **value) 98 Eina_Promise_Owner *promise)
122{ 99{
123 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 100 EINA_SAFETY_ON_NULL_RETURN(promise);
124 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
125 DBG("(%p): property=%s", obj, property); 101 DBG("(%p): property=%s", obj, property);
126 102
127 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
128 return EFL_MODEL_LOAD_STATUS_ERROR;
129
130 if (strcmp(property, UNIQUE_NAME_PROPERTY) != 0)
131 return EFL_MODEL_LOAD_STATUS_ERROR;
132
133 *value = pd->unique_name;
134 return pd->load.status;
135}
136
137static void
138_eldbus_model_connection_efl_model_base_load(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
139{
140 if (!pd->connection) 103 if (!pd->connection)
141 _eldbus_model_connection_connect(pd); 104 _eldbus_model_connection_connect(pd);
142 105
143 _eldbus_model_connection_efl_model_base_properties_load(obj, pd); 106 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
144 _eldbus_model_connection_efl_model_base_children_load(obj, pd);
145}
146 107
147static Efl_Model_Load_Status 108 if (pd->unique_name == NULL)
148_eldbus_model_connection_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd) 109 {
149{ 110 const char *unique_name;
150 return pd->load.status;
151}
152 111
153static void 112 unique_name = eldbus_connection_unique_name_get(pd->connection);
154_eldbus_model_connection_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd) 113 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND);
155{ 114 pd->unique_name = strdup(unique_name);
156 _eldbus_model_connection_clear(pd); 115 }
157 116
158 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED); 117 Eina_Value* v = eina_promise_owner_buffer_get(promise);
118 eina_value_setup(v, EINA_VALUE_TYPE_STRING);
119 eina_value_set(v, pd->unique_name);
120 eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
159} 121}
160 122
161static Eo * 123static Eo *
@@ -164,56 +126,70 @@ _eldbus_model_connection_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Mo
164 return NULL; 126 return NULL;
165} 127}
166 128
167static Efl_Model_Load_Status 129static void
168_eldbus_model_connection_efl_model_base_child_del(Eo *obj EINA_UNUSED, 130_eldbus_model_connection_efl_model_base_child_del(Eo *obj EINA_UNUSED,
169 Eldbus_Model_Connection_Data *pd EINA_UNUSED, 131 Eldbus_Model_Connection_Data *pd EINA_UNUSED,
170 Eo *child EINA_UNUSED) 132 Eo *child EINA_UNUSED)
171{ 133{
172 return EFL_MODEL_LOAD_STATUS_ERROR;
173} 134}
174 135
175static Efl_Model_Load_Status 136static void
176_eldbus_model_connection_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, 137_eldbus_model_connection_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
177 Eldbus_Model_Connection_Data *pd, 138 Eldbus_Model_Connection_Data *pd,
178 unsigned start, 139 unsigned start,
179 unsigned count, 140 unsigned count,
180 Eina_Accessor **children_accessor) 141 Eina_Promise_Owner *promise)
181{ 142{
182 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)) 143 _Eldbus_Children_Slice_Promise* data;
144 Eldbus_Pending *pending;
145
146 if (!pd->connection)
147 _eldbus_model_connection_connect(pd);
148
149 if (pd->is_listed)
183 { 150 {
184 WRN("(%p): Children not loaded", obj); 151 Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
185 *children_accessor = NULL; 152 eina_promise_owner_value_set(promise, &ac, (Eina_Promise_Free_Cb)&_accessor_free);
186 return pd->load.status; 153 return;
187 } 154 }
188 155
189 *children_accessor = efl_model_list_slice(pd->children_list, start, count); 156 data = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
190 return pd->load.status; 157 EINA_SAFETY_ON_NULL_RETURN(data);
191} 158 data->promise = promise;
159 data->start = start;
160 data->count = count;
192 161
193static Efl_Model_Load_Status 162 pd->children_promises = eina_list_prepend(pd->children_promises, data);
194_eldbus_model_connection_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, 163
195 Eldbus_Model_Connection_Data *pd, 164 if (pd->pending_list == NULL)
196 unsigned *children_count) 165 {
197{ 166 pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
198 *children_count = eina_list_count(pd->children_list); 167 pd->pending_list = eina_list_append(pd->pending_list, pending);
199 return pd->load.status; 168 }
200} 169}
201 170
202static void 171static void
203_eldbus_model_connection_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd) 172_eldbus_model_connection_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
173 Eldbus_Model_Connection_Data *pd,
174 Eina_Promise_Owner *promise)
204{ 175{
205 Eldbus_Pending *pending; 176 Eldbus_Pending *pending;
206
207 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
208 return;
209
210 if (!pd->connection) 177 if (!pd->connection)
211 _eldbus_model_connection_connect(pd); 178 _eldbus_model_connection_connect(pd);
212 179
213 pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd); 180 if (pd->is_listed)
214 pd->pending_list = eina_list_append(pd->pending_list, pending); 181 {
182 unsigned int c = eina_list_count(pd->children_list);
183 eina_promise_owner_value_set(promise, &c, NULL);
184 return;
185 }
215 186
216 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN); 187 pd->count_promises = eina_list_prepend(pd->count_promises, promise);
188 if (pd->pending_list == NULL)
189 {
190 pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
191 pd->pending_list = eina_list_append(pd->pending_list, pending);
192 }
217} 193}
218 194
219static const char * 195static const char *
@@ -297,7 +273,7 @@ _eldbus_model_connection_clear(Eldbus_Model_Connection_Data *pd)
297 if (!pd->connection) 273 if (!pd->connection)
298 return; 274 return;
299 275
300 eina_value_free(pd->unique_name); 276 free(pd->unique_name);
301 pd->unique_name = NULL; 277 pd->unique_name = NULL;
302 278
303 EINA_LIST_FREE(pd->children_list, child) 279 EINA_LIST_FREE(pd->children_list, child)
@@ -321,17 +297,19 @@ _eldbus_model_connection_names_list_cb(void *data,
321 Eldbus_Pending *pending) 297 Eldbus_Pending *pending)
322{ 298{
323 Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*)data; 299 Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*)data;
300 _Eldbus_Children_Slice_Promise * p;
324 const char *error_name, *error_text; 301 const char *error_name, *error_text;
325 Eldbus_Message_Iter *array = NULL; 302 Eldbus_Message_Iter *array = NULL;
326 const char *bus; 303 const char *bus;
327 unsigned int count; 304 unsigned int count;
305 Eina_List* i;
328 306
329 pd->pending_list = eina_list_remove(pd->pending_list, pending); 307 pd->pending_list = eina_list_remove(pd->pending_list, pending);
330 308
331 if (eldbus_message_error_get(msg, &error_name, &error_text)) 309 if (eldbus_message_error_get(msg, &error_name, &error_text))
332 { 310 {
333 ERR("%s: %s", error_name, error_text); 311 ERR("%s: %s", error_name, error_text);
334 efl_model_error_notify(pd->obj); 312 //efl_model_error_notify(pd->obj);
335 return; 313 return;
336 } 314 }
337 315
@@ -350,11 +328,29 @@ _eldbus_model_connection_names_list_cb(void *data,
350 pd->children_list = eina_list_append(pd->children_list, child); 328 pd->children_list = eina_list_append(pd->children_list, child);
351 } 329 }
352 330
353 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
354
355 count = eina_list_count(pd->children_list); 331 count = eina_list_count(pd->children_list);
332
356 if (count) 333 if (count)
357 eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count); 334 eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count);
335
336 pd->is_listed = EINA_TRUE;
337
338 EINA_LIST_FOREACH(pd->children_promises, i, p)
339 {
340 Eina_Accessor *ac = efl_model_list_slice(pd->children_list, p->start, p->count);
341 eina_promise_owner_value_set(p->promise, &ac, (Eina_Promise_Free_Cb)&_accessor_free);
342 free(p);
343 }
344 eina_list_free(pd->children_promises);
345
346 Eina_Promise_Owner *ep;
347 EINA_LIST_FOREACH(pd->count_promises, i, ep)
348 {
349 unsigned c = eina_list_count(pd->children_list);
350 eina_promise_owner_value_set(ep, &c, NULL);
351 }
352 eina_list_free(pd->count_promises);
358} 353}
359 354
355
360#include "eldbus_model_connection.eo.c" 356#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 5e4de6a..3d797cb 100644
--- a/src/lib/eldbus/eldbus_model_connection.eo
+++ b/src/lib/eldbus/eldbus_model_connection.eo
@@ -36,17 +36,12 @@ class Eldbus.Model_Connection (Eo.Base, Efl.Model.Base) {
36 Eo.Base.constructor; 36 Eo.Base.constructor;
37 Eo.Base.destructor; 37 Eo.Base.destructor;
38 Efl.Model.Base.properties.get; 38 Efl.Model.Base.properties.get;
39 Efl.Model.Base.properties_load; 39 Efl.Model.Base.property_set;
40 Efl.Model.Base.property.set; 40 Efl.Model.Base.property_get;
41 Efl.Model.Base.property.get;
42 Efl.Model.Base.load;
43 Efl.Model.Base.load_status.get;
44 Efl.Model.Base.unload;
45 Efl.Model.Base.child_add; 41 Efl.Model.Base.child_add;
46 Efl.Model.Base.child_del; 42 Efl.Model.Base.child_del;
47 Efl.Model.Base.children_slice.get; 43 Efl.Model.Base.children_slice_get;
48 Efl.Model.Base.children_count.get; 44 Efl.Model.Base.children_count_get;
49 Efl.Model.Base.children_load;
50 } 45 }
51 constructors { 46 constructors {
52 .constructor; 47 .constructor;
diff --git a/src/lib/eldbus/eldbus_model_connection_private.h b/src/lib/eldbus/eldbus_model_connection_private.h
index 4123f92..a1636b9 100644
--- a/src/lib/eldbus/eldbus_model_connection_private.h
+++ b/src/lib/eldbus/eldbus_model_connection_private.h
@@ -13,14 +13,16 @@ 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 Efl_Model_Load load; 16 Eina_Bool is_listed : 1;
17 Eldbus_Connection *connection; 17 Eldbus_Connection *connection;
18 Eina_Array *properties_array; 18 Eina_Array *properties_array;
19 Eina_List *children_list; 19 Eina_List *children_list;
20 Eina_List *children_promises;
21 Eina_List *count_promises;
20 Eldbus_Connection_Type type; 22 Eldbus_Connection_Type type;
21 Eina_Stringshare *address; 23 Eina_Stringshare *address;
22 bool private; 24 bool private;
23 Eina_Value *unique_name; 25 char *unique_name;
24 Eina_List *pending_list; 26 Eina_List *pending_list;
25}; 27};
26 28
diff --git a/src/lib/eldbus/eldbus_model_method.c b/src/lib/eldbus/eldbus_model_method.c
index d62b8eb..76292ec 100644
--- a/src/lib/eldbus/eldbus_model_method.c
+++ b/src/lib/eldbus/eldbus_model_method.c
@@ -40,7 +40,7 @@ _eldbus_model_method_constructor(Eo *obj EINA_UNUSED,
40 pd->method = method; 40 pd->method = method;
41} 41}
42 42
43static Efl_Model_Load_Status 43static void
44_eldbus_model_method_call(Eo *obj EINA_UNUSED, Eldbus_Model_Method_Data *pd EINA_UNUSED) 44_eldbus_model_method_call(Eo *obj EINA_UNUSED, Eldbus_Model_Method_Data *pd EINA_UNUSED)
45{ 45{
46 Eldbus_Model_Arguments_Data *data = eo_data_scope_get(obj, ELDBUS_MODEL_ARGUMENTS_CLASS); 46 Eldbus_Model_Arguments_Data *data = eo_data_scope_get(obj, ELDBUS_MODEL_ARGUMENTS_CLASS);
@@ -82,11 +82,10 @@ _eldbus_model_method_call(Eo *obj EINA_UNUSED, Eldbus_Model_Method_Data *pd EINA
82 pending = eldbus_proxy_send(data->proxy, msg, _eldbus_model_method_call_cb, pd, -1); 82 pending = eldbus_proxy_send(data->proxy, msg, _eldbus_model_method_call_cb, pd, -1);
83 data->pending_list = eina_list_append(data->pending_list, pending); 83 data->pending_list = eina_list_append(data->pending_list, pending);
84 84
85 return data->load.status; 85 return;
86 86
87on_error: 87on_error:
88 eldbus_message_unref(msg); 88 eldbus_message_unref(msg);
89 return EFL_MODEL_LOAD_STATUS_ERROR;
90} 89}
91 90
92static void 91static void
diff --git a/src/lib/eldbus/eldbus_model_method.eo b/src/lib/eldbus/eldbus_model_method.eo
index 5cc05d9..b0829a6 100644
--- a/src/lib/eldbus/eldbus_model_method.eo
+++ b/src/lib/eldbus/eldbus_model_method.eo
@@ -19,10 +19,8 @@ class Eldbus.Model_Method (Eldbus.Model_Arguments) {
19 The event EMODEL_EVENT_PROPERTIES_CHANGED is raised for output arguments (properties). 19 The event EMODEL_EVENT_PROPERTIES_CHANGED is raised for output arguments (properties).
20 20
21 The event ELDBUS_MODEL_METHOD_EVENT_METHOD_CALLED is raised for a successful call. Otherwise 21 The event ELDBUS_MODEL_METHOD_EVENT_METHOD_CALLED is raised for a successful call. Otherwise
22 the event EMODEL_EVENT_LOAD_STATUS with the status set to EMODEL_LOAD_STATUS_ERROR is raised.
23 22
24 @since 1.16]] 23 @since 1.16]]
25 return: Efl.Model.Load_Status; [[#Emodel_Load_Status on success, #EMODEL_LOAD_STATUS_ERROR otherwise.]]
26 } 24 }
27 } 25 }
28 implements { 26 implements {
diff --git a/src/lib/eldbus/eldbus_model_object.c b/src/lib/eldbus/eldbus_model_object.c
index e1462b7..8791576 100644
--- a/src/lib/eldbus/eldbus_model_object.c
+++ b/src/lib/eldbus/eldbus_model_object.c
@@ -5,6 +5,7 @@
5#include "eldbus_model_object_private.h" 5#include "eldbus_model_object_private.h"
6#include "eldbus_model_private.h" 6#include "eldbus_model_private.h"
7 7
8#include <Ecore.h>
8#include <Eina.h> 9#include <Eina.h>
9 10
10#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS 11#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS
@@ -12,8 +13,6 @@
12 13
13#define UNIQUE_NAME_PROPERTY "unique_name" 14#define UNIQUE_NAME_PROPERTY "unique_name"
14 15
15static void _eldbus_model_object_efl_model_base_properties_load(Eo *, Eldbus_Model_Object_Data *);
16static void _eldbus_model_object_efl_model_base_children_load(Eo *, Eldbus_Model_Object_Data *);
17static bool _eldbus_model_object_introspect(Eldbus_Model_Object_Data *, const char *, const char *); 16static bool _eldbus_model_object_introspect(Eldbus_Model_Object_Data *, const char *, const char *);
18static void _eldbus_model_object_introspect_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 17static void _eldbus_model_object_introspect_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
19static void _eldbus_model_object_connect(Eldbus_Model_Object_Data *); 18static void _eldbus_model_object_connect(Eldbus_Model_Object_Data *);
@@ -23,13 +22,20 @@ static void _eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *, co
23static char *_eldbus_model_object_concatenate_path(const char *, const char *); 22static char *_eldbus_model_object_concatenate_path(const char *, const char *);
24static void _eldbus_model_object_create_children(Eldbus_Model_Object_Data *, Eldbus_Object *, Eina_List *); 23static void _eldbus_model_object_create_children(Eldbus_Model_Object_Data *, Eldbus_Object *, Eina_List *);
25 24
25void
26_accessor_free(void *data)
27{
28 Eina_Accessor **ac = data;
29 eina_accessor_free(*ac);
30}
31
26static Eo_Base* 32static Eo_Base*
27_eldbus_model_object_eo_base_constructor(Eo *obj, Eldbus_Model_Object_Data *pd) 33_eldbus_model_object_eo_base_constructor(Eo *obj, Eldbus_Model_Object_Data *pd)
28{ 34{
29 obj = eo_constructor(eo_super(obj, MY_CLASS)); 35 obj = eo_constructor(eo_super(obj, MY_CLASS));
30 36
31 pd->obj = obj; 37 pd->obj = obj;
32 pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED; 38 pd->is_listed = EINA_FALSE;
33 pd->connection = NULL; 39 pd->connection = NULL;
34 pd->object_list = NULL; 40 pd->object_list = NULL;
35 pd->properties_array = NULL; 41 pd->properties_array = NULL;
@@ -93,104 +99,67 @@ _eldbus_model_object_eo_base_destructor(Eo *obj, Eldbus_Model_Object_Data *pd)
93 eo_destructor(eo_super(obj, MY_CLASS)); 99 eo_destructor(eo_super(obj, MY_CLASS));
94} 100}
95 101
96static Efl_Model_Load_Status 102static Eina_Array const *
97_eldbus_model_object_efl_model_base_properties_get(Eo *obj EINA_UNUSED, 103_eldbus_model_object_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
98 Eldbus_Model_Object_Data *pd, 104 Eldbus_Model_Object_Data *pd)
99 Eina_Array * const* properties_array)
100{ 105{
101 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR); 106 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
102 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR); 107 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, NULL);
103 108
104 if (pd->properties_array == NULL) 109 if (pd->properties_array == NULL)
105 { 110 {
106 Eina_Bool ret; 111 Eina_Bool ret;
107 112
108 pd->properties_array = eina_array_new(1); 113 pd->properties_array = eina_array_new(1);
109 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, EFL_MODEL_LOAD_STATUS_ERROR); 114 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, NULL);
110 115
111 ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY); 116 ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY);
112 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_MODEL_LOAD_STATUS_ERROR); 117 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
113 } 118 }
114 119
115 *(Eina_Array**)properties_array = pd->properties_array; 120 return pd->properties_array;
116 return pd->load.status;
117} 121}
118 122
119static void 123static void
120_eldbus_model_object_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
121{
122 const char *unique_name;
123 Eina_Bool ret;
124
125 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
126 return;
127
128 if (!pd->connection)
129 _eldbus_model_object_connect(pd);
130
131 pd->unique_name = eina_value_new(EINA_VALUE_TYPE_STRING);
132 EINA_SAFETY_ON_NULL_RETURN(pd->unique_name);
133
134 unique_name = eldbus_connection_unique_name_get(pd->connection);
135 ret = eina_value_set(pd->unique_name, unique_name);
136 EINA_SAFETY_ON_FALSE_RETURN(ret);
137
138 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
139}
140
141static Efl_Model_Load_Status
142_eldbus_model_object_efl_model_base_property_set(Eo *obj EINA_UNUSED, 124_eldbus_model_object_efl_model_base_property_set(Eo *obj EINA_UNUSED,
143 Eldbus_Model_Object_Data *pd EINA_UNUSED, 125 Eldbus_Model_Object_Data *pd EINA_UNUSED,
144 const char *property EINA_UNUSED, 126 const char *property,
145 Eina_Value const* value EINA_UNUSED) 127 const Eina_Value *value EINA_UNUSED,
128 Eina_Promise_Owner *promise)
146{ 129{
147 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 130 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
148 DBG("(%p): property=%s", obj, property); 131 eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
149 return EFL_MODEL_LOAD_STATUS_ERROR;
150} 132}
151 133
152static Efl_Model_Load_Status 134static void
153_eldbus_model_object_efl_model_base_property_get(Eo *obj EINA_UNUSED, 135_eldbus_model_object_efl_model_base_property_get(Eo *obj EINA_UNUSED,
154 Eldbus_Model_Object_Data *pd, 136 Eldbus_Model_Object_Data *pd,
155 const char *property, 137 const char *property,
156 Eina_Value const**value) 138 Eina_Promise_Owner *promise)
157{ 139{
158 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 140 EINA_SAFETY_ON_NULL_RETURN(promise);
159 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
160 DBG("(%p): property=%s", obj, property);
161
162 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
163 return EFL_MODEL_LOAD_STATUS_ERROR;
164
165 if (strcmp(property, UNIQUE_NAME_PROPERTY) != 0)
166 return EFL_MODEL_LOAD_STATUS_ERROR;
167 141
168 *value = pd->unique_name; 142 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
169 return pd->load.status; 143 DBG("(%p): property=%s", obj, property);
170}
171 144
172static void
173_eldbus_model_object_efl_model_base_load(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
174{
175 if (!pd->connection) 145 if (!pd->connection)
176 _eldbus_model_object_connect(pd); 146 _eldbus_model_object_connect(pd);
177 147
178 _eldbus_model_object_efl_model_base_properties_load(obj, pd); 148 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
179 _eldbus_model_object_efl_model_base_children_load(obj, pd);
180}
181 149
182static Efl_Model_Load_Status 150 if (pd->unique_name == NULL)
183_eldbus_model_object_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd) 151 {
184{ 152 const char *unique_name;
185 return pd->load.status;
186}
187 153
188static void 154 unique_name = eldbus_connection_unique_name_get(pd->connection);
189_eldbus_model_object_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd) 155 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND);
190{ 156 pd->unique_name = strdup(unique_name);
191 _eldbus_model_object_clear(pd); 157 }
192 158
193 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED); 159 Eina_Value* v = eina_promise_owner_buffer_get(promise);
160 eina_value_setup(v, EINA_VALUE_TYPE_STRING);
161 eina_value_set(v, pd->unique_name);
162 eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
194} 163}
195 164
196static Eo * 165static Eo *
@@ -199,56 +168,61 @@ _eldbus_model_object_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_
199 return NULL; 168 return NULL;
200} 169}
201 170
202static Efl_Model_Load_Status 171static void
203_eldbus_model_object_efl_model_base_child_del(Eo *obj EINA_UNUSED, 172_eldbus_model_object_efl_model_base_child_del(Eo *obj EINA_UNUSED,
204 Eldbus_Model_Object_Data *pd EINA_UNUSED, 173 Eldbus_Model_Object_Data *pd EINA_UNUSED,
205 Eo *child EINA_UNUSED) 174 Eo *child EINA_UNUSED)
206{ 175{
207 return EFL_MODEL_LOAD_STATUS_ERROR;
208} 176}
209 177
210static Efl_Model_Load_Status 178static void
211_eldbus_model_object_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, 179_eldbus_model_object_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
212 Eldbus_Model_Object_Data *pd, 180 Eldbus_Model_Object_Data *pd,
213 unsigned start, 181 unsigned start,
214 unsigned count, 182 unsigned count,
215 Eina_Accessor **children_accessor) 183 Eina_Promise_Owner *promise)
216{ 184{
217 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)) 185 _Eldbus_Children_Slice_Promise* p;
186
187 if (!pd->connection)
188 _eldbus_model_object_connect(pd);
189
190 if (pd->is_listed)
218 { 191 {
219 WRN("(%p): Children not loaded", obj); 192 Eina_Accessor* ac = efl_model_list_slice(pd->children_list, start, count);
220 *children_accessor = NULL; 193 eina_promise_owner_value_set(promise, &ac, &_accessor_free);
221 return pd->load.status; 194 return;
222 } 195 }
223 else
224 WRN("(%p): Children already loaded", obj);
225 196
226 *children_accessor = efl_model_list_slice(pd->children_list, start, count); 197 p = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
227 return pd->load.status; 198 EINA_SAFETY_ON_NULL_RETURN(p);
228} 199 p->promise = promise;
200 p->start = start;
201 p->count = count;
229 202
230static Efl_Model_Load_Status 203 pd->children_promises = eina_list_prepend(pd->children_promises, p);
231_eldbus_model_object_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, 204 if (pd->pending_list == NULL)
232 Eldbus_Model_Object_Data *pd, 205 _eldbus_model_object_introspect(pd, pd->bus, pd->path);
233 unsigned *children_count)
234{
235 *children_count = eina_list_count(pd->children_list);
236 return pd->load.status;
237} 206}
238 207
239static void 208static void
240_eldbus_model_object_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd) 209_eldbus_model_object_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
210 Eldbus_Model_Object_Data *pd,
211 Eina_Promise_Owner *promise)
241{ 212{
242 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
243 return;
244
245 if (!pd->connection) 213 if (!pd->connection)
246 _eldbus_model_object_connect(pd); 214 _eldbus_model_object_connect(pd);
247 215
248 if (!_eldbus_model_object_introspect(pd, pd->bus, pd->path)) 216 if (pd->is_listed)
249 return; 217 {
218 unsigned int c = eina_list_count(pd->children_list);
219 eina_promise_owner_value_set(promise, &c, NULL);
220 return;
221 }
250 222
251 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN); 223 pd->count_promises = eina_list_prepend(pd->count_promises, promise);
224 if (pd->pending_list == NULL)
225 _eldbus_model_object_introspect(pd, pd->bus, pd->path);
252} 226}
253 227
254static const char * 228static const char *
@@ -358,7 +332,7 @@ _eldbus_model_object_clear(Eldbus_Model_Object_Data *pd)
358 if (!pd->connection) 332 if (!pd->connection)
359 return; 333 return;
360 334
361 eina_value_free(pd->unique_name); 335 free(pd->unique_name);
362 pd->unique_name = NULL; 336 pd->unique_name = NULL;
363 337
364 EINA_LIST_FREE(pd->children_list, child) 338 EINA_LIST_FREE(pd->children_list, child)
@@ -432,7 +406,7 @@ _eldbus_model_object_introspect_cb(void *data,
432 if (eldbus_message_error_get(msg, &error_name, &error_text)) 406 if (eldbus_message_error_get(msg, &error_name, &error_text))
433 { 407 {
434 ERR("%s: %s", error_name, error_text); 408 ERR("%s: %s", error_name, error_text);
435 efl_model_error_notify(pd->obj); 409 //efl_model_error_notify(pd->obj);
436 return; 410 return;
437 } 411 }
438 412
@@ -456,13 +430,26 @@ _eldbus_model_object_introspect_cb(void *data,
456 430
457 if (eina_list_count(pd->pending_list) == 0) 431 if (eina_list_count(pd->pending_list) == 0)
458 { 432 {
459 unsigned int count; 433 Eina_List* i;
460 434
461 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN); 435 pd->is_listed = EINA_TRUE;
436 _Eldbus_Children_Slice_Promise* p;
437 EINA_LIST_FOREACH(pd->children_promises, i, p)
438 {
439 Eina_Accessor* ac = efl_model_list_slice(pd->children_list, p->start, p->count);
440 eina_promise_owner_value_set(p->promise, &ac, &_accessor_free);
441 free(p);
442 }
443 eina_list_free(pd->children_promises);
444
445 Eina_Promise_Owner *ep;
446 EINA_LIST_FOREACH(pd->count_promises, i, ep)
447 {
448 unsigned c = eina_list_count(pd->children_list);
449 eina_promise_owner_value_set(ep, &c, NULL);
450 }
451 eina_list_free(pd->count_promises);
462 452
463 count = eina_list_count(pd->children_list);
464 if (count)
465 eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count);
466 } 453 }
467} 454}
468 455
diff --git a/src/lib/eldbus/eldbus_model_object.eo b/src/lib/eldbus/eldbus_model_object.eo
index 3cb4a2c..b3a8b73 100644
--- a/src/lib/eldbus/eldbus_model_object.eo
+++ b/src/lib/eldbus/eldbus_model_object.eo
@@ -63,17 +63,12 @@ class Eldbus.Model_Object (Eo.Base, Efl.Model.Base) {
63 Eo.Base.constructor; 63 Eo.Base.constructor;
64 Eo.Base.destructor; 64 Eo.Base.destructor;
65 Efl.Model.Base.properties.get; 65 Efl.Model.Base.properties.get;
66 Efl.Model.Base.properties_load; 66 Efl.Model.Base.property_set;
67 Efl.Model.Base.property.set; 67 Efl.Model.Base.property_get;
68 Efl.Model.Base.property.get;
69 Efl.Model.Base.load;
70 Efl.Model.Base.load_status.get;
71 Efl.Model.Base.unload;
72 Efl.Model.Base.child_add; 68 Efl.Model.Base.child_add;
73 Efl.Model.Base.child_del; 69 Efl.Model.Base.child_del;
74 Efl.Model.Base.children_slice.get; 70 Efl.Model.Base.children_slice_get;
75 Efl.Model.Base.children_count.get; 71 Efl.Model.Base.children_count_get;
76 Efl.Model.Base.children_load;
77 } 72 }
78 constructors { 73 constructors {
79 .constructor; 74 .constructor;
diff --git a/src/lib/eldbus/eldbus_model_object_private.h b/src/lib/eldbus/eldbus_model_object_private.h
index 7454921..4330a2f 100644
--- a/src/lib/eldbus/eldbus_model_object_private.h
+++ b/src/lib/eldbus/eldbus_model_object_private.h
@@ -5,25 +5,26 @@
5 5
6#include <stdbool.h> 6#include <stdbool.h>
7 7
8typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
9
10/** 8/**
11 * eldbus_model_object 9 * eldbus_model_object
12 */ 10 */
11typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
13struct _Eldbus_Model_Object_Data 12struct _Eldbus_Model_Object_Data
14{ 13{
15 Eo *obj; 14 Eo *obj;
16 Efl_Model_Load load; 15 Eina_Bool is_listed : 1;
17 Eldbus_Connection *connection; 16 Eldbus_Connection *connection;
18 Eina_List *object_list; 17 Eina_List *object_list;
19 Eina_Array *properties_array; 18 Eina_Array *properties_array;
20 Eina_List *children_list; 19 Eina_List *children_list;
20 Eina_List *children_promises;
21 Eina_List *count_promises;
21 Eldbus_Connection_Type type; 22 Eldbus_Connection_Type type;
22 Eina_Stringshare *address; 23 Eina_Stringshare *address;
23 bool private; 24 bool private;
24 Eina_Stringshare *bus; 25 Eina_Stringshare *bus;
25 Eina_Stringshare *path; 26 Eina_Stringshare *path;
26 Eina_Value *unique_name; 27 char *unique_name;
27 Eina_List *pending_list; 28 Eina_List *pending_list;
28 Eldbus_Introspection_Node *introspection; 29 Eldbus_Introspection_Node *introspection;
29}; 30};
diff --git a/src/lib/eldbus/eldbus_model_private.h b/src/lib/eldbus/eldbus_model_private.h
index 784b422..29d7bdd 100644
--- a/src/lib/eldbus/eldbus_model_private.h
+++ b/src/lib/eldbus/eldbus_model_private.h
@@ -3,12 +3,42 @@
3 3
4#include "eldbus_private.h" 4#include "eldbus_private.h"
5 5
6#include <Ecore.h>
7#include <Eina.h>
6#include <Eo.h> 8#include <Eo.h>
7#include <Efl.h> 9#include <Efl.h>
8 10
11typedef struct _Eldbus_Children_Slice_Promise _Eldbus_Children_Slice_Promise;
12struct _Eldbus_Children_Slice_Promise
13{
14 unsigned start;
15 unsigned count;
16 Eina_Promise_Owner* promise;
17};
18
19typedef struct _Eldbus_Property_Promise _Eldbus_Property_Promise;
20struct _Eldbus_Property_Promise
21{
22 char *property;
23 Eina_Promise_Owner* promise;
24};
25
26void _accessor_free(void *data);
27
9/* logging support */ 28/* logging support */
10extern int eldbus_model_log_dom; 29extern int eldbus_model_log_dom;
11 30
31#define ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(exp, promise, err) \
32 do \
33 { \
34 if (EINA_UNLIKELY(!(exp))) \
35 { \
36 eina_promise_owner_error_set(promise, err); \
37 return; \
38 } \
39 } \
40 while(0)
41
12#ifdef CRI 42#ifdef CRI
13# undef CRI 43# undef CRI
14#endif 44#endif
diff --git a/src/lib/eldbus/eldbus_model_proxy.c b/src/lib/eldbus/eldbus_model_proxy.c
index 9196e4b..0caa4b3 100644
--- a/src/lib/eldbus/eldbus_model_proxy.c
+++ b/src/lib/eldbus/eldbus_model_proxy.c
@@ -10,9 +10,7 @@
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 void _eldbus_model_proxy_efl_model_base_properties_load(Eo *, Eldbus_Model_Proxy_Data *); 13static Eina_Bool _eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *);
14static void _eldbus_model_proxy_efl_model_base_children_load(Eo *, Eldbus_Model_Proxy_Data *);
15static bool _eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *);
16static void _eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *); 14static void _eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *);
17static void _eldbus_model_proxy_property_get_all_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 15static void _eldbus_model_proxy_property_get_all_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
18static void _eldbus_model_proxy_property_set_cb(void *, const Eldbus_Message *, Eldbus_Pending *); 16static void _eldbus_model_proxy_property_set_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
@@ -50,14 +48,15 @@ _eldbus_model_proxy_eo_base_constructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
50 obj = eo_constructor(eo_super(obj, MY_CLASS)); 48 obj = eo_constructor(eo_super(obj, MY_CLASS));
51 49
52 pd->obj = obj; 50 pd->obj = obj;
53 pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
54 pd->object = NULL; 51 pd->object = NULL;
55 pd->proxy = NULL; 52 pd->proxy = NULL;
53 pd->is_listed = pd->is_loaded = EINA_FALSE;
56 pd->properties_array = NULL; 54 pd->properties_array = NULL;
57 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_proxy_hash_free)); 55 pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_proxy_hash_free));
58 pd->children_list = NULL; 56 pd->children_list = NULL;
59 pd->name = NULL; 57 pd->name = NULL;
60 pd->pending_list = NULL; 58 pd->pending_list = NULL;
59 pd->promise_list = NULL;
61 pd->monitoring = false; 60 pd->monitoring = false;
62 pd->interface = NULL; 61 pd->interface = NULL;
63 62
@@ -91,210 +90,143 @@ _eldbus_model_proxy_eo_base_destructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
91 eo_destructor(eo_super(obj, MY_CLASS)); 90 eo_destructor(eo_super(obj, MY_CLASS));
92} 91}
93 92
94static Efl_Model_Load_Status 93static Eina_Array const *
95_eldbus_model_proxy_efl_model_base_properties_get(Eo *obj EINA_UNUSED, 94_eldbus_model_proxy_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
96 Eldbus_Model_Proxy_Data *pd, 95 Eldbus_Model_Proxy_Data *pd)
97 Eina_Array * const* properties_array)
98{ 96{
99 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR); 97 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
100 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
101 98
102 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)) 99 _eldbus_model_proxy_load(pd);
103 { 100 return pd->properties_array;
104 WRN("%s", "Properties not loaded.");
105 return EFL_MODEL_LOAD_STATUS_ERROR;
106 }
107
108 *(Eina_Array**)properties_array = pd->properties_array;
109 return pd->load.status;
110} 101}
111 102
112static void 103static void
113_eldbus_model_proxy_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
114{
115 Eldbus_Introspection_Property *property;
116 Eina_List *it;
117 Eldbus_Pending *pending;
118
119 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
120 return;
121
122 if (!_eldbus_model_proxy_load(pd))
123 return;
124
125 const unsigned int properties_count = eina_list_count(pd->interface->properties);
126
127 pd->properties_array = eina_array_new(properties_count);
128 EINA_SAFETY_ON_NULL_RETURN(pd->properties_array);
129
130 if (!properties_count)
131 {
132 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
133 return;
134 }
135
136 EINA_LIST_FOREACH(pd->interface->properties, it, property)
137 {
138 Eina_Stringshare *name;
139 Eina_Bool ret;
140
141 name = eina_stringshare_add(property->name);
142 ret = eina_array_push(pd->properties_array, name);
143 EINA_SAFETY_ON_FALSE_RETURN(ret);
144 }
145
146 pending = eldbus_proxy_property_get_all(pd->proxy, _eldbus_model_proxy_property_get_all_cb, pd);
147 pd->pending_list = eina_list_append(pd->pending_list, pending);
148
149 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES);
150}
151
152static Efl_Model_Load_Status
153_eldbus_model_proxy_efl_model_base_property_set(Eo *obj EINA_UNUSED, 104_eldbus_model_proxy_efl_model_base_property_set(Eo *obj EINA_UNUSED,
154 Eldbus_Model_Proxy_Data *pd, 105 Eldbus_Model_Proxy_Data *pd,
155 const char *property, 106 const char *property,
156 Eina_Value const* value) 107 Eina_Value const* value,
108 Eina_Promise_Owner *promise)
157{ 109{
158 Eldbus_Model_Proxy_Property_Set_Data *data; 110 Eldbus_Model_Proxy_Property_Set_Data *data;
159 const char *signature; 111 const char *signature;
160 Eldbus_Pending *pending; 112 Eldbus_Pending *pending;
113 Eina_Bool ret;
161 114
162 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 115 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
163 116
164 DBG("(%p): property=%s", obj, property); 117 DBG("(%p): property=%s", obj, property);
118 ret = _eldbus_model_proxy_load(pd);
119 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
165 120
166 if (!_eldbus_model_proxy_is_property_writeable(pd, property)) 121 ret = _eldbus_model_proxy_is_property_writeable(pd, property);
167 { 122 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY);
168 WRN("Property is read-only: %s", property);
169 return EFL_MODEL_LOAD_STATUS_ERROR;
170 }
171 123
172 data = _eldbus_model_proxy_property_set_data_new(pd, property, value); 124 data = _eldbus_model_proxy_property_set_data_new(pd, property, value);
173 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EFL_MODEL_LOAD_STATUS_ERROR); 125 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(data, promise, EFL_MODEL_ERROR_UNKNOWN);
174 126
175 signature = _eldbus_model_proxy_property_type_get(pd, property); 127 signature = _eldbus_model_proxy_property_type_get(pd, property);
176 EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EFL_MODEL_LOAD_STATUS_ERROR); 128 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(data, promise, EFL_MODEL_ERROR_UNKNOWN);
177 129
130 pd->promises_set = eina_list_append(pd->promises_set, promise);
178 pending = eldbus_proxy_property_value_set 131 pending = eldbus_proxy_property_value_set
179 (pd->proxy, property, signature, (Eina_Value*)value, _eldbus_model_proxy_property_set_cb, data); 132 (pd->proxy, property, signature, (Eina_Value*)value, _eldbus_model_proxy_property_set_cb, data);
180 pd->pending_list = eina_list_append(pd->pending_list, pending); 133 pd->pending_list = eina_list_append(pd->pending_list, pending);
181
182 return pd->load.status;
183} 134}
184 135
185static Efl_Model_Load_Status 136static void
186_eldbus_model_proxy_efl_model_base_property_get(Eo *obj EINA_UNUSED, 137_eldbus_model_proxy_efl_model_base_property_get(Eo *obj EINA_UNUSED,
187 Eldbus_Model_Proxy_Data *pd, 138 Eldbus_Model_Proxy_Data *pd,
188 const char *property, 139 const char *property,
189 Eina_Value const **value) 140 Eina_Promise_Owner *promise)
190{ 141{
191 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR); 142 Eina_Bool ret;
192 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR); 143 EINA_SAFETY_ON_NULL_RETURN(promise);
193
194 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
195 return EFL_MODEL_LOAD_STATUS_ERROR;
196 144
197 if (!_eldbus_model_proxy_is_property_readable(pd, property)) 145 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
198 {
199 WRN("Property is write-only: %s", property);
200 return EFL_MODEL_LOAD_STATUS_ERROR;
201 }
202 146
203 *value = eina_hash_find(pd->properties_hash, property); 147 ret = _eldbus_model_proxy_load(pd);
148 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
204 149
205 if(!*value) 150 if (!pd->is_loaded)
206 { 151 {
207 *value = &pd->tmp_value; 152 Eldbus_Pending *pending;
208 return EFL_MODEL_LOAD_STATUS_ERROR; 153 _Eldbus_Property_Promise *p = calloc(1, sizeof(_Eldbus_Property_Promise));
154 EINA_SAFETY_ON_NULL_RETURN(p);
155
156 p->promise = promise;
157 p->property = strdup(property);
158 pd->promise_list = eina_list_append(pd->promise_list, p);
159
160 if (!pd->pending_list)
161 {
162 pending = eldbus_proxy_property_get_all(pd->proxy, _eldbus_model_proxy_property_get_all_cb, pd);
163 pd->pending_list = eina_list_append(pd->pending_list, pending);
164 }
165 return;
209 } 166 }
210 167
211 return pd->load.status; 168 Eina_Value* value = eina_hash_find(pd->properties_hash, property);
212} 169 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_NOT_FOUND);
213
214static void
215_eldbus_model_proxy_efl_model_base_load(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
216{
217 if (!_eldbus_model_proxy_load(pd))
218 return;
219
220 _eldbus_model_proxy_efl_model_base_properties_load(obj, pd);
221 _eldbus_model_proxy_efl_model_base_children_load(obj, pd);
222}
223
224static Efl_Model_Load_Status
225_eldbus_model_proxy_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
226{
227 return pd->load.status;
228}
229 170
230static void 171 ret = _eldbus_model_proxy_is_property_writeable(pd, property);
231_eldbus_model_proxy_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd) 172 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY);
232{
233 _eldbus_model_proxy_unload(pd);
234 173
235 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED); 174 eina_value_copy(value, eina_promise_owner_buffer_get(promise));
175 eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
236} 176}
237 177
238static Eo * 178static Eo *
239_eldbus_model_proxy_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd EINA_UNUSED) 179_eldbus_model_proxy_efl_model_base_child_add(Eo *obj EINA_UNUSED,
180 Eldbus_Model_Proxy_Data *pd EINA_UNUSED)
240{ 181{
241 return NULL; 182 return NULL;
242} 183}
243 184
244static Efl_Model_Load_Status 185static void
245_eldbus_model_proxy_efl_model_base_child_del(Eo *obj EINA_UNUSED, 186_eldbus_model_proxy_efl_model_base_child_del(Eo *obj EINA_UNUSED,
246 Eldbus_Model_Proxy_Data *pd EINA_UNUSED, 187 Eldbus_Model_Proxy_Data *pd EINA_UNUSED,
247 Eo *child EINA_UNUSED) 188 Eo *child EINA_UNUSED)
248{ 189{
249 return EFL_MODEL_LOAD_STATUS_ERROR;
250} 190}
251 191
252static Efl_Model_Load_Status 192static void
253_eldbus_model_proxy_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, 193_eldbus_model_proxy_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
254 Eldbus_Model_Proxy_Data *pd, 194 Eldbus_Model_Proxy_Data *pd,
255 unsigned start, 195 unsigned start,
256 unsigned count, 196 unsigned count,
257 Eina_Accessor **children_accessor) 197 Eina_Promise_Owner *promise)
258{ 198{
259 if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)) 199 Eina_Bool ret = _eldbus_model_proxy_load(pd);
200 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
201
202 if (!pd->is_listed)
260 { 203 {
261 WRN("(%p): Children not loaded", obj); 204 _eldbus_model_proxy_create_methods_children(pd);
262 *children_accessor = NULL; 205 _eldbus_model_proxy_create_signals_children(pd);
263 return pd->load.status; 206 pd->is_listed = EINA_TRUE;
264 } 207 }
265 208
266 *children_accessor = efl_model_list_slice(pd->children_list, start, count); 209 Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
267 return pd->load.status; 210 eina_promise_owner_value_set(promise, &ac, (Eina_Promise_Free_Cb)&_accessor_free);
268} 211}
269 212
270static Efl_Model_Load_Status 213static void
271_eldbus_model_proxy_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, 214_eldbus_model_proxy_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
272 Eldbus_Model_Proxy_Data *pd, 215 Eldbus_Model_Proxy_Data *pd,
273 unsigned *children_count) 216 Eina_Promise_Owner *promise)
274{
275 *children_count = eina_list_count(pd->children_list);
276 return pd->load.status;
277}
278
279static void
280_eldbus_model_proxy_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
281{ 217{
282 unsigned int count; 218 Eina_Bool ret = _eldbus_model_proxy_load(pd);
283 219 ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
284 if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
285 return;
286
287 if (!_eldbus_model_proxy_load(pd))
288 return;
289
290 _eldbus_model_proxy_create_methods_children(pd);
291 _eldbus_model_proxy_create_signals_children(pd);
292 220
293 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN); 221 if (!pd->is_listed)
222 {
223 _eldbus_model_proxy_create_methods_children(pd);
224 _eldbus_model_proxy_create_signals_children(pd);
225 pd->is_listed = EINA_TRUE;
226 }
294 227
295 count = eina_list_count(pd->children_list); 228 unsigned int c = eina_list_count(pd->children_list);
296 if (count) 229 eina_promise_owner_value_set(promise, &c, NULL);
297 eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count);
298} 230}
299 231
300static void 232static void
@@ -323,7 +255,8 @@ _eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *pd)
323 method_name = method->name; 255 method_name = method->name;
324 if (!method_name) continue; 256 if (!method_name) continue;
325 257
326 INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s", pd->obj, bus, path, interface_name, method_name); 258 INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s",
259 pd->obj, bus, path, interface_name, method_name);
327 260
328 child = eo_add(ELDBUS_MODEL_METHOD_CLASS, NULL, eldbus_model_method_constructor(eo_self, pd->proxy, method)); 261 child = eo_add(ELDBUS_MODEL_METHOD_CLASS, NULL, eldbus_model_method_constructor(eo_self, pd->proxy, method));
329 262
@@ -357,7 +290,8 @@ _eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *pd)
357 signal_name = signal->name; 290 signal_name = signal->name;
358 if (!signal_name) continue; 291 if (!signal_name) continue;
359 292
360 DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s", pd->obj, bus, path, interface_name, signal_name); 293 DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s",
294 pd->obj, bus, path, interface_name, signal_name);
361 295
362 child = eo_add(ELDBUS_MODEL_SIGNAL_CLASS, NULL, eldbus_model_signal_constructor(eo_self, pd->proxy, signal)); 296 child = eo_add(ELDBUS_MODEL_SIGNAL_CLASS, NULL, eldbus_model_signal_constructor(eo_self, pd->proxy, signal));
363 297
@@ -371,22 +305,42 @@ _eldbus_model_proxy_name_get(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
371 return pd->name; 305 return pd->name;
372} 306}
373 307
374static bool 308static Eina_Bool
375_eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *pd) 309_eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *pd)
376{ 310{
377 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false); 311 Eldbus_Introspection_Property *property;
312 Eina_List *it;
313
314 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EINA_FALSE);
378 315
379 if (pd->proxy) 316 if (pd->proxy)
380 return true; 317 return EINA_TRUE;
318
319 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->object, EINA_FALSE);
320 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->name, EINA_FALSE);
321 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->interface, EINA_FALSE);
381 322
382 pd->proxy = eldbus_proxy_get(pd->object, pd->name); 323 pd->proxy = eldbus_proxy_get(pd->object, pd->name);
383 if (!pd->proxy) 324 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->proxy, EINA_FALSE);
325
326 const unsigned int properties_count = eina_list_count(pd->interface->properties);
327
328 pd->properties_array = eina_array_new(properties_count);
329 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, EINA_FALSE);
330
331 if (!properties_count) return EINA_TRUE;
332
333 EINA_LIST_FOREACH(pd->interface->properties, it, property)
384 { 334 {
385 ERR("Cannot get proxy for interface: %s", pd->name); 335 Eina_Stringshare *name;
386 return false; 336 Eina_Bool ret;
337
338 name = eina_stringshare_add(property->name);
339 ret = eina_array_push(pd->properties_array, name);
340 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EINA_FALSE);
387 } 341 }
388 342
389 return true; 343 return EINA_TRUE;
390} 344}
391 345
392static void 346static void
@@ -401,7 +355,9 @@ _eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *pd)
401 eo_unref(child); 355 eo_unref(child);
402 356
403 EINA_LIST_FREE(pd->pending_list, pending) 357 EINA_LIST_FREE(pd->pending_list, pending)
358 {
404 eldbus_pending_cancel(pending); 359 eldbus_pending_cancel(pending);
360 }
405 361
406 if (pd->properties_array) 362 if (pd->properties_array)
407 { 363 {
@@ -491,18 +447,6 @@ _eldbus_model_proxy_property_invalidated_cb(void *data,
491 Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data; 447 Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
492 Eldbus_Proxy_Event_Property_Changed *event = (Eldbus_Proxy_Event_Property_Changed*)event_info; 448 Eldbus_Proxy_Event_Property_Changed *event = (Eldbus_Proxy_Event_Property_Changed*)event_info;
493 449
494#if 0
495 Efl_Model_Property_Event evt = {0};
496
497 // TODO: eldbus_proxy_property_get(event->name) ?
498
499 evt.invalidated_properties = eina_array_new(1);
500 EINA_SAFETY_ON_NULL_RETURN(evt.invalidated_properties);
501
502 eina_array_push(evt.invalidated_properties, event->name);
503 eina_array_free(evt.invalidated_properties);
504#endif
505
506 efl_model_property_invalidated_notify(pd->obj, event->name); 450 efl_model_property_invalidated_notify(pd->obj, event->name);
507} 451}
508 452
@@ -524,7 +468,14 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
524 if (eldbus_message_error_get(msg, &error_name, &error_text)) 468 if (eldbus_message_error_get(msg, &error_name, &error_text))
525 { 469 {
526 ERR("%s: %s", error_name, error_text); 470 ERR("%s: %s", error_name, error_text);
527 efl_model_error_notify(pd->obj); 471 Eina_List* i;
472 _Eldbus_Property_Promise* p;
473 EINA_LIST_FOREACH(pd->promise_list, i, p)
474 {
475 eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_UNKNOWN);
476 free(p->property);
477 }
478 eina_list_free(pd->promise_list);
528 return; 479 return;
529 } 480 }
530 481
@@ -577,6 +528,28 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
577 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error); 528 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error);
578 } 529 }
579 530
531 pd->is_loaded = EINA_TRUE;
532
533 Eina_List* i;
534 _Eldbus_Property_Promise* p;
535 EINA_LIST_FOREACH(pd->promise_list, i, p)
536 {
537 Eina_Value* value = eina_hash_find(pd->properties_hash, p->property);
538 if (!value || !_eldbus_model_proxy_is_property_readable(pd, p->property))
539 {
540 eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_READ_ONLY);
541 free(p->property);
542 continue;
543 }
544
545 free(p->property);
546
547 eina_value_copy(value, eina_promise_owner_buffer_get(p->promise));
548 eina_promise_owner_value_set(p->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
549 }
550 eina_list_free(pd->promise_list);
551
552
580 _eldbus_model_proxy_start_monitor(pd); 553 _eldbus_model_proxy_start_monitor(pd);
581 554
582 if (eina_array_count(changed_properties)) 555 if (eina_array_count(changed_properties))
@@ -588,8 +561,6 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
588 eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, &evt); 561 eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, &evt);
589 } 562 }
590 563
591 efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
592
593 on_error: 564 on_error:
594 eina_array_free(changed_properties); 565 eina_array_free(changed_properties);
595} 566}
@@ -611,7 +582,6 @@ _eldbus_model_proxy_property_set_cb(void *data,
611 if (eldbus_message_error_get(msg, &error_name, &error_text)) 582 if (eldbus_message_error_get(msg, &error_name, &error_text))
612 { 583 {
613 ERR("%s: %s", error_name, error_text); 584 ERR("%s: %s", error_name, error_text);
614 efl_model_error_notify(pd->obj);
615 goto on_error; 585 goto on_error;
616 } 586 }
617 587
@@ -622,6 +592,7 @@ _eldbus_model_proxy_property_set_cb(void *data,
622 ret = eina_value_copy(&property_set_data->value, prop_value); 592 ret = eina_value_copy(&property_set_data->value, prop_value);
623 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error); 593 EINA_SAFETY_ON_FALSE_GOTO(ret, on_error);
624 594
595 on_error:
625 { 596 {
626 Efl_Model_Property_Event evt = { 597 Efl_Model_Property_Event evt = {
627 .changed_properties = pd->properties_array 598 .changed_properties = pd->properties_array
@@ -631,7 +602,6 @@ _eldbus_model_proxy_property_set_cb(void *data,
631 efl_model_property_changed_notify(pd->obj, property_set_data->property); 602 efl_model_property_changed_notify(pd->obj, property_set_data->property);
632 } 603 }
633 604
634 on_error:
635 _eldbus_model_proxy_property_set_data_free(property_set_data); 605 _eldbus_model_proxy_property_set_data_free(property_set_data);
636} 606}
637 607
diff --git a/src/lib/eldbus/eldbus_model_proxy.eo b/src/lib/eldbus/eldbus_model_proxy.eo
index a5b51b7..fb0f26c7 100644
--- a/src/lib/eldbus/eldbus_model_proxy.eo
+++ b/src/lib/eldbus/eldbus_model_proxy.eo
@@ -26,17 +26,12 @@ class Eldbus.Model_Proxy (Eo.Base, Efl.Model.Base) {
26 Eo.Base.constructor; 26 Eo.Base.constructor;
27 Eo.Base.destructor; 27 Eo.Base.destructor;
28 Efl.Model.Base.properties.get; 28 Efl.Model.Base.properties.get;
29 Efl.Model.Base.properties_load; 29 Efl.Model.Base.property_set;
30 Efl.Model.Base.property.set; 30 Efl.Model.Base.property_get;
31 Efl.Model.Base.property.get;
32 Efl.Model.Base.load;
33 Efl.Model.Base.load_status.get;
34 Efl.Model.Base.unload;
35 Efl.Model.Base.child_add; 31 Efl.Model.Base.child_add;
36 Efl.Model.Base.child_del; 32 Efl.Model.Base.child_del;
37 Efl.Model.Base.children_slice.get; 33 Efl.Model.Base.children_slice_get;
38 Efl.Model.Base.children_count.get; 34 Efl.Model.Base.children_count_get;
39 Efl.Model.Base.children_load;
40 } 35 }
41 constructors { 36 constructors {
42 .constructor; 37 .constructor;
diff --git a/src/lib/eldbus/eldbus_model_proxy_private.h b/src/lib/eldbus/eldbus_model_proxy_private.h
index 02153fc..8308a09 100644
--- a/src/lib/eldbus/eldbus_model_proxy_private.h
+++ b/src/lib/eldbus/eldbus_model_proxy_private.h
@@ -13,7 +13,8 @@ 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 Efl_Model_Load load; 16 Eina_Bool is_listed : 1;
17 Eina_Bool is_loaded : 1;
17 Eldbus_Object *object; 18 Eldbus_Object *object;
18 Eldbus_Proxy *proxy; 19 Eldbus_Proxy *proxy;
19 Eina_Array *properties_array; 20 Eina_Array *properties_array;
@@ -21,6 +22,8 @@ struct _Eldbus_Model_Proxy_Data
21 Eina_List *children_list; 22 Eina_List *children_list;
22 Eina_Stringshare *name; 23 Eina_Stringshare *name;
23 Eina_List *pending_list; 24 Eina_List *pending_list;
25 Eina_List *promise_list;
26 Eina_List *promises_set;
24 bool monitoring; 27 bool monitoring;
25 const Eldbus_Introspection_Interface *interface; 28 const Eldbus_Introspection_Interface *interface;
26 Eina_Value tmp_value; 29 Eina_Value tmp_value;
diff --git a/src/lib/eldbus/eldbus_model_signal.c b/src/lib/eldbus/eldbus_model_signal.c
index 406c451..24a69f8 100644
--- a/src/lib/eldbus/eldbus_model_signal.c
+++ b/src/lib/eldbus/eldbus_model_signal.c
@