forked from enlightenment/efl
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.
This commit is contained in:
parent
e466dd5c3b
commit
218403dc19
|
@ -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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
static void
|
||||
promise_then(void* obj EINA_UNUSED, void* data)
|
||||
{
|
||||
Eina_Accessor *accessor;
|
||||
unsigned int* count;
|
||||
|
||||
Eina_Iterator* iterator = data;
|
||||
|
||||
if (!eina_iterator_next(iterator, (void**)&accessor))
|
||||
{
|
||||
printf("bye\n");
|
||||
if (quit_on_done)
|
||||
ecore_main_loop_quit();
|
||||
else
|
||||
printf("monitoring events...\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
future_then(void* obj EINA_UNUSED, const Efl_Event *event)
|
||||
{
|
||||
Efl_Future_Event_Success *future = event->info;
|
||||
Eina_Accessor *values = future->value;
|
||||
Eina_Accessor *children;
|
||||
unsigned int *count;
|
||||
|
||||
if (!eina_accessor_data_get(values, 0, (void**)&children))
|
||||
{
|
||||
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 (argc > 1) bus = argv[1];
|
||||
if (argc > 2) path = argv[2];
|
||||
if (quit_option) 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));
|
||||
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;
|
||||
}
|
||||
|
||||
Eina_Promise *promises[] = { NULL, NULL, NULL};
|
||||
promises[0] = efl_model_children_slice_get(root, 0, 0);
|
||||
promises[1] = efl_model_children_count_get(root);
|
||||
conn_type = (is_system ?
|
||||
ELDBUS_CONNECTION_TYPE_SYSTEM :
|
||||
ELDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
|
||||
&promise_then, &error_cb, 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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue