forked from enlightenment/efl
eldbus: migrate and refactor eldbus.model to new efl.model API.
This commit is contained in:
parent
ddcf8d8b97
commit
3edb4ca697
|
@ -225,6 +225,7 @@ typedef void (*Eldbus_Signal_Cb)(void *data, const Eldbus_Message *msg);
|
||||||
|
|
||||||
#ifdef EFL_BETA_API_SUPPORT
|
#ifdef EFL_BETA_API_SUPPORT
|
||||||
|
|
||||||
|
#include "eldbus_model.eo.h"
|
||||||
#include "eldbus_model_arguments.eo.h"
|
#include "eldbus_model_arguments.eo.h"
|
||||||
#include "eldbus_model_connection.eo.h"
|
#include "eldbus_model_connection.eo.h"
|
||||||
#include "eldbus_model_method.eo.h"
|
#include "eldbus_model_method.eo.h"
|
||||||
|
|
|
@ -74,6 +74,15 @@ _eldbus_model_efl_object_finalize(Eo *obj, Eldbus_Model_Data *pd)
|
||||||
return efl_finalize(efl_super(obj, ELDBUS_MODEL_CLASS));
|
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
|
static void
|
||||||
_eldbus_model_efl_object_destructor(Eo *obj, Eldbus_Model_Data *pd)
|
_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);
|
eina_stringshare_del(pd->address);
|
||||||
pd->address = NULL;
|
pd->address = NULL;
|
||||||
|
|
||||||
eldbus_connection_unref(pd->connection);
|
|
||||||
pd->connection = NULL;
|
|
||||||
|
|
||||||
efl_destructor(efl_super(obj, MY_CLASS));
|
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;
|
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;
|
err = EFL_MODEL_ERROR_NOT_FOUND;
|
||||||
return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
|
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;
|
Eina_Array *r;
|
||||||
|
|
||||||
r = eina_array_new(1);
|
r = eina_array_new(1);
|
||||||
eina_array_push(r, UNIQUE_NAME_PROPERTY);
|
eina_array_push(r, eina_stringshare_add(UNIQUE_NAME_PROPERTY));
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ class Eldbus.Model (Efl.Object, Efl.Model) {
|
||||||
}
|
}
|
||||||
implements {
|
implements {
|
||||||
Efl.Object.finalize;
|
Efl.Object.finalize;
|
||||||
|
Efl.Object.invalidate;
|
||||||
Efl.Object.destructor;
|
Efl.Object.destructor;
|
||||||
Efl.Model.property { get; set; }
|
Efl.Model.property { get; set; }
|
||||||
Efl.Model.properties { get; }
|
Efl.Model.properties { get; }
|
||||||
|
|
|
@ -30,8 +30,6 @@ _eldbus_model_arguments_hash_free(Eina_Value *value)
|
||||||
static Efl_Object*
|
static Efl_Object*
|
||||||
_eldbus_model_arguments_efl_object_constructor(Eo *obj, Eldbus_Model_Arguments_Data *pd)
|
_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->obj = obj;
|
||||||
pd->properties_array = NULL;
|
pd->properties_array = NULL;
|
||||||
pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free));
|
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->proxy = NULL;
|
||||||
pd->arguments = NULL;
|
pd->arguments = NULL;
|
||||||
pd->name = 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
|
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));
|
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_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);
|
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*
|
static Eina_Future *
|
||||||
_eldbus_model_arguments_efl_model_property_set(Eo *obj EINA_UNUSED,
|
_eldbus_model_arguments_efl_model_property_set(Eo *obj,
|
||||||
Eldbus_Model_Arguments_Data *pd,
|
Eldbus_Model_Arguments_Data *pd,
|
||||||
const char *property,
|
const char *property, Eina_Value *value)
|
||||||
Eina_Value const* value)
|
|
||||||
{
|
{
|
||||||
Eina_Value *prop_value;
|
Eina_Value *prop_value;
|
||||||
Eina_Value *promise_value;
|
Eina_Error err = 0;
|
||||||
Efl_Promise* promise = efl_add(EFL_PROMISE_CLASS, obj);
|
Eina_Bool ret;
|
||||||
Efl_Future* future = efl_promise_future_get(promise);
|
|
||||||
|
|
||||||
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);
|
DBG("(%p): property=%s", obj, property);
|
||||||
|
|
||||||
|
err = EFL_MODEL_ERROR_NOT_FOUND;
|
||||||
|
if (!property || !value) goto on_error;
|
||||||
|
|
||||||
_eldbus_model_arguments_properties_load(pd);
|
_eldbus_model_arguments_properties_load(pd);
|
||||||
|
|
||||||
Eina_Bool ret = _eldbus_model_arguments_is_input_argument(pd, property);
|
err = EFL_MODEL_ERROR_READ_ONLY;
|
||||||
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY, future);
|
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);
|
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_flush(prop_value);
|
||||||
eina_value_copy(value, prop_value);
|
eina_value_copy(value, prop_value);
|
||||||
|
|
||||||
promise_value = eina_value_new(eina_value_type_get(value));
|
return eina_future_resolved(efl_loop_future_scheduler_get(obj),
|
||||||
eina_value_copy(value, promise_value);
|
eina_value_reference_copy(value));
|
||||||
efl_promise_value_set(promise, promise_value, (Eina_Free_Cb)&eina_value_free);
|
|
||||||
return future;
|
on_error:
|
||||||
|
return eina_future_rejected(efl_loop_future_scheduler_get(obj), err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Efl_Future*
|
static Eina_Value *
|
||||||
_eldbus_model_arguments_efl_model_property_get(Eo *obj EINA_UNUSED,
|
_eldbus_model_arguments_efl_model_property_get(const Eo *obj, Eldbus_Model_Arguments_Data *pd, const char *property)
|
||||||
Eldbus_Model_Arguments_Data *pd,
|
|
||||||
const char *property)
|
|
||||||
{
|
{
|
||||||
Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS, obj);
|
Eina_Value *value;
|
||||||
Efl_Future *future = efl_promise_future_get(promise);
|
Eina_Bool ret;
|
||||||
Eina_Value *promise_value;
|
|
||||||
|
|
||||||
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE, future);
|
|
||||||
DBG("(%p): property=%s", obj, property);
|
DBG("(%p): property=%s", obj, property);
|
||||||
|
if (!property) return eina_value_error_new(EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||||
|
|
||||||
_eldbus_model_arguments_properties_load(pd);
|
_eldbus_model_arguments_properties_load(pd);
|
||||||
|
|
||||||
Eina_Value* value = eina_hash_find(pd->properties_hash, property);
|
value = eina_hash_find(pd->properties_hash, property);
|
||||||
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_NOT_FOUND, future);
|
if (!value) return eina_value_error_new(EFL_MODEL_ERROR_NOT_FOUND);
|
||||||
|
|
||||||
Eina_Bool ret = _eldbus_model_arguments_is_output_argument(pd, property);
|
ret = _eldbus_model_arguments_is_output_argument(pd, property);
|
||||||
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_PERMISSION_DENIED, future);
|
if (!ret) return eina_value_error_new(EFL_MODEL_ERROR_PERMISSION_DENIED);
|
||||||
|
|
||||||
promise_value = eina_value_new(eina_value_type_get(value));
|
return eina_value_dup(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import eldbus_types;
|
import eldbus_types;
|
||||||
|
|
||||||
class Eldbus.Model.Arguments (Efl.Object, Efl.Model) {
|
class Eldbus.Model.Arguments (Eldbus.Model) {
|
||||||
[[Eldbus model arguments class]]
|
[[Eldbus model arguments class]]
|
||||||
|
|
||||||
methods {
|
methods {
|
||||||
|
@ -24,14 +24,10 @@ class Eldbus.Model.Arguments (Efl.Object, Efl.Model) {
|
||||||
}
|
}
|
||||||
implements {
|
implements {
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
|
Efl.Object.finalize;
|
||||||
Efl.Object.destructor;
|
Efl.Object.destructor;
|
||||||
Efl.Model.properties { get; }
|
Efl.Model.properties { get; }
|
||||||
Efl.Model.property_set;
|
Efl.Model.property { set; get; }
|
||||||
Efl.Model.property_get;
|
|
||||||
Efl.Model.child_add;
|
|
||||||
Efl.Model.child_del;
|
|
||||||
Efl.Model.children_slice_get;
|
|
||||||
Efl.Model.children_count_get;
|
|
||||||
}
|
}
|
||||||
constructors {
|
constructors {
|
||||||
.custom_constructor;
|
.custom_constructor;
|
||||||
|
|
|
@ -9,13 +9,7 @@
|
||||||
#define MY_CLASS ELDBUS_MODEL_CONNECTION_CLASS
|
#define MY_CLASS ELDBUS_MODEL_CONNECTION_CLASS
|
||||||
#define MY_CLASS_NAME "Eldbus_Model_Connection"
|
#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_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*
|
static Efl_Object*
|
||||||
_eldbus_model_connection_efl_object_constructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
|
_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));
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
||||||
|
|
||||||
pd->obj = obj;
|
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;
|
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
|
static void
|
||||||
_eldbus_model_connection_efl_object_destructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
|
_eldbus_model_connection_efl_object_destructor(Eo *obj, Eldbus_Model_Connection_Data *pd)
|
||||||
{
|
{
|
||||||
eina_stringshare_del(pd->address);
|
Eldbus_Children_Slice_Promise *slice;
|
||||||
|
|
||||||
_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;
|
|
||||||
Eo *child;
|
Eo *child;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN(pd);
|
if (pd->pending) eldbus_pending_cancel(pd->pending);
|
||||||
|
|
||||||
if (!pd->connection)
|
EINA_LIST_FREE(pd->childrens, child)
|
||||||
return;
|
|
||||||
|
|
||||||
free(pd->unique_name);
|
|
||||||
pd->unique_name = NULL;
|
|
||||||
|
|
||||||
EINA_LIST_FREE(pd->children_list, child)
|
|
||||||
efl_del(child);
|
efl_del(child);
|
||||||
|
|
||||||
EINA_LIST_FREE(pd->pending_list, pending)
|
EINA_LIST_FREE(pd->requests, slice)
|
||||||
eldbus_pending_cancel(pending);
|
|
||||||
|
|
||||||
if (pd->properties_array)
|
|
||||||
{
|
{
|
||||||
eina_array_free(pd->properties_array);
|
eina_promise_reject(slice->p, EFL_MODEL_ERROR_UNKNOWN);
|
||||||
pd->properties_array = NULL;
|
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
|
static void
|
||||||
_eldbus_model_connection_names_list_cb(void *data,
|
_eldbus_model_connection_names_list_cb(void *data,
|
||||||
const Eldbus_Message *msg,
|
const Eldbus_Message *msg,
|
||||||
Eldbus_Pending *pending)
|
Eldbus_Pending *pending EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*)data;
|
Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*) data;
|
||||||
_Eldbus_Children_Slice_Promise * p;
|
Eldbus_Model_Data *sd;
|
||||||
|
Eldbus_Children_Slice_Promise *slice;
|
||||||
const char *error_name, *error_text;
|
const char *error_name, *error_text;
|
||||||
Eldbus_Message_Iter *array = NULL;
|
Eldbus_Message_Iter *array = NULL;
|
||||||
const char *bus;
|
const char *bus;
|
||||||
unsigned int count;
|
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))
|
if (eldbus_message_error_get(msg, &error_name, &error_text))
|
||||||
{
|
{
|
||||||
ERR("%s: %s", error_name, error_text);
|
ERR("%s: %s", error_name, error_text);
|
||||||
//efl_model_error_notify(pd->obj);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,39 +121,37 @@ _eldbus_model_connection_names_list_cb(void *data,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sd = efl_data_scope_get(pd->obj, ELDBUS_MODEL_CLASS);
|
||||||
|
|
||||||
while (eldbus_message_iter_get_and_next(array, 's', &bus))
|
while (eldbus_message_iter_get_and_next(array, 's', &bus))
|
||||||
{
|
{
|
||||||
|
Eo *child;
|
||||||
|
|
||||||
DBG("(%p): bus = %s", pd->obj, bus);
|
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;
|
pd->is_listed = EINA_TRUE;
|
||||||
|
|
||||||
EINA_LIST_FOREACH(pd->children_promises, i, p)
|
count = eina_list_count(pd->childrens);
|
||||||
{
|
efl_event_callback_call(pd->obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &count);
|
||||||
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);
|
|
||||||
|
|
||||||
Efl_Promise *ep;
|
EINA_LIST_FREE(pd->requests, slice)
|
||||||
EINA_LIST_FOREACH(pd->count_promises, i, ep)
|
|
||||||
{
|
{
|
||||||
unsigned *c = calloc(sizeof(unsigned), 1);
|
Eina_Value v;
|
||||||
*c = eina_list_count(pd->children_list);
|
|
||||||
efl_promise_value_set(ep, c, free);
|
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"
|
#include "eldbus_model_connection.eo.c"
|
||||||
|
|
|
@ -1,53 +1,12 @@
|
||||||
import eldbus_types;
|
import eldbus_types;
|
||||||
|
|
||||||
class Eldbus.Model.Connection (Efl.Object, Efl.Model) {
|
class Eldbus.Model.Connection (Eldbus.Model) {
|
||||||
[[Eldbus model connection class]]
|
[[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 {
|
implements {
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
Efl.Object.destructor;
|
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_slice_get;
|
||||||
Efl.Model.children_count_get;
|
Efl.Model.children_count { get; }
|
||||||
}
|
|
||||||
constructors {
|
|
||||||
.custom_constructor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,20 @@ typedef struct _Eldbus_Model_Connection_Data Eldbus_Model_Connection_Data;
|
||||||
struct _Eldbus_Model_Connection_Data
|
struct _Eldbus_Model_Connection_Data
|
||||||
{
|
{
|
||||||
Eo *obj;
|
Eo *obj;
|
||||||
Eina_Bool is_listed : 1;
|
|
||||||
Eldbus_Connection *connection;
|
Eldbus_Connection *connection;
|
||||||
Eina_Array *properties_array;
|
Eldbus_Pending *pending;
|
||||||
Eina_List *children_list;
|
|
||||||
Eina_List *children_promises;
|
|
||||||
Eina_List *count_promises;
|
|
||||||
Eldbus_Connection_Type type;
|
Eldbus_Connection_Type type;
|
||||||
|
|
||||||
|
Eina_List *childrens;
|
||||||
|
Eina_List *requests;
|
||||||
|
|
||||||
Eina_Stringshare *address;
|
Eina_Stringshare *address;
|
||||||
bool private;
|
|
||||||
char *unique_name;
|
char *unique_name;
|
||||||
Eina_List *pending_list;
|
|
||||||
|
bool private;
|
||||||
|
|
||||||
|
Eina_Bool is_listed : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -26,17 +26,33 @@ _eldbus_model_method_efl_object_constructor(Eo *obj, Eldbus_Model_Method_Data *p
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Efl_Object*
|
||||||
_eldbus_model_method_method_constructor(Eo *obj EINA_UNUSED,
|
_eldbus_model_method_efl_object_finalize(Eo *obj, Eldbus_Model_Method_Data *pd)
|
||||||
Eldbus_Model_Method_Data *pd,
|
|
||||||
Eldbus_Proxy *proxy,
|
|
||||||
const Eldbus_Introspection_Method *method)
|
|
||||||
{
|
{
|
||||||
EINA_SAFETY_ON_NULL_RETURN(proxy);
|
if (!pd->proxy ||
|
||||||
EINA_SAFETY_ON_NULL_RETURN(method);
|
!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;
|
pd->method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,20 @@ import eldbus_types;
|
||||||
class Eldbus.Model.Method (Eldbus.Model.Arguments) {
|
class Eldbus.Model.Method (Eldbus.Model.Arguments) {
|
||||||
[[Eldbus model method class]]
|
[[Eldbus model method class]]
|
||||||
methods {
|
methods {
|
||||||
method_constructor {
|
@property proxy {
|
||||||
[[Custom Eldbus_Model_Method constructor.
|
[[Custom Eldbus_Model_Method constructor.
|
||||||
|
|
||||||
@since 1.16]]
|
@since 1.21]]
|
||||||
params {
|
set {}
|
||||||
@in proxy: ptr(Eldbus.Proxy); [[Eldbus proxy]]
|
values {
|
||||||
@cref method: Eldbus.Introspection.Method; [[The introspected method]]
|
proxy: ptr(Eldbus.Proxy); [[Eldbus proxy]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@property method {
|
||||||
|
[[Object]]
|
||||||
|
set {}
|
||||||
|
values {
|
||||||
|
@cref method: Eldbus.Introspection.Method; [[The introspected interface]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
call {
|
call {
|
||||||
|
@ -24,9 +31,11 @@ class Eldbus.Model.Method (Eldbus.Model.Arguments) {
|
||||||
}
|
}
|
||||||
implements {
|
implements {
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
|
Efl.Object.finalize;
|
||||||
}
|
}
|
||||||
constructors {
|
constructors {
|
||||||
.method_constructor;
|
.proxy;
|
||||||
|
.method;
|
||||||
}
|
}
|
||||||
events {
|
events {
|
||||||
successful,call; [[Event dispatched for a successful method call.]]
|
successful,call; [[Event dispatched for a successful method call.]]
|
||||||
|
|
|
@ -11,8 +11,10 @@ typedef struct _Eldbus_Model_Method_Data Eldbus_Model_Method_Data;
|
||||||
struct _Eldbus_Model_Method_Data
|
struct _Eldbus_Model_Method_Data
|
||||||
{
|
{
|
||||||
Eo *obj;
|
Eo *obj;
|
||||||
|
|
||||||
const Eldbus_Introspection_Method *method;
|
const Eldbus_Introspection_Method *method;
|
||||||
|
|
||||||
|
Eldbus_Proxy *proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,7 @@
|
||||||
#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS
|
#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS
|
||||||
#define MY_CLASS_NAME "Eldbus_Model_Object"
|
#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_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 void _eldbus_model_object_create_children(Eldbus_Model_Object_Data *, Eldbus_Object *, Eina_List *);
|
||||||
|
|
||||||
static Efl_Object*
|
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));
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
||||||
|
|
||||||
pd->obj = obj;
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_eldbus_model_object_custom_constructor(Eo *obj EINA_UNUSED,
|
_eldbus_model_object_bus_set(Eo *obj EINA_UNUSED,
|
||||||
Eldbus_Model_Object_Data *pd,
|
Eldbus_Model_Object_Data *pd,
|
||||||
Eldbus_Connection_Type type,
|
const char *bus)
|
||||||
const char* address,
|
|
||||||
Eina_Bool private,
|
|
||||||
const char* bus,
|
|
||||||
const char* path)
|
|
||||||
{
|
{
|
||||||
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->bus = eina_stringshare_add(bus);
|
||||||
pd->path = eina_stringshare_add(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_eldbus_model_object_connection_constructor(Eo *obj EINA_UNUSED,
|
_eldbus_model_object_path_set(Eo *obj EINA_UNUSED,
|
||||||
Eldbus_Model_Object_Data *pd,
|
Eldbus_Model_Object_Data *pd,
|
||||||
Eldbus_Connection *connection,
|
const char *path)
|
||||||
const char* bus,
|
|
||||||
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);
|
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
|
static void
|
||||||
_eldbus_model_object_efl_object_destructor(Eo *obj, Eldbus_Model_Object_Data *pd)
|
_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->bus);
|
||||||
eina_stringshare_del(pd->path);
|
eina_stringshare_del(pd->path);
|
||||||
|
|
||||||
_eldbus_model_object_clear(pd);
|
|
||||||
|
|
||||||
efl_destructor(efl_super(obj, MY_CLASS));
|
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
|
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
|
static Eina_Future *
|
||||||
_eldbus_model_object_type_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
|
_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 *
|
static const char *
|
||||||
|
@ -255,105 +163,71 @@ _eldbus_model_object_path_get(const Eo *obj EINA_UNUSED, Eldbus_Model_Object_Dat
|
||||||
return pd->path;
|
return pd->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static char *
|
||||||
_eldbus_model_object_connect(Eldbus_Model_Object_Data *pd)
|
_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)
|
buffer = eina_strbuf_new();
|
||||||
{
|
eina_strbuf_append_printf(buffer, format, root_path, relative_path);
|
||||||
if (pd->private)
|
absolute_path = eina_strbuf_string_steal(buffer);
|
||||||
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_strbuf_free(buffer);
|
||||||
|
return absolute_path;
|
||||||
EINA_SAFETY_ON_FALSE_RETURN(NULL != pd->connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_Introspection_Node *node;
|
||||||
eldbus_connection_unref(pd->connection);
|
Eina_List *it;
|
||||||
pd->connection = NULL;
|
|
||||||
|
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
|
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_Introspection_Interface *interface;
|
||||||
Eldbus_Object *object;
|
const char *current_path;
|
||||||
Eo *child;
|
Eina_List *l;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN(pd);
|
current_path = eldbus_object_path_get(object);
|
||||||
if (!pd->connection)
|
if (!current_path) return ;
|
||||||
return;
|
|
||||||
|
|
||||||
free(pd->unique_name);
|
EINA_LIST_FOREACH(interfaces, l, interface)
|
||||||
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_array_free(pd->properties_array);
|
Eo *child;
|
||||||
pd->properties_array = NULL;
|
|
||||||
|
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
|
static void
|
||||||
|
@ -362,12 +236,15 @@ _eldbus_model_object_introspect_cb(void *data,
|
||||||
Eldbus_Pending *pending)
|
Eldbus_Pending *pending)
|
||||||
{
|
{
|
||||||
Eldbus_Model_Object_Data *pd = (Eldbus_Model_Object_Data*)data;
|
Eldbus_Model_Object_Data *pd = (Eldbus_Model_Object_Data*)data;
|
||||||
|
Eldbus_Children_Slice_Promise* slice;
|
||||||
Eldbus_Object *object;
|
Eldbus_Object *object;
|
||||||
const char *error_name, *error_text;
|
const char *error_name;
|
||||||
|
const char *error_text;
|
||||||
const char *xml = NULL;
|
const char *xml = NULL;
|
||||||
const char *current_path;
|
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");
|
object = eldbus_pending_data_get(pending, "object");
|
||||||
|
|
||||||
if (eldbus_message_error_get(msg, &error_name, &error_text))
|
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.");
|
ERR("Error getting arguments.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EINA_SAFETY_ON_NULL_RETURN(xml);
|
|
||||||
|
if (!xml)
|
||||||
|
{
|
||||||
|
ERR("No XML.");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
current_path = eldbus_object_path_get(object);
|
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);
|
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_introspect_nodes(pd, current_path, pd->introspection->nodes);
|
||||||
_eldbus_model_object_create_children(pd, object, pd->introspection->interfaces);
|
_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;
|
v = efl_model_list_value_get(pd->childrens, slice->start, slice->count);
|
||||||
_Eldbus_Children_Slice_Promise* p;
|
eina_promise_resolve(slice->p, v);
|
||||||
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);
|
|
||||||
|
|
||||||
Efl_Promise *ep;
|
free(slice);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,63 +1,22 @@
|
||||||
import eldbus_types;
|
import eldbus_types;
|
||||||
|
|
||||||
class Eldbus.Model.Object (Efl.Object, Efl.Model) {
|
class Eldbus.Model.Object (Eldbus.Model) {
|
||||||
[[Eldbus model object class]]
|
[[Eldbus model object class]]
|
||||||
|
|
||||||
data: Eldbus_Model_Object_Data;
|
data: Eldbus_Model_Object_Data;
|
||||||
methods {
|
methods {
|
||||||
custom_constructor {
|
@property bus {
|
||||||
[[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 {
|
|
||||||
[[DBus Name or unique-id]]
|
[[DBus Name or unique-id]]
|
||||||
get { }
|
get { }
|
||||||
|
set { }
|
||||||
values {
|
values {
|
||||||
bus: string; [[DBus name]]
|
bus: string; [[DBus name]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property path {
|
@property path {
|
||||||
[[DBus path]]
|
[[DBus path]]
|
||||||
get { }
|
get { }
|
||||||
|
set { }
|
||||||
values {
|
values {
|
||||||
path: string; [[DBus path]]
|
path: string; [[DBus path]]
|
||||||
}
|
}
|
||||||
|
@ -65,17 +24,10 @@ class Eldbus.Model.Object (Efl.Object, Efl.Model) {
|
||||||
}
|
}
|
||||||
implements {
|
implements {
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
|
Efl.Object.finalize;
|
||||||
|
Efl.Object.invalidate;
|
||||||
Efl.Object.destructor;
|
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_slice_get;
|
||||||
Efl.Model.children_count_get;
|
Efl.Model.children_count { get; }
|
||||||
}
|
|
||||||
constructors {
|
|
||||||
.custom_constructor;
|
|
||||||
.connection_constructor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,22 +12,18 @@ typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
|
||||||
struct _Eldbus_Model_Object_Data
|
struct _Eldbus_Model_Object_Data
|
||||||
{
|
{
|
||||||
Eo *obj;
|
Eo *obj;
|
||||||
Eina_Bool is_listed : 1;
|
|
||||||
Eldbus_Connection *connection;
|
Eina_List *objects;
|
||||||
Eina_List *object_list;
|
Eina_List *childrens;
|
||||||
Eina_Array *properties_array;
|
Eina_List *requests;
|
||||||
Eina_List *children_list;
|
Eina_List *pendings;
|
||||||
Eina_List *children_promises;
|
|
||||||
Eina_List *count_promises;
|
|
||||||
Eldbus_Connection_Type type;
|
|
||||||
Eina_Stringshare *address;
|
|
||||||
bool private;
|
|
||||||
Eina_Stringshare *bus;
|
Eina_Stringshare *bus;
|
||||||
Eina_Stringshare *path;
|
Eina_Stringshare *path;
|
||||||
char *unique_name;
|
|
||||||
Eina_List *pending_list;
|
|
||||||
Eldbus_Introspection_Node *introspection;
|
Eldbus_Introspection_Node *introspection;
|
||||||
|
|
||||||
|
Eina_Bool is_listed : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,19 +8,28 @@
|
||||||
#include <Eo.h>
|
#include <Eo.h>
|
||||||
#include <Efl.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
|
struct _Eldbus_Children_Slice_Promise
|
||||||
{
|
{
|
||||||
unsigned start;
|
Eina_Promise *p;
|
||||||
unsigned count;
|
|
||||||
Efl_Promise* promise;
|
unsigned int start;
|
||||||
|
unsigned int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _Eldbus_Property_Promise _Eldbus_Property_Promise;
|
struct _Eldbus_Model_Data
|
||||||
struct _Eldbus_Property_Promise
|
|
||||||
{
|
{
|
||||||
char *property;
|
Eldbus_Connection *connection;
|
||||||
Efl_Promise* promise;
|
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"
|
#define UNIQUE_NAME_PROPERTY "unique_name"
|
||||||
|
@ -28,6 +37,12 @@ struct _Eldbus_Property_Promise
|
||||||
/* logging support */
|
/* logging support */
|
||||||
extern int eldbus_model_log_dom;
|
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) \
|
#define ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(exp, promise, err, v) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,24 @@
|
||||||
import eldbus_types;
|
import eldbus_types;
|
||||||
|
|
||||||
class Eldbus.Model.Proxy (Efl.Object, Efl.Model) {
|
class Eldbus.Model.Proxy (Eldbus.Model) {
|
||||||
[[Eldbus model proxy class]]
|
[[Eldbus model proxy class]]
|
||||||
|
|
||||||
methods {
|
methods {
|
||||||
custom_constructor {
|
@property object {
|
||||||
[[Custom Eldbus_Model_Proxy constructor.
|
[[Object]]
|
||||||
|
set {}
|
||||||
@since 1.16]]
|
values {
|
||||||
params {
|
object: ptr(Eldbus.Object); [[Eldbus object]]
|
||||||
@in object: ptr(Eldbus.Object); [[Eldbus object]]
|
}
|
||||||
|
}
|
||||||
|
@property interface {
|
||||||
|
[[Object]]
|
||||||
|
set {}
|
||||||
|
values {
|
||||||
@cref interface: Eldbus.Introspection.Interface; [[The introspected interface]]
|
@cref interface: Eldbus.Introspection.Interface; [[The introspected interface]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property proxy_name {
|
@property proxy_name {
|
||||||
[[Proxy name]]
|
[[Proxy name]]
|
||||||
get {}
|
get {}
|
||||||
values {
|
values {
|
||||||
|
@ -23,16 +28,15 @@ class Eldbus.Model.Proxy (Efl.Object, Efl.Model) {
|
||||||
}
|
}
|
||||||
implements {
|
implements {
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
|
Efl.Object.finalize;
|
||||||
|
Efl.Object.invalidate;
|
||||||
Efl.Object.destructor;
|
Efl.Object.destructor;
|
||||||
Efl.Model.properties { get; }
|
Efl.Model.properties { get; }
|
||||||
Efl.Model.property_set;
|
Efl.Model.property { set; get; }
|
||||||
Efl.Model.property_get;
|
|
||||||
Efl.Model.child_add;
|
|
||||||
Efl.Model.child_del;
|
|
||||||
Efl.Model.children_slice_get;
|
Efl.Model.children_slice_get;
|
||||||
Efl.Model.children_count_get;
|
Efl.Model.children_count { get; }
|
||||||
}
|
}
|
||||||
constructors {
|
constructors {
|
||||||
.custom_constructor;
|
.interface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,20 +13,21 @@ typedef struct _Eldbus_Model_Proxy_Data Eldbus_Model_Proxy_Data;
|
||||||
struct _Eldbus_Model_Proxy_Data
|
struct _Eldbus_Model_Proxy_Data
|
||||||
{
|
{
|
||||||
Eo *obj;
|
Eo *obj;
|
||||||
Eina_Bool is_listed : 1;
|
|
||||||
Eina_Bool is_loaded : 1;
|
const Eldbus_Introspection_Interface *interface;
|
||||||
|
|
||||||
Eldbus_Object *object;
|
Eldbus_Object *object;
|
||||||
Eldbus_Proxy *proxy;
|
Eldbus_Proxy *proxy;
|
||||||
Eina_Array *properties_array;
|
Eina_Hash *properties;
|
||||||
Eina_Hash *properties_hash;
|
Eina_List *childrens;
|
||||||
Eina_List *children_list;
|
Eina_List *pendings;
|
||||||
|
Eina_List *promises;
|
||||||
|
|
||||||
Eina_Stringshare *name;
|
Eina_Stringshare *name;
|
||||||
Eina_List *pending_list;
|
|
||||||
Eina_List *promise_list;
|
Eina_Bool monitoring : 1;
|
||||||
bool monitoring;
|
Eina_Bool is_listed : 1;
|
||||||
const Eldbus_Introspection_Interface *interface;
|
Eina_Bool is_loaded : 1;
|
||||||
Eina_Value tmp_value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue