eldbus: migrate and refactor eldbus.model to new efl.model API.

This commit is contained in:
Cedric Bail 2017-10-25 18:05:41 -07:00 committed by Cedric BAIL
parent ddcf8d8b97
commit 3edb4ca697
18 changed files with 815 additions and 1362 deletions

View File

@ -225,6 +225,7 @@ typedef void (*Eldbus_Signal_Cb)(void *data, const Eldbus_Message *msg);
#ifdef EFL_BETA_API_SUPPORT
#include "eldbus_model.eo.h"
#include "eldbus_model_arguments.eo.h"
#include "eldbus_model_connection.eo.h"
#include "eldbus_model_method.eo.h"

View File

@ -74,6 +74,15 @@ _eldbus_model_efl_object_finalize(Eo *obj, Eldbus_Model_Data *pd)
return efl_finalize(efl_super(obj, ELDBUS_MODEL_CLASS));
}
static void
_eldbus_model_efl_object_invalidate(Eo *obj, Eldbus_Model_Data *pd)
{
if (pd->connection) eldbus_connection_unref(pd->connection);
pd->connection = NULL;
efl_invalidate(efl_super(obj, MY_CLASS));
}
static void
_eldbus_model_efl_object_destructor(Eo *obj, Eldbus_Model_Data *pd)
{
@ -83,9 +92,6 @@ _eldbus_model_efl_object_destructor(Eo *obj, Eldbus_Model_Data *pd)
eina_stringshare_del(pd->address);
pd->address = NULL;
eldbus_connection_unref(pd->connection);
pd->connection = NULL;
efl_destructor(efl_super(obj, MY_CLASS));
}
@ -115,7 +121,7 @@ _eldbus_model_efl_model_property_set(Eo *obj,
{
Eina_Error err = EFL_MODEL_ERROR_READ_ONLY;
if (!strcmp(property, UNIQUE_NAME_PROPERTY))
if (strcmp(property, UNIQUE_NAME_PROPERTY))
err = EFL_MODEL_ERROR_NOT_FOUND;
return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
}
@ -153,7 +159,7 @@ _eldbus_model_efl_model_properties_get(const Eo *obj EINA_UNUSED,
Eina_Array *r;
r = eina_array_new(1);
eina_array_push(r, UNIQUE_NAME_PROPERTY);
eina_array_push(r, eina_stringshare_add(UNIQUE_NAME_PROPERTY));
return r;
}

View File

@ -46,6 +46,7 @@ class Eldbus.Model (Efl.Object, Efl.Model) {
}
implements {
Efl.Object.finalize;
Efl.Object.invalidate;
Efl.Object.destructor;
Efl.Model.property { get; set; }
Efl.Model.properties { get; }

View File

@ -30,8 +30,6 @@ _eldbus_model_arguments_hash_free(Eina_Value *value)
static Efl_Object*
_eldbus_model_arguments_efl_object_constructor(Eo *obj, Eldbus_Model_Arguments_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->obj = obj;
pd->properties_array = NULL;
pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free));
@ -39,7 +37,19 @@ _eldbus_model_arguments_efl_object_constructor(Eo *obj, Eldbus_Model_Arguments_D
pd->proxy = NULL;
pd->arguments = NULL;
pd->name = NULL;
return obj;
return efl_constructor(efl_super(obj, MY_CLASS));
}
static Efl_Object *
_eldbus_model_arguments_efl_object_finalize(Eo *obj, Eldbus_Model_Arguments_Data *pd)
{
if (!pd->proxy) return NULL;
if (!eldbus_model_connection_get(obj))
eldbus_model_connection_set(obj,
eldbus_object_connection_get(eldbus_proxy_object_get(pd->proxy)));
return efl_finalize(efl_super(obj, MY_CLASS));
}
static void
@ -70,9 +80,9 @@ _eldbus_model_arguments_efl_object_destructor(Eo *obj, Eldbus_Model_Arguments_Da
efl_destructor(efl_super(obj, MY_CLASS));
}
static Eina_Array const *
static Eina_Array *
_eldbus_model_arguments_efl_model_properties_get(const Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd)
Eldbus_Model_Arguments_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
@ -113,98 +123,58 @@ _eldbus_model_arguments_properties_load(Eldbus_Model_Arguments_Data *pd)
}
}
static Efl_Future*
_eldbus_model_arguments_efl_model_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
const char *property,
Eina_Value const* value)
static Eina_Future *
_eldbus_model_arguments_efl_model_property_set(Eo *obj,
Eldbus_Model_Arguments_Data *pd,
const char *property, Eina_Value *value)
{
Eina_Value *prop_value;
Eina_Value *promise_value;
Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future* future = efl_promise_future_get(promise);
Eina_Error err = 0;
Eina_Bool ret;
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
DBG("(%p): property=%s", obj, property);
err = EFL_MODEL_ERROR_NOT_FOUND;
if (!property || !value) goto on_error;
_eldbus_model_arguments_properties_load(pd);
Eina_Bool ret = _eldbus_model_arguments_is_input_argument(pd, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY, future);
err = EFL_MODEL_ERROR_READ_ONLY;
ret = _eldbus_model_arguments_is_input_argument(pd, property);
if (!ret) goto on_error;
err = EFL_MODEL_ERROR_NOT_FOUND;
prop_value = eina_hash_find(pd->properties_hash, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(prop_value, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
if (!prop_value) goto on_error;
eina_value_flush(prop_value);
eina_value_copy(value, prop_value);
promise_value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, promise_value);
efl_promise_value_set(promise, promise_value, (Eina_Free_Cb)&eina_value_free);
return future;
return eina_future_resolved(efl_loop_future_scheduler_get(obj),
eina_value_reference_copy(value));
on_error:
return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
}
static Efl_Future*
_eldbus_model_arguments_efl_model_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
const char *property)
static Eina_Value *
_eldbus_model_arguments_efl_model_property_get(const Eo *obj, Eldbus_Model_Arguments_Data *pd, const char *property)
{
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future *future = efl_promise_future_get(promise);
Eina_Value *promise_value;
Eina_Value *value;
Eina_Bool ret;
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
DBG("(%p): property=%s", obj, property);
if (!property) return eina_value_error_new(EFL_MODEL_ERROR_INCORRECT_VALUE);
_eldbus_model_arguments_properties_load(pd);
Eina_Value* value = eina_hash_find(pd->properties_hash, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
value = eina_hash_find(pd->properties_hash, property);
if (!value) return eina_value_error_new(EFL_MODEL_ERROR_NOT_FOUND);
Eina_Bool ret = _eldbus_model_arguments_is_output_argument(pd, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_PERMISSION_DENIED, future);
ret = _eldbus_model_arguments_is_output_argument(pd, property);
if (!ret) return eina_value_error_new(EFL_MODEL_ERROR_PERMISSION_DENIED);
promise_value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, promise_value);
efl_promise_value_set(promise, promise_value, (Eina_Free_Cb)&eina_value_free);
return future;
}
static Eo *
_eldbus_model_arguments_efl_model_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd EINA_UNUSED)
{
return NULL;
}
static void
_eldbus_model_arguments_efl_model_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
}
static Efl_Future*
_eldbus_model_arguments_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
unsigned start EINA_UNUSED,
unsigned count EINA_UNUSED)
{
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
efl_promise_failed_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
return efl_promise_future_get(promise);
}
static Efl_Future*
_eldbus_model_arguments_efl_model_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED)
{
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future* future = efl_promise_future_get(promise);
unsigned *count = malloc(sizeof(unsigned));
*count = 0;
efl_promise_value_set(promise, count, free);
return future;
return eina_value_dup(value);
}
static const char *

View File

@ -1,6 +1,6 @@
import eldbus_types;
class Eldbus.Model.Arguments (Efl.Object, Efl.Model) {
class Eldbus.Model.Arguments (Eldbus.Model) {
[[Eldbus model arguments class]]
methods {
@ -24,14 +24,10 @@ class Eldbus.Model.Arguments (Efl.Object, Efl.Model) {
}
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
Efl.Model.properties { get; }
Efl.Model.property_set;
Efl.Model.property_get;
Efl.Model.child_add;
Efl.Model.child_del;
Efl.Model.children_slice_get;
Efl.Model.children_count_get;
Efl.Model.property { set; get; }
}
constructors {
.custom_constructor;

View File

@ -9,13 +9,7 @@
#define MY_CLASS ELDBUS_MODEL_CONNECTION_CLASS
#define MY_CLASS_NAME "Eldbus_Model_Connection"
#define UNIQUE_NAME_PROPERTY "unique_name"
static void _eldbus_model_connection_names_list_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
static void _eldbus_model_connection_connect(Eldbus_Model_Connection_Data *);
static void _eldbus_model_connection_disconnect(Eldbus_Model_Connection_Data *);
static void _eldbus_model_connection_clear(Eldbus_Model_Connection_Data *);
static Efl_Object*
_eldbus_model_connection_efl_object_constructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
@ -23,288 +17,101 @@ _eldbus_model_connection_efl_object_constructor(Eo *obj, Eldbus_Model_Connection
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->obj = obj;
pd->is_listed = EINA_FALSE;
pd->connection = NULL;
pd->properties_array = NULL;
pd->children_list = NULL;
pd->type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
pd->address = NULL;
pd->private = false;
pd->unique_name = NULL;
pd->pending_list = NULL;
return obj;
}
static void
_eldbus_model_connection_custom_constructor(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
Eldbus_Connection_Type type,
const char* address,
Eina_Bool private)
{
pd->type = type;
pd->address = eina_stringshare_add(address);
pd->private = private;
}
static void
_eldbus_model_connection_efl_object_destructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
{
eina_stringshare_del(pd->address);
_eldbus_model_connection_clear(pd);
efl_destructor(efl_super(obj, MY_CLASS));
}
static Eina_Array const *
_eldbus_model_connection_efl_model_properties_get(const Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, NULL);
if (pd->properties_array == NULL)
{
Eina_Bool ret;
pd->properties_array = eina_array_new(1);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, NULL);
ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
}
return pd->properties_array;
}
static Efl_Future*
_eldbus_model_connection_efl_model_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd EINA_UNUSED,
const char *property,
Eina_Value const* value EINA_UNUSED)
{
Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future* future = efl_promise_future_get(promise);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise,
EFL_MODEL_ERROR_NOT_FOUND, future);
efl_promise_failed_set(promise, EFL_MODEL_ERROR_READ_ONLY);
return future;
}
static Efl_Future*
_eldbus_model_connection_efl_model_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
const char *property)
{
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future *future = efl_promise_future_get(promise);
DBG("(%p): property=%s", obj, property);
if (!pd->connection)
_eldbus_model_connection_connect(pd);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise,
EFL_MODEL_ERROR_NOT_FOUND, future);
if (pd->unique_name == NULL)
{
const char *unique_name;
unique_name = eldbus_connection_unique_name_get(pd->connection);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
pd->unique_name = strdup(unique_name);
}
Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING);
eina_value_set(v, pd->unique_name);
efl_promise_value_set(promise, v, (Eina_Free_Cb)&eina_value_free);
return future;
}
static Eo *
_eldbus_model_connection_efl_model_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd EINA_UNUSED)
{
return NULL;
}
static void
_eldbus_model_connection_efl_model_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
}
static Efl_Promise*
_eldbus_model_connection_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
unsigned int start,
unsigned int count)
{
Efl_Promise *promise;
Efl_Future *future;
_Eldbus_Children_Slice_Promise* data;
Eldbus_Pending *pending;
promise = efl_add(EFL_PROMISE_CLASS, obj);
future = efl_promise_future_get(promise);
if (!pd->connection)
_eldbus_model_connection_connect(pd);
if (pd->is_listed)
{
Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
efl_promise_value_set(promise, ac, (Eina_Free_Cb)&eina_accessor_free);
return future;
}
data = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
EINA_SAFETY_ON_NULL_RETURN_VAL(data, future);
data->promise = promise;
data->start = start;
data->count = count;
pd->children_promises = eina_list_prepend(pd->children_promises, data);
if (pd->pending_list == NULL)
{
pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
pd->pending_list = eina_list_append(pd->pending_list, pending);
}
return future;
}
static Efl_Future*
_eldbus_model_connection_efl_model_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd)
{
Efl_Promise *promise;
Eldbus_Pending *pending;
promise = efl_add(EFL_PROMISE_CLASS, obj);
if (!pd->connection)
_eldbus_model_connection_connect(pd);
if (pd->is_listed)
{
unsigned int *c = calloc(sizeof(unsigned int), 1);
*c = eina_list_count(pd->children_list);
efl_promise_value_set(promise, c, free);
return efl_promise_future_get(promise);
}
pd->count_promises = eina_list_prepend(pd->count_promises, promise);
if (pd->pending_list == NULL)
{
pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
pd->pending_list = eina_list_append(pd->pending_list, pending);
}
return efl_promise_future_get(promise);
}
static const char *
_eldbus_model_connection_address_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
return pd->address;
}
static Eina_Bool
_eldbus_model_connection_private_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
return pd->private;
}
static Eldbus_Connection_Type
_eldbus_model_connection_type_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
return pd->type;
}
static void
_eldbus_model_connection_connect(Eldbus_Model_Connection_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN(pd);
if (ELDBUS_CONNECTION_TYPE_ADDRESS == pd->type)
{
if (pd->private)
pd->connection = eldbus_address_connection_get(pd->address);
else
pd->connection = eldbus_private_address_connection_get(pd->address);
}
else
{
if (pd->private)
pd->connection = eldbus_private_connection_get(pd->type);
else
pd->connection = eldbus_connection_get(pd->type);
}
// TODO: Register for disconnection event
EINA_SAFETY_ON_FALSE_RETURN(pd->connection != NULL);
}
static void
_eldbus_model_connection_disconnect(Eldbus_Model_Connection_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN(pd);
eldbus_connection_unref(pd->connection);
pd->connection = NULL;
}
static void
_eldbus_model_connection_clear(Eldbus_Model_Connection_Data *pd)
{
Eldbus_Pending *pending;
Eldbus_Children_Slice_Promise *slice;
Eo *child;
EINA_SAFETY_ON_NULL_RETURN(pd);
if (pd->pending) eldbus_pending_cancel(pd->pending);
if (!pd->connection)
return;
free(pd->unique_name);
pd->unique_name = NULL;
EINA_LIST_FREE(pd->children_list, child)
EINA_LIST_FREE(pd->childrens, child)
efl_del(child);
EINA_LIST_FREE(pd->pending_list, pending)
eldbus_pending_cancel(pending);
if (pd->properties_array)
EINA_LIST_FREE(pd->requests, slice)
{
eina_array_free(pd->properties_array);
pd->properties_array = NULL;
eina_promise_reject(slice->p, EFL_MODEL_ERROR_UNKNOWN);
free(slice);
}
_eldbus_model_connection_disconnect(pd);
efl_destructor(efl_super(obj, ELDBUS_MODEL_CONNECTION_CLASS));
}
static void
_eldbus_model_children_list(const Eo *obj, Eldbus_Model_Connection_Data *pd)
{
Eldbus_Model_Data *sd;
if (pd->pending || pd->is_listed) return ;
sd = efl_data_scope_get(obj, ELDBUS_MODEL_CLASS);
pd->pending = eldbus_names_list(sd->connection,
&_eldbus_model_connection_names_list_cb,
pd);
}
static Eina_Future *
_eldbus_model_connection_efl_model_children_slice_get(Eo *obj,
Eldbus_Model_Connection_Data *pd,
unsigned int start,
unsigned int count)
{
Eldbus_Children_Slice_Promise* slice;
Eina_Promise *p;
if (pd->is_listed)
{
Eina_Value v;
v = efl_model_list_value_get(pd->childrens, start, count);
return eina_future_resolved(efl_loop_future_scheduler_get(obj), v);
}
p = eina_promise_new(efl_loop_future_scheduler_get(obj),
_eldbus_eina_promise_cancel, NULL);
slice = calloc(1, sizeof (Eldbus_Children_Slice_Promise));
slice->p = p;
slice->start = start;
slice->count = count;
pd->requests = eina_list_prepend(pd->requests, slice);
_eldbus_model_children_list(obj, pd);
return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));;
}
static unsigned int
_eldbus_model_connection_efl_model_children_count_get(const Eo *obj,
Eldbus_Model_Connection_Data *pd)
{
_eldbus_model_children_list(obj, pd);
return eina_list_count(pd->childrens);
}
static void
_eldbus_model_connection_names_list_cb(void *data,
const Eldbus_Message *msg,
Eldbus_Pending *pending)
Eldbus_Pending *pending EINA_UNUSED)
{
Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*)data;
_Eldbus_Children_Slice_Promise * p;
Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*) data;
Eldbus_Model_Data *sd;
Eldbus_Children_Slice_Promise *slice;
const char *error_name, *error_text;
Eldbus_Message_Iter *array = NULL;
const char *bus;
unsigned int count;
Eina_List* i;
pd->pending_list = eina_list_remove(pd->pending_list, pending);
pd->pending = NULL;
if (eldbus_message_error_get(msg, &error_name, &error_text))
{
ERR("%s: %s", error_name, error_text);
//efl_model_error_notify(pd->obj);
return;
}
@ -314,39 +121,37 @@ _eldbus_model_connection_names_list_cb(void *data,
return;
}
sd = efl_data_scope_get(pd->obj, ELDBUS_MODEL_CLASS);
while (eldbus_message_iter_get_and_next(array, 's', &bus))
{
Eo *child;
DBG("(%p): bus = %s", pd->obj, bus);
Eo *child = efl_add(ELDBUS_MODEL_OBJECT_CLASS, pd->obj, eldbus_model_object_connection_constructor(efl_added, pd->connection, bus, "/"));
child = efl_add(ELDBUS_MODEL_OBJECT_CLASS, pd->obj,
eldbus_model_connection_set(efl_added, sd->connection),
eldbus_model_object_bus_set(efl_added, bus),
eldbus_model_object_path_set(efl_added, "/"));
pd->children_list = eina_list_append(pd->children_list, child);
pd->childrens = eina_list_append(pd->childrens, child);
}
count = eina_list_count(pd->children_list);
if (count)
efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
pd->is_listed = EINA_TRUE;
EINA_LIST_FOREACH(pd->children_promises, i, p)
{
Eina_Accessor *ac = efl_model_list_slice(pd->children_list, p->start, p->count);
efl_promise_value_set(p->promise, ac, (Eina_Free_Cb)&eina_accessor_free);
free(p);
}
eina_list_free(pd->children_promises);
count = eina_list_count(pd->childrens);
efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
Efl_Promise *ep;
EINA_LIST_FOREACH(pd->count_promises, i, ep)
EINA_LIST_FREE(pd->requests, slice)
{
unsigned *c = calloc(sizeof(unsigned), 1);
*c = eina_list_count(pd->children_list);
efl_promise_value_set(ep, c, free);
Eina_Value v;
v = efl_model_list_value_get(pd->childrens,
slice->start, slice->count);
eina_promise_resolve(slice->p, v);
free(slice);
}
eina_list_free(pd->count_promises);
}
#include "eldbus_model_connection.eo.c"

View File

@ -1,53 +1,12 @@
import eldbus_types;
class Eldbus.Model.Connection (Efl.Object, Efl.Model) {
class Eldbus.Model.Connection (Eldbus.Model) {
[[Eldbus model connection class]]
methods {
custom_constructor {
[[Custom Eldbus_Model_Connection constructor.
@since 1.16]]
params {
@in type: Eldbus.Connection.Type; [[The connection type]]
@in address: string; [[Remote address of DBus]]
@in private_: bool; [[Non shared dbus connection]]
}
}
@property type {
[[Connection type]]
get { }
values {
type: Eldbus.Connection.Type; [[Connection type]]
}
}
@property address {
[[Remote DBus address]]
get { }
values {
address: string; [[Address]]
}
}
@property private {
[[Indicate if the DBus connection is shared or private]]
get { }
values {
private_: bool; [[Private DBus connection]]
}
}
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Model.properties { get; }
Efl.Model.property_set;
Efl.Model.property_get;
Efl.Model.child_add;
Efl.Model.child_del;
Efl.Model.children_slice_get;
Efl.Model.children_count_get;
}
constructors {
.custom_constructor;
Efl.Model.children_count { get; }
}
}

View File

@ -13,18 +13,20 @@ typedef struct _Eldbus_Model_Connection_Data Eldbus_Model_Connection_Data;
struct _Eldbus_Model_Connection_Data
{
Eo *obj;
Eina_Bool is_listed : 1;
Eldbus_Connection *connection;
Eina_Array *properties_array;
Eina_List *children_list;
Eina_List *children_promises;
Eina_List *count_promises;
Eldbus_Pending *pending;
Eldbus_Connection_Type type;
Eina_List *childrens;
Eina_List *requests;
Eina_Stringshare *address;
bool private;
char *unique_name;
Eina_List *pending_list;
bool private;
Eina_Bool is_listed : 1;
};
#endif

View File

@ -26,17 +26,33 @@ _eldbus_model_method_efl_object_constructor(Eo *obj, Eldbus_Model_Method_Data *p
return obj;
}
static void
_eldbus_model_method_method_constructor(Eo *obj EINA_UNUSED,
Eldbus_Model_Method_Data *pd,
Eldbus_Proxy *proxy,
const Eldbus_Introspection_Method *method)
static Efl_Object*
_eldbus_model_method_efl_object_finalize(Eo *obj, Eldbus_Model_Method_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN(proxy);
EINA_SAFETY_ON_NULL_RETURN(method);
if (!pd->proxy ||
!pd->method)
return NULL;
eldbus_model_arguments_custom_constructor(efl_super(obj, MY_CLASS), proxy, method->name, method->arguments);
eldbus_model_arguments_custom_constructor(obj,
pd->proxy,
pd->method->name, pd->method->arguments);
return obj;
}
static void
_eldbus_model_method_proxy_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Method_Data *pd,
Eldbus_Proxy *proxy)
{
pd->proxy = proxy;
}
static void
_eldbus_model_method_method_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Method_Data *pd,
const Eldbus_Introspection_Method *method)
{
pd->method = method;
}

View File

@ -3,13 +3,20 @@ import eldbus_types;
class Eldbus.Model.Method (Eldbus.Model.Arguments) {
[[Eldbus model method class]]
methods {
method_constructor {
@property proxy {
[[Custom Eldbus_Model_Method constructor.
@since 1.16]]
params {
@in proxy: ptr(Eldbus.Proxy); [[Eldbus proxy]]
@cref method: Eldbus.Introspection.Method; [[The introspected method]]
@since 1.21]]
set {}
values {
proxy: ptr(Eldbus.Proxy); [[Eldbus proxy]]
}
}
@property method {
[[Object]]
set {}
values {
@cref method: Eldbus.Introspection.Method; [[The introspected interface]]
}
}
call {
@ -24,9 +31,11 @@ class Eldbus.Model.Method (Eldbus.Model.Arguments) {
}
implements {
Efl.Object.constructor;
Efl.Object.finalize;
}
constructors {
.method_constructor;
.proxy;
.method;
}
events {
successful,call; [[Event dispatched for a successful method call.]]

View File

@ -11,8 +11,10 @@ typedef struct _Eldbus_Model_Method_Data Eldbus_Model_Method_Data;
struct _Eldbus_Model_Method_Data
{
Eo *obj;
const Eldbus_Introspection_Method *method;
Eldbus_Proxy *proxy;
};
#endif

View File

@ -11,15 +11,7 @@
#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS
#define MY_CLASS_NAME "Eldbus_Model_Object"
#define UNIQUE_NAME_PROPERTY "unique_name"
static bool _eldbus_model_object_introspect(Eldbus_Model_Object_Data *, const char *, const char *);
static void _eldbus_model_object_introspect_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
static void _eldbus_model_object_connect(Eldbus_Model_Object_Data *);
static void _eldbus_model_object_disconnect(Eldbus_Model_Object_Data *);
static void _eldbus_model_object_clear(Eldbus_Model_Object_Data *);
static void _eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *, const char *, Eina_List *);
static char *_eldbus_model_object_concatenate_path(const char *, const char *);
static void _eldbus_model_object_create_children(Eldbus_Model_Object_Data *, Eldbus_Object *, Eina_List *);
static Efl_Object*
@ -28,219 +20,135 @@ _eldbus_model_object_efl_object_constructor(Eo *obj, Eldbus_Model_Object_Data *p
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->obj = obj;
pd->is_listed = EINA_FALSE;
pd->connection = NULL;
pd->object_list = NULL;
pd->properties_array = NULL;
pd->children_list = NULL;
pd->type = ELDBUS_CONNECTION_TYPE_UNKNOWN;
pd->address = NULL;
pd->private = false;
pd->bus = NULL;
pd->path = NULL;
pd->unique_name = NULL;
pd->pending_list = NULL;
pd->introspection = NULL;
return obj;
}
static void
_eldbus_model_object_custom_constructor(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
Eldbus_Connection_Type type,
const char* address,
Eina_Bool private,
const char* bus,
const char* path)
_eldbus_model_object_bus_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
const char *bus)
{
EINA_SAFETY_ON_NULL_RETURN(bus);
EINA_SAFETY_ON_NULL_RETURN(path);
pd->type = type;
pd->address = eina_stringshare_add(address);
pd->private = private;
pd->bus = eina_stringshare_add(bus);
pd->path = eina_stringshare_add(path);
}
static void
_eldbus_model_object_connection_constructor(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
Eldbus_Connection *connection,
const char* bus,
const char* path)
_eldbus_model_object_path_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
const char *path)
{
EINA_SAFETY_ON_NULL_RETURN(connection);
EINA_SAFETY_ON_NULL_RETURN(bus);
EINA_SAFETY_ON_NULL_RETURN(path);
pd->connection = eldbus_connection_ref(connection);
pd->bus = eina_stringshare_add(bus);
pd->path = eina_stringshare_add(path);
}
static Efl_Object*
_eldbus_model_object_efl_object_finalize(Eo *obj, Eldbus_Model_Object_Data *pd)
{
if (!pd->bus || !pd->path)
return NULL;
return efl_finalize(efl_super(obj, MY_CLASS));
}
static void
_eldbus_model_object_efl_object_invalidate(Eo *obj, Eldbus_Model_Object_Data *pd)
{
Eldbus_Pending *pending;
Eldbus_Object *object;
Eo *child;
EINA_LIST_FREE(pd->childrens, child)
efl_unref(child);
EINA_LIST_FREE(pd->pendings, pending)
eldbus_pending_cancel(pending);
EINA_LIST_FREE(pd->objects, object)
eldbus_object_unref(object);
if (pd->introspection)
{
eldbus_introspection_node_free(pd->introspection);
pd->introspection = NULL;
}
efl_invalidate(efl_super(obj, MY_CLASS));
}
static void
_eldbus_model_object_efl_object_destructor(Eo *obj, Eldbus_Model_Object_Data *pd)
{
eina_stringshare_del(pd->address);
eina_stringshare_del(pd->bus);
eina_stringshare_del(pd->path);
_eldbus_model_object_clear(pd);
efl_destructor(efl_super(obj, MY_CLASS));
}
static Eina_Array const *
_eldbus_model_object_efl_model_properties_get(const Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, NULL);
if (pd->properties_array == NULL)
{
Eina_Bool ret;
pd->properties_array = eina_array_new(1);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, NULL);
ret = eina_array_push(pd->properties_array, UNIQUE_NAME_PROPERTY);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
}
return pd->properties_array;
}
static Efl_Future*
_eldbus_model_object_efl_model_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd EINA_UNUSED,
const char *property,
const Eina_Value *value EINA_UNUSED)
{
Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise,
EFL_MODEL_ERROR_NOT_FOUND, efl_promise_future_get(promise));
efl_promise_failed_set(promise, EFL_MODEL_ERROR_READ_ONLY);
return efl_promise_future_get(promise);
}
static Efl_Future*
_eldbus_model_object_efl_model_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
const char *property)
{
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future *future = efl_promise_future_get(promise);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
DBG("(%p): property=%s", obj, property);
if (!pd->connection)
_eldbus_model_object_connect(pd);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise,
EFL_MODEL_ERROR_NOT_FOUND, future);
if (pd->unique_name == NULL)
{
const char *unique_name;
unique_name = eldbus_connection_unique_name_get(pd->connection);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
pd->unique_name = strdup(unique_name);
}
Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING);
eina_value_set(v, pd->unique_name);
efl_promise_value_set(promise, v, (Eina_Free_Cb)&eina_value_free);
return future;
}
static Eo *
_eldbus_model_object_efl_model_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd EINA_UNUSED)
{
return NULL;
}
static void
_eldbus_model_object_efl_model_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
}
static Efl_Future*
_eldbus_model_object_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
unsigned start,
unsigned count)
{
_Eldbus_Children_Slice_Promise* p;
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
Efl_Future *future = efl_promise_future_get(promise);
if (!pd->connection)
_eldbus_model_object_connect(pd);
if (pd->is_listed)
{
Eina_Accessor* ac = efl_model_list_slice(pd->children_list, start, count);
efl_promise_value_set(promise, ac, (Eina_Free_Cb)&eina_accessor_free);
return future;
}
p = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
EINA_SAFETY_ON_NULL_RETURN_VAL(p, future);
p->promise = promise;
p->start = start;
p->count = count;
pd->children_promises = eina_list_prepend(pd->children_promises, p);
if (pd->pending_list == NULL)
_eldbus_model_object_introspect(pd, pd->bus, pd->path);
return future;
}
static Efl_Future*
_eldbus_model_object_efl_model_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd)
{
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
if (!pd->connection)
_eldbus_model_object_connect(pd);
if (pd->is_listed)
{
unsigned int *c = calloc(sizeof(unsigned int), 1);
*c = eina_list_count(pd->children_list);
efl_promise_value_set(promise, c, free);
return efl_promise_future_get(promise);
}
pd->count_promises = eina_list_prepend(pd->count_promises, promise);
if (pd->pending_list == NULL)
_eldbus_model_object_introspect(pd, pd->bus, pd->path);
return efl_promise_future_get(promise);
}
static const char *
_eldbus_model_object_address_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
{
return pd->address;
}
static Eina_Bool
_eldbus_model_object_private_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
_eldbus_model_object_introspect(const Eo *obj,
Eldbus_Model_Object_Data *pd,
const char *bus,
const char *path)
{
return pd->private;
Eldbus_Pending *pending;
Eldbus_Object *object;
DBG("(%p) Introspecting: bus = %s, path = %s", pd->obj, bus, path);
object = eldbus_object_get(eldbus_model_connection_get(obj),
bus, path);
if (!object)
{
ERR("(%p): Cannot get object: bus=%s, path=%s", pd->obj, bus, path);
return EINA_FALSE;
}
pd->objects = eina_list_append(pd->objects, object);
// TODO: Register for interface added/removed event
pending = eldbus_object_introspect(object, &_eldbus_model_object_introspect_cb, pd);
eldbus_pending_data_set(pending, "object", object);
pd->pendings = eina_list_append(pd->pendings, pending);
return EINA_TRUE;
}
static Eldbus_Connection_Type
_eldbus_model_object_type_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
static Eina_Future *
_eldbus_model_object_efl_model_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
unsigned start,
unsigned count)
{
return pd->type;
Eldbus_Children_Slice_Promise *slice;
Eina_Promise *p;
if (pd->is_listed)
{
Eina_Value v;
v = efl_model_list_value_get(pd->childrens, start, count);
return eina_future_resolved(efl_loop_future_scheduler_get(obj), v);
}
p = eina_promise_new(efl_loop_future_scheduler_get(obj),
_eldbus_eina_promise_cancel, NULL);
slice = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
slice->p = p;
slice->start = start;
slice->count = count;
pd->requests = eina_list_prepend(pd->requests, slice);
if (!pd->pendings)
_eldbus_model_object_introspect(obj, pd, pd->bus, pd->path);
return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));;
}
static unsigned int
_eldbus_model_object_efl_model_children_count_get(const Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd)
{
if (!pd->is_listed && !pd->pendings)
_eldbus_model_object_introspect(obj, pd, pd->bus, pd->path);
return eina_list_count(pd->childrens);
}
static const char *
@ -255,105 +163,71 @@ _eldbus_model_object_path_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Dat
return pd->path;
}
static void
_eldbus_model_object_connect(Eldbus_Model_Object_Data *pd)
static char *
_eldbus_model_object_concatenate_path(const char *root_path,
const char *relative_path)
{
EINA_SAFETY_ON_NULL_RETURN(pd);
Eina_Strbuf *buffer;
const char *format = (strcmp(root_path, "/") != 0) ? "%s/%s" : "%s%s";
char *absolute_path = NULL;
if (ELDBUS_CONNECTION_TYPE_ADDRESS == pd->type)
{
if (pd->private)
pd->connection = eldbus_address_connection_get(pd->address);
else
pd->connection = eldbus_private_address_connection_get(pd->address);
}
else
{
if (pd->private)
pd->connection = eldbus_private_connection_get(pd->type);
else
pd->connection = eldbus_connection_get(pd->type);
}
buffer = eina_strbuf_new();
eina_strbuf_append_printf(buffer, format, root_path, relative_path);
absolute_path = eina_strbuf_string_steal(buffer);
// TODO: Register for disconnection event
EINA_SAFETY_ON_FALSE_RETURN(NULL != pd->connection);
eina_strbuf_free(buffer);
return absolute_path;
}
static void
_eldbus_model_object_disconnect(Eldbus_Model_Object_Data *pd)
_eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *pd,
const char *current_path,
Eina_List *nodes)
{
EINA_SAFETY_ON_NULL_RETURN(pd);
eldbus_connection_unref(pd->connection);
pd->connection = NULL;
Eldbus_Introspection_Node *node;
Eina_List *it;
EINA_LIST_FOREACH(nodes, it, node)
{
const char *relative_path;
char *absolute_path;
relative_path = node->name;
if (!relative_path) continue;
absolute_path = _eldbus_model_object_concatenate_path(current_path, relative_path);
if (!absolute_path) continue;
_eldbus_model_object_introspect(pd->obj, pd, pd->bus, absolute_path);
free(absolute_path);
}
}
static void
_eldbus_model_object_clear(Eldbus_Model_Object_Data *pd)
_eldbus_model_object_create_children(Eldbus_Model_Object_Data *pd, Eldbus_Object *object, Eina_List *interfaces)
{
Eldbus_Pending *pending;
Eldbus_Object *object;
Eo *child;
Eldbus_Introspection_Interface *interface;
const char *current_path;
Eina_List *l;
EINA_SAFETY_ON_NULL_RETURN(pd);
if (!pd->connection)
return;
current_path = eldbus_object_path_get(object);
if (!current_path) return ;
free(pd->unique_name);
pd->unique_name = NULL;
EINA_LIST_FREE(pd->children_list, child)
efl_unref(child);
EINA_LIST_FREE(pd->pending_list, pending)
eldbus_pending_cancel(pending);
if (pd->properties_array)
EINA_LIST_FOREACH(interfaces, l, interface)
{
eina_array_free(pd->properties_array);
pd->properties_array = NULL;
Eo *child;
DBG("(%p) Creating child: bus = %s, path = %s, interface = %s",
pd->obj, pd->bus, current_path, interface->name);
// TODO: increment reference to keep 'interface' in memory
child = efl_add_ref(ELDBUS_MODEL_PROXY_CLASS, pd->obj,
eldbus_model_proxy_object_set(efl_added, object),
eldbus_model_proxy_interface_set(efl_added, interface));
if (child) pd->childrens = eina_list_append(pd->childrens, child);
}
EINA_LIST_FREE(pd->object_list, object)
eldbus_object_unref(object);
if (pd->introspection)
{
eldbus_introspection_node_free(pd->introspection);
pd->introspection = NULL;
}
_eldbus_model_object_disconnect(pd);
}
static bool
_eldbus_model_object_introspect(Eldbus_Model_Object_Data *pd,
const char *bus,
const char *path)
{
Eldbus_Object *object;
Eldbus_Pending *pending;
EINA_SAFETY_ON_NULL_RETURN_VAL(bus, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(path, false);
DBG("(%p) Introspecting: bus = %s, path = %s", pd->obj, bus, path);
object = eldbus_object_get(pd->connection, bus, path);
if (!object)
{
ERR("(%p): Cannot get object: bus=%s, path=%s", pd->obj, bus, path);
return false;
}
pd->object_list = eina_list_append(pd->object_list, object);
// TODO: Register for interface added/removed event
pending = eldbus_object_introspect(object, &_eldbus_model_object_introspect_cb, pd);
eldbus_pending_data_set(pending, "object", object);
pd->pending_list = eina_list_append(pd->pending_list, pending);
return true;
}
static void
@ -362,12 +236,15 @@ _eldbus_model_object_introspect_cb(void *data,
Eldbus_Pending *pending)
{
Eldbus_Model_Object_Data *pd = (Eldbus_Model_Object_Data*)data;
Eldbus_Children_Slice_Promise* slice;
Eldbus_Object *object;
const char *error_name, *error_text;
const char *error_name;
const char *error_text;
const char *xml = NULL;
const char *current_path;
unsigned int count;
pd->pending_list = eina_list_remove(pd->pending_list, pending);
pd->pendings = eina_list_remove(pd->pendings, pending);
object = eldbus_pending_data_get(pending, "object");
if (eldbus_message_error_get(msg, &error_name, &error_text))
@ -382,114 +259,36 @@ _eldbus_model_object_introspect_cb(void *data,
ERR("Error getting arguments.");
return;
}
EINA_SAFETY_ON_NULL_RETURN(xml);
if (!xml)
{
ERR("No XML.");
return ;
}
current_path = eldbus_object_path_get(object);
EINA_SAFETY_ON_NULL_RETURN(current_path);
pd->introspection = eldbus_introspection_parse(xml);
DBG("(%p): introspect of bus = %s, path = %s =>\n%s", pd->obj, pd->bus, current_path, xml);
pd->introspection = eldbus_introspection_parse(xml);
EINA_SAFETY_ON_NULL_RETURN(pd->introspection);
_eldbus_model_object_introspect_nodes(pd, current_path, pd->introspection->nodes);
_eldbus_model_object_create_children(pd, object, pd->introspection->interfaces);
if (eina_list_count(pd->pending_list) == 0)
if (eina_list_count(pd->pendings) != 0) return ;
count = eina_list_count(pd->childrens);
efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
pd->is_listed = EINA_TRUE;
EINA_LIST_FREE(pd->requests, slice)
{
Eina_List* i;
Eina_Value v;
pd->is_listed = EINA_TRUE;
_Eldbus_Children_Slice_Promise* p;
EINA_LIST_FOREACH(pd->children_promises, i, p)
{
Eina_Accessor* ac = efl_model_list_slice(pd->children_list, p->start, p->count);
efl_promise_value_set(p->promise, ac, (Eina_Free_Cb)&eina_accessor_free);
free(p);
}
pd->children_promises = eina_list_free(pd->children_promises);
v = efl_model_list_value_get(pd->childrens, slice->start, slice->count);
eina_promise_resolve(slice->p, v);
Efl_Promise *ep;
EINA_LIST_FOREACH(pd->count_promises, i, ep)
{
unsigned *c = calloc(sizeof(unsigned), 1);
*c = eina_list_count(pd->children_list);
efl_promise_value_set(ep, c, free);
}
pd->count_promises = eina_list_free(pd->count_promises);
}
}
static void
_eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *pd, const char *current_path, Eina_List *nodes)
{
Eina_List *it;
Eldbus_Introspection_Node *node;
EINA_SAFETY_ON_NULL_RETURN(pd);
EINA_SAFETY_ON_NULL_RETURN(current_path);
EINA_LIST_FOREACH(nodes, it, node)
{
const char *relative_path;
char *absolute_path;
relative_path = node->name;
if (!relative_path) continue;
absolute_path = _eldbus_model_object_concatenate_path(current_path, relative_path);
if (!absolute_path) continue;
_eldbus_model_object_introspect(pd, pd->bus, absolute_path);
free(absolute_path);
}
}
static char *
_eldbus_model_object_concatenate_path(const char *root_path, const char *relative_path)
{
Eina_Strbuf *buffer;
char *absolute_path = NULL;
Eina_Bool ret;
buffer = eina_strbuf_new();
EINA_SAFETY_ON_NULL_RETURN_VAL(buffer, NULL);
ret = eina_strbuf_append(buffer, root_path);
if (strcmp(root_path, "/") != 0)
ret = ret && eina_strbuf_append_char(buffer, '/');
ret = ret && eina_strbuf_append(buffer, relative_path);
EINA_SAFETY_ON_FALSE_GOTO(ret, free_buffer);
absolute_path = eina_strbuf_string_steal(buffer);
free_buffer:
eina_strbuf_free(buffer);
return absolute_path;
}
static void
_eldbus_model_object_create_children(Eldbus_Model_Object_Data *pd, Eldbus_Object *object, Eina_List *interfaces)
{
Eldbus_Introspection_Interface *interface;
Eina_List *it;
const char *current_path;
current_path = eldbus_object_path_get(object);
EINA_SAFETY_ON_NULL_RETURN(current_path);
EINA_LIST_FOREACH(interfaces, it, interface)
{
Eo *child;
DBG("(%p) Creating child: bus = %s, path = %s, interface = %s", pd->obj, pd->bus, current_path, interface->name);
// TODO: increment reference to keep 'interface' in memory
child = efl_add_ref(ELDBUS_MODEL_PROXY_CLASS, pd->obj, eldbus_model_proxy_custom_constructor(efl_added, object, interface));
pd->children_list = eina_list_append(pd->children_list, child);
free(slice);
}
}

View File

@ -1,63 +1,22 @@
import eldbus_types;
class Eldbus.Model.Object (Efl.Object, Efl.Model) {
class Eldbus.Model.Object (Eldbus.Model) {
[[Eldbus model object class]]
data: Eldbus_Model_Object_Data;
methods {
custom_constructor {
[[Custom Eldbus_Model_Object constructor.
@since 1.16]]
params {
@in type: Eldbus.Connection.Type; [[The connection type]]
@in address: string; [[Remote address of DBus]]
@in private_: bool; [[Non shared DBus connection]]
@in bus: string; [[DBus Name or unique-id]]
@in path: string; [[DBus path]]
}
}
connection_constructor {
[[Custom Eldbus_Model_Object connection_constructor.
@since 1.16]]
params {
@in connection: ptr(Eldbus.Connection); [[Eldbus connection]]
@in bus: string; [[DBus Name or unique-id]]
@in path: string; [[DBus path]]
}
}
@property type {
[[Connection type]]
get { }
values {
type: Eldbus.Connection.Type; [[Connection type]]
}
}
@property address {
[[Remote address of DBus]]
get { }
values {
address: string; [[Address]]
}
}
@property private {
[[Indicate if the DBus connection is shared or private]]
get { }
values {
private_: bool; [[Private DBus connection]]
}
}
@property bus {
@property bus {
[[DBus Name or unique-id]]
get { }
set { }
values {
bus: string; [[DBus name]]
}
}
@property path {
@property path {
[[DBus path]]
get { }
set { }
values {
path: string; [[DBus path]]
}
@ -65,17 +24,10 @@ class Eldbus.Model.Object (Efl.Object, Efl.Model) {
}
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.invalidate;
Efl.Object.destructor;
Efl.Model.properties { get; }
Efl.Model.property_set;
Efl.Model.property_get;
Efl.Model.child_add;
Efl.Model.child_del;
Efl.Model.children_slice_get;
Efl.Model.children_count_get;
}
constructors {
.custom_constructor;
.connection_constructor;
Efl.Model.children_count { get; }
}
}

View File

@ -12,22 +12,18 @@ typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
struct _Eldbus_Model_Object_Data
{
Eo *obj;
Eina_Bool is_listed : 1;
Eldbus_Connection *connection;
Eina_List *object_list;
Eina_Array *properties_array;
Eina_List *children_list;
Eina_List *children_promises;
Eina_List *count_promises;
Eldbus_Connection_Type type;
Eina_Stringshare *address;
bool private;
Eina_List *objects;
Eina_List *childrens;
Eina_List *requests;
Eina_List *pendings;
Eina_Stringshare *bus;
Eina_Stringshare *path;
char *unique_name;
Eina_List *pending_list;
Eldbus_Introspection_Node *introspection;
Eina_Bool is_listed : 1;
};
#endif

View File

@ -8,19 +8,28 @@
#include <Eo.h>
#include <Efl.h>
typedef struct _Eldbus_Children_Slice_Promise _Eldbus_Children_Slice_Promise;
typedef struct _Eldbus_Children_Slice_Promise Eldbus_Children_Slice_Promise;
typedef struct _Eldbus_Model_Data Eldbus_Model_Data;
struct _Eldbus_Children_Slice_Promise
{
unsigned start;
unsigned count;
Efl_Promise* promise;
Eina_Promise *p;
unsigned int start;
unsigned int count;
};
typedef struct _Eldbus_Property_Promise _Eldbus_Property_Promise;
struct _Eldbus_Property_Promise
struct _Eldbus_Model_Data
{
char *property;
Efl_Promise* promise;
Eldbus_Connection *connection;
Eldbus_Connection_Type type;
Eina_Stringshare *address;
Eina_Stringshare *unique_name;
Eina_Bool private : 1;
Eina_Bool is_listed : 1;
};
#define UNIQUE_NAME_PROPERTY "unique_name"
@ -28,6 +37,12 @@ struct _Eldbus_Property_Promise
/* logging support */
extern int eldbus_model_log_dom;
static inline void
_eldbus_eina_promise_cancel(void *data EINA_UNUSED,
const Eina_Promise *dead_ptr EINA_UNUSED)
{
}
#define ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(exp, promise, err, v) \
do \
{ \

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,24 @@
import eldbus_types;
class Eldbus.Model.Proxy (Efl.Object, Efl.Model) {
class Eldbus.Model.Proxy (Eldbus.Model) {
[[Eldbus model proxy class]]
methods {
custom_constructor {
[[Custom Eldbus_Model_Proxy constructor.
@since 1.16]]
params {
@in object: ptr(Eldbus.Object); [[Eldbus object]]
@property object {
[[Object]]
set {}
values {
object: ptr(Eldbus.Object); [[Eldbus object]]
}
}
@property interface {
[[Object]]
set {}
values {
@cref interface: Eldbus.Introspection.Interface; [[The introspected interface]]
}
}
@property proxy_name {
@property proxy_name {
[[Proxy name]]
get {}
values {
@ -23,16 +28,15 @@ class Eldbus.Model.Proxy (Efl.Object, Efl.Model) {
}
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.invalidate;
Efl.Object.destructor;
Efl.Model.properties { get; }
Efl.Model.property_set;
Efl.Model.property_get;
Efl.Model.child_add;
Efl.Model.child_del;
Efl.Model.property { set; get; }
Efl.Model.children_slice_get;
Efl.Model.children_count_get;
Efl.Model.children_count { get; }
}
constructors {
.custom_constructor;
.interface;
}
}

View File

@ -13,20 +13,21 @@ typedef struct _Eldbus_Model_Proxy_Data Eldbus_Model_Proxy_Data;
struct _Eldbus_Model_Proxy_Data
{
Eo *obj;
Eina_Bool is_listed : 1;
Eina_Bool is_loaded : 1;
const Eldbus_Introspection_Interface *interface;
Eldbus_Object *object;
Eldbus_Proxy *proxy;
Eina_Array *properties_array;
Eina_Hash *properties_hash;
Eina_List *children_list;
Eina_Hash *properties;
Eina_List *childrens;
Eina_List *pendings;
Eina_List *promises;
Eina_Stringshare *name;
Eina_List *pending_list;
Eina_List *promise_list;
bool monitoring;
const Eldbus_Introspection_Interface *interface;
Eina_Value tmp_value;
Eina_Bool monitoring : 1;
Eina_Bool is_listed : 1;
Eina_Bool is_loaded : 1;
};
#endif