summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-11-04 13:09:27 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-11-04 13:19:57 -0200
commit218403dc19aa55c50c554375ad73b63dfaae7715 (patch)
tree886ed837665e55e2d3650da32eb45826efbbaacc
parente466dd5c3b34f4a022b87e7f99e119d2ab93fbc7 (diff)
downloadefl-218403dc19aa55c50c554375ad73b63dfaae7715.tar.gz
examples/eldbus/dbusmodel.c improve situation, far from correct.
it was using old API, updated, but still doesn't work as expected, lots of warnings from children being left alive, all proxies are reporting no properties... when model dies, all children proxies should die as well, otherwise we get on console: ``` CRI:eldbus lib/eldbus/eldbus_core.c:215 eldbus_shutdown() Alive TYPE_SYSTEM connection ERR:eldbus lib/eldbus/eldbus_core.c:175 print_live_connection() conn=0x8219230 alive object=0x8276d50 net.connman of bus=net.connman ... ``` Also, all proxies are reporting no properties "(no properties yet)", likely they are missing to fetch such... even if "--wait" to let it run, no asynchronous properties are delivered, at least not triggering EFL_MODEL_EVENT_PROPERTIES_CHANGED.
-rw-r--r--src/examples/eldbus/dbusmodel.c217
1 files changed, 167 insertions, 50 deletions
diff --git a/src/examples/eldbus/dbusmodel.c b/src/examples/eldbus/dbusmodel.c
index 034fde63d2..47aecd369e 100644
--- a/src/examples/eldbus/dbusmodel.c
+++ b/src/examples/eldbus/dbusmodel.c
@@ -9,22 +9,26 @@
#include <Eldbus_Model.h>
#include <Efl.h>
#include <Ecore.h>
+#include <Ecore_Getopt.h>
-#define DEFAULT_BUS "org.freedesktop.DBus"
+#define DEFAULT_BUS_NAME "org.freedesktop.DBus"
#define DEFAULT_PATH "/"
static int prop_count = 0;
+static int retval = EXIT_SUCCESS;
+static Eina_Bool quit_on_done = EINA_TRUE;
static void
-promise_then_prop_c(void* priv_obj, void* data)
+future_properties_then(void* data, const Efl_Event *event)
{
- Eo* obj = priv_obj;
+ Eo* obj = data;
+ Efl_Future_Event_Success *future = event->info;
Eina_Value * property_value;
const Eina_Array *properties_list;
Eina_Array_Iterator a_it;
char *property, *prop_str;
const char *name;
- Eina_Iterator* it = data;
+ Eina_Iterator* it = future->value;
name = eldbus_model_proxy_name_get(obj);
properties_list = efl_model_properties_get(obj);
@@ -43,108 +47,221 @@ promise_then_prop_c(void* priv_obj, void* data)
prop_count--;
if (prop_count == 0)
- ecore_main_loop_quit();
+ {
+ if (quit_on_done)
+ ecore_main_loop_quit();
+ else
+ printf("monitoring events...\n");
+ }
}
static void
-error_cb(void* data EINA_UNUSED, Eina_Error error EINA_UNUSED)
+error_cb(void* data EINA_UNUSED, const Efl_Event *event)
{
- printf(" ERROR\n");
+ Efl_Future_Event_Failure *future = event->info;
+ printf(" ERROR: #%d '%s'\n", future->error, eina_error_msg_get(future->error));
ecore_main_loop_quit();
+ retval = EXIT_FAILURE;
}
static void
-promise_then_a(void* priv_obj EINA_UNUSED, void* data)
+loop_children(Eina_Accessor *children)
{
- const Eina_Array *properties_list;
- Eina_Array_Iterator a_it;
- Eina_Promise **promises;
- const char *name;
- char *property;
Eo* child;
int i = 0;
- Eina_Accessor* accessor = data;
- EINA_ACCESSOR_FOREACH(accessor, i, child)
+ EINA_ACCESSOR_FOREACH(children, i, child)
{
- properties_list = efl_model_properties_get(child);
- name = eldbus_model_proxy_name_get(child);
-
+ const Eina_Array *properties_list = efl_model_properties_get(child);
unsigned p_count = eina_array_count(properties_list);
+ const char *name = eldbus_model_proxy_name_get(child);
if (p_count)
{
- promises = (Eina_Promise **)calloc(p_count + 1, sizeof(Eina_Promise *));
- promises[p_count] = NULL;
-
+ Efl_Future **futures = calloc(p_count + 1, sizeof(Efl_Future *));
+ Eina_Array_Iterator a_it;
+ const char *property;
unsigned j = 0;
+
EINA_ARRAY_ITER_NEXT(properties_list, j, property, a_it)
{
- promises[j] = efl_model_property_get(child, property);
+ futures[j] = efl_model_property_get(child, property);
}
- eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
- &promise_then_prop_c, &error_cb, child);
+ efl_future_then(efl_future_iterator_all(eina_carray_iterator_new((void **)futures)),
+ &future_properties_then, &error_cb, NULL, child);
prop_count++;
+ free(futures);
+ printf(" %2d: %s (loading %u properties asynchronously)\n", i, name, j);
}
else
{
- printf(" -> %s\n", name);
+ printf(" %2d: %s (no properties yet)\n", i, name);
}
}
if (prop_count == 0)
- ecore_main_loop_quit();
+ {
+ if (quit_on_done)
+ ecore_main_loop_quit();
+ else
+ printf("monitoring events...\n");
+ }
}
+
static void
-promise_then(void* obj EINA_UNUSED, void* data)
+future_then(void* obj EINA_UNUSED, const Efl_Event *event)
{
- Eina_Accessor *accessor;
- unsigned int* count;
-
- Eina_Iterator* iterator = data;
+ Efl_Future_Event_Success *future = event->info;
+ Eina_Accessor *values = future->value;
+ Eina_Accessor *children;
+ unsigned int *count;
- if (!eina_iterator_next(iterator, (void**)&accessor))
+ if (!eina_accessor_data_get(values, 0, (void**)&children))
{
- printf("bye\n");
+ fprintf(stderr, "ERROR: missing future fulfillment value #0\n");
+ retval = EXIT_FAILURE;
ecore_main_loop_quit();
return;
}
- if(eina_iterator_next(iterator, (void **)&count))
+ if (!eina_accessor_data_get(values, 1, (void**)&count))
{
- printf("efl_model_loaded count %d\n", (int)*count); fflush(stdout);
- printf("efl_model_loaded accessor %p\n", accessor); fflush(stdout);
-
- promise_then_a(NULL, accessor);
+ fprintf(stderr, "ERROR: missing future fulfillment value #1\n");
+ retval = EXIT_FAILURE;
+ ecore_main_loop_quit();
+ return;
}
+
+ printf("efl_model_loaded count %u\n", *count);
+ loop_children(children);
}
+static void
+_on_properties_changed(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Efl_Model_Property_Event *ev = event->info;
+ Eina_Array_Iterator it;
+ const char *str;
+ unsigned int i;
+
+ printf("Properties changed:\n");
+ EINA_ARRAY_ITER_NEXT(ev->changed_properties, i, str, it)
+ printf("\t%s\n", str);
+
+ printf("Properties invalidated:\n");
+ EINA_ARRAY_ITER_NEXT(ev->invalidated_properties, i, str, it)
+ printf("\t%s\n", str);
+}
+
+static void
+_on_child_added(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Eo *child = event->info;
+ printf("Children Added: %p\n", child);
+}
+
+static void
+_on_child_removed(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Eo *child = event->info;
+ printf("Children Removed: %p\n", child);
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(event_cbs,
+ { EFL_MODEL_EVENT_PROPERTIES_CHANGED, _on_properties_changed },
+ { EFL_MODEL_EVENT_CHILD_ADDED, _on_child_added },
+ { EFL_MODEL_EVENT_CHILD_REMOVED, _on_child_removed });
+
+static const Ecore_Getopt options = {
+ "dbusmodel", /* program name */
+ NULL, /* usage line */
+ "1", /* version */
+ "(C) 2016 Enlightenment Project", /* copyright */
+ "BSD 2-Clause", /* license */
+ /* long description, may be multiline and contain \n */
+ "Example of Eldbus.Model.Object to fetch children and properties.\n",
+ EINA_FALSE,
+ {
+ ECORE_GETOPT_STORE_TRUE('s', "system", "connect to the system bus, not user session."),
+ ECORE_GETOPT_STORE_FALSE('w', "wait", "after done, wait for events (monitoring)"),
+
+ ECORE_GETOPT_VERSION('V', "version"),
+ ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+ ECORE_GETOPT_LICENSE('L', "license"),
+ ECORE_GETOPT_HELP('h', "help"),
+
+ ECORE_GETOPT_STORE_METAVAR_STR(0, NULL, "The bus name to connect.", "bus_name"),
+ ECORE_GETOPT_STORE_METAVAR_STR(0, NULL, "The path to explore.", "path"),
+
+ ECORE_GETOPT_SENTINEL
+ }
+};
+
int
main(int argc, char **argv EINA_UNUSED)
{
- const char *bus, *path;
+ Eldbus_Connection_Type conn_type;
+ Eina_Bool is_system = EINA_FALSE;
+ char *bus_name = DEFAULT_BUS_NAME;
+ char *path = DEFAULT_PATH;
+ Eina_Bool quit_option = EINA_FALSE;
+ Ecore_Getopt_Value values[] = {
+ ECORE_GETOPT_VALUE_BOOL(is_system),
+ ECORE_GETOPT_VALUE_BOOL(quit_on_done),
+
+ /* standard block to provide version, copyright, license and help */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -V/--version quits */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -C/--copyright quits */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -L/--license quits */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -h/--help quits */
+
+ /* positional argument */
+ ECORE_GETOPT_VALUE_STR(bus_name),
+ ECORE_GETOPT_VALUE_STR(path),
+
+ ECORE_GETOPT_VALUE_NONE /* sentinel */
+ };
+ int args;
Eo *root;
ecore_init();
eldbus_init();
- bus = DEFAULT_BUS;
- path = DEFAULT_PATH;
+ args = ecore_getopt_parse(&options, values, argc, argv);
+ if (args < 0)
+ {
+ fputs("ERROR: Could not parse command line options.\n", stderr);
+ retval = EXIT_FAILURE;
+ goto end;
+ }
+
+ if (quit_option) goto end;
- if (argc > 1) bus = argv[1];
- if (argc > 2) path = argv[2];
+ args = ecore_getopt_parse_positional(&options, values, argc, argv, args);
+ if (args < 0)
+ {
+ fputs("ERROR: Could not parse positional arguments.\n", stderr);
+ retval = EXIT_FAILURE;
+ goto end;
+ }
- root = efl_add_ref(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(efl_added, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, bus, path));
+ conn_type = (is_system ?
+ ELDBUS_CONNECTION_TYPE_SYSTEM :
+ ELDBUS_CONNECTION_TYPE_SESSION);
- Eina_Promise *promises[] = { NULL, NULL, NULL};
- promises[0] = efl_model_children_slice_get(root, 0, 0);
- promises[1] = efl_model_children_count_get(root);
+ root = efl_add_ref(ELDBUS_MODEL_OBJECT_CLASS, ecore_main_loop_get(),
+ eldbus_model_object_constructor(efl_added, conn_type, NULL, EINA_FALSE, bus_name, path),
+ efl_event_callback_array_add(efl_added, event_cbs(), NULL));
- eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
- &promise_then, &error_cb, root);
+ efl_future_then(efl_future_all(efl_model_children_slice_get(root, 0, 0),
+ efl_model_children_count_get(root)),
+ &future_then, &error_cb, NULL, root);
ecore_main_loop_begin();
+ efl_del(root);
- efl_unref(root);
+ end:
eldbus_shutdown();
+ ecore_shutdown();
+ return retval;
}