Efl, Eio, Eldbus, Elementary: new model API use eina_promise

Efl - efl_model_base changed to use eina_promise
Eio - eio_model use efl_model_base with promise
Eldbus - elddbus models use promise now
Elementary - elm_view_list and elm_view_form use new models with promise

updated all related examples and tests
This commit is contained in:
Larry Jr 2016-04-20 17:07:53 -03:00 committed by Felipe Magno de Almeida
parent 42346e22f4
commit 0c76f82a31
41 changed files with 1533 additions and 2148 deletions

View File

@ -1,7 +1,9 @@
//Compile with:
// gcc -o busmodel busmodel.c `pkg-config --cflags --libs eldbus ecore eina`
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Eldbus.h>
#include <Eldbus_Model.h>
@ -11,77 +13,113 @@
#define DEFAULT_BUS "org.freedesktop.DBus"
#define DEFAULT_PATH "/"
static unsigned int children_count = 0;
static int prop_count = 0;
static Eina_Bool
_event_interface_load_status_cb(void *data EINA_UNUSED, const Eo_Event *event)
struct eina_iterator
{
Efl_Model_Load *actual_load = (Efl_Model_Load*)event->info;
Eina_Array *properties_list;
Eina_Array_Iterator iterator;
Eina_Value const* property_value;
Eina_Iterator* success_iterator;
Eina_Iterator* failure_iterator;
};
static void
promise_then_prop_c(Eo* obj, struct eina_iterator* it_struct)
{
Eina_Value * property_value;
const Eina_Array *properties_list;
Eina_Array_Iterator a_it;
char *property, *prop_str;
const char *name;
unsigned int i;
Eina_Iterator* it = it_struct->success_iterator;
if (EFL_MODEL_LOAD_STATUS_LOADED != actual_load->status)
return EINA_TRUE;
name = eldbus_model_proxy_name_get(obj);
properties_list = efl_model_properties_get(obj);
name = eldbus_model_proxy_name_get(event->obj);
efl_model_properties_get(event->obj, &properties_list);
printf(" -> %s\n", name);
if (eina_array_count(properties_list))
printf(" Properties:\n");
EINA_ARRAY_ITER_NEXT(properties_list, i, property, iterator)
printf(" -> %s\n Properties:\n", name);
unsigned i = 0;
EINA_ARRAY_ITER_NEXT(properties_list, i, property, a_it)
{
efl_model_property_get(event->obj, property, &property_value);
if (property_value)
if (eina_iterator_next(it, (void **)&property_value) && property_value)
{
prop_str = eina_value_to_string(property_value);
printf(" * %s=%s \n", property, prop_str);
free(prop_str);
}
printf(" * %s: %s \n", property, prop_str);
free(prop_str);
prop_str = NULL;
}
children_count--;
if (!children_count)
prop_count--;
if (prop_count == 0)
ecore_main_loop_quit();
return EINA_FALSE;
}
static Eina_Bool
_event_load_status_cb(void *data EINA_UNUSED, const Eo_Event *event)
static void
error_cb(void* data EINA_UNUSED, const Eina_Error *error EINA_UNUSED)
{
Efl_Model_Load *actual_load = (Efl_Model_Load*)event->info;
Eina_Accessor *accessor;
Eo *child = NULL;
unsigned int i;
printf(" ERROR\n");
ecore_main_loop_quit();
}
if (EFL_MODEL_LOAD_STATUS_LOADED != actual_load->status)
return EINA_TRUE;
static void
promise_then_a(Eo* obj EINA_UNUSED, Eina_Accessor **accessor)
{
const Eina_Array *properties_list;
Eina_Array_Iterator a_it;
Eina_Promise **promises;
const char *name;
char *property;
Eo* child;
int i = 0;
efl_model_children_count_get(event->obj, &children_count);
if (children_count == 0)
EINA_ACCESSOR_FOREACH(*accessor, i, child)
{
printf("Don't find Interfaces\n");
properties_list = efl_model_properties_get(child);
name = eldbus_model_proxy_name_get(child);
unsigned p_count = eina_array_count(properties_list);
if (p_count)
{
promises = (Eina_Promise **)calloc(p_count + 1, sizeof(Eina_Promise *));
promises[p_count] = NULL;
unsigned j = 0;
EINA_ARRAY_ITER_NEXT(properties_list, j, property, a_it)
{
efl_model_property_get(child, property, &promises[j]);
}
eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
(Eina_Promise_Cb)&promise_then_prop_c, &error_cb, child);
prop_count++;
}
else
{
printf(" -> %s\n", name);
}
}
if (prop_count == 0)
ecore_main_loop_quit();
}
static void
promise_then(Eo* obj EINA_UNUSED, struct eina_iterator* it_struct)
{
Eina_Accessor **accessor;
unsigned int* count;
Eina_Iterator* iterator = it_struct->success_iterator;
if (!eina_iterator_next(iterator, (void **)&accessor))
{
printf("bye\n");
ecore_main_loop_quit();
return EINA_FALSE;
return;
}
efl_model_children_slice_get(event->obj, 0, 0, &accessor);
printf("\nInterfaces:\n");
EINA_ACCESSOR_FOREACH(accessor, i, child)
{
eo_event_callback_add(child, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_interface_load_status_cb, NULL);
efl_model_load(child);
}
eina_iterator_next(iterator, (void **)&count);
return EINA_FALSE;
printf("efl_model_loaded count %d\n", (int)*count); fflush(stdout);
printf("efl_model_loaded accessor %p\n", accessor); fflush(stdout);
promise_then_a(NULL, accessor);
}
int
@ -90,6 +128,7 @@ main(int argc, char **argv EINA_UNUSED)
const char *bus, *path;
Eo *root;
ecore_init();
eldbus_init();
bus = DEFAULT_BUS;
@ -100,12 +139,15 @@ main(int argc, char **argv EINA_UNUSED)
root = eo_add_ref(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(eo_self, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, bus, path));
eo_event_callback_add(root, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_load_status_cb, NULL);
efl_model_load(root);
Eina_Promise *promises[] = { NULL, NULL, NULL};
efl_model_children_slice_get(root, 0, 0, &promises[0]);
efl_model_children_count_get(root, &promises[1]);
eina_promise_then(eina_promise_all(eina_carray_iterator_new((void **)promises)),
(Eina_Promise_Cb)&promise_then, &error_cb, root);
ecore_main_loop_begin();
eo_event_callback_del(root, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_load_status_cb, NULL);
eo_unref(root);
eldbus_shutdown();
}

View File

@ -51,29 +51,41 @@ _list_selected_cb(void *data EINA_UNUSED, const Eo_Event *event)
{
Efl_Model_Test_Filemvc_Data *priv = data;
Eo *child = event->info;
ethumb_client_file_free(elm_thumb_ethumb_client_get());
// ethumb_client_file_free(elm_thumb_ethumb_client_get());
printf("LIST selected model\n");
elm_view_form_model_set(priv->formview, child);
return EINA_TRUE;
}
static void
_promise_then(void *data, void *value)
{
Efl_Model_Test_Filemvc_Data *priv = data;
char *path;
Eo *model;
eina_value_get((Eina_Value *)value, &path);
model = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, path));
elm_view_list_model_set(priv->fileview, model);
}
static void
_promise_error(void *data, const Eina_Error *err)
{
}
static Eina_Bool
_tree_selected_cb(void *data, const Eo_Event *event)
{
Efl_Model_Test_Filemvc_Data *priv = data;
Eo *child = event->info;
const Eina_Value *vpath;
Eo *model;
char *path;
Eina_Promise *promise;
printf("TREE selected model\n");
efl_model_property_get(child, "path", &vpath);
eina_value_get(vpath, &path);
model = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, path));
efl_model_load(model);
elm_view_list_model_set(priv->fileview, model);
efl_model_property_get(child, "path", &promise);
eina_promise_then(promise, &_promise_then, &_promise_error, priv);
return EINA_TRUE;
}
@ -130,16 +142,12 @@ elm_main(int argc, char **argv)
evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, panes);
ecore_init();
eio_init();
if(argv[1] != NULL) dirname = argv[1];
else dirname = EFL_MODEL_TEST_FILENAME_PATH;
//treemodel
priv.treemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname));
eio_model_children_filter_set(priv.treemodel, _filter_cb, NULL);
efl_model_load(priv.treemodel);
//treeview
genlist = elm_genlist_add(win);
@ -155,6 +163,7 @@ elm_main(int argc, char **argv)
_widget_init(vpanes);
elm_object_part_content_set(panes, "right", vpanes);
eo_event_callback_add(priv.treeview, ELM_VIEW_LIST_EVENT_MODEL_SELECTED, _tree_selected_cb, &priv);
//listview
genlist = elm_genlist_add(win);
priv.fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_NONE, "double_label"));

View File

@ -42,7 +42,6 @@ elm_main(int argc, char **argv)
memset(&priv, 0, sizeof(Efl_Model_Test_Fileview_Data));
ecore_init();
eio_init();
if(argv[1] != NULL) dirname = argv[1];
else dirname = EFL_MODEL_TEST_FILENAME_PATH;
@ -58,7 +57,6 @@ elm_main(int argc, char **argv)
priv.filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname));
priv.fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_TREE, "double_label"));
elm_view_list_model_set(priv.fileview, priv.filemodel);
efl_model_load(priv.filemodel);
evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, &priv);
elm_view_list_property_connect(priv.fileview, "filename", "elm.text");

View File

@ -1,6 +1,18 @@
#ifndef EFL_MODEL_COMMON_H__
# define EFL_MODEL_COMMON_H__
#include <Eina.h>
EAPI extern Eina_Error EFL_MODEL_ERROR_UNKNOWN;
EAPI extern Eina_Error EFL_MODEL_ERROR_NOT_SUPPORTED;
EAPI extern Eina_Error EFL_MODEL_ERROR_NOT_FOUND;
EAPI extern Eina_Error EFL_MODEL_ERROR_READ_ONLY;
EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED;
EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE;
EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED;
typedef struct _Eina_Promise Eina_Promise;
/**
* @struct _Efl_Model_Children_Event
* Every time a child id added the event
@ -29,16 +41,7 @@ typedef struct _Efl_Model_Children_Event Efl_Model_Children_Event;
#include "interfaces/efl_model_base.eo.h"
/**
* @brief Sets the new load status signaling an event if changed
*
* @param model The model to call the event @c EFL_MODEL_EVENT_LOAD_STATUS
* @param load The load status to be changed
* @param status The new status
*
* @since 1.17
*/
EAPI void efl_model_load_set(Efl_Model_Base *model, Efl_Model_Load *load, Efl_Model_Load_Status status) EINA_ARG_NONNULL(1, 2);
EAPI int efl_model_init(void);
/**
* @brief Slices a list
@ -54,14 +57,6 @@ EAPI void efl_model_load_set(Efl_Model_Base *model, Efl_Model_Load *load, Efl_Mo
*/
EAPI Eina_Accessor *efl_model_list_slice(Eina_List *list, unsigned start, unsigned count) EINA_ARG_NONNULL(1);
/**
* @brief Notifies an error with an @c EFL_MODEL_EVENT_LOAD_STATUS
*
* @param model The model to be notified
*
* @since 1.17
*/
EAPI void efl_model_error_notify(Efl_Model_Base *model) EINA_ARG_NONNULL(1);
/**
* @brief Notifies a property changed event with an @c EFL_MODEL_EVENT_PROPERTIES_CHANGED

View File

@ -48,5 +48,5 @@ EAPI const Eo_Event_Description _EFL_GFX_PATH_CHANGED =
EAPI void
__efl_internal_init(void)
{
/* nothing to do, the symbol only is required for link to work */
efl_model_init();
}

View File

@ -1,47 +1,13 @@
enum Efl.Model.Load_Status {
error = 0,
loading_properties = (1 << 0),
loading_children = (1 << 1),
loading = (1 << 0) | (1 << 1),
loaded_properties = (1 << 2),
loaded_children = (1 << 3),
loaded = (1 << 2) | (1 << 3),
unloading = (1 << 4),
unloaded = (1 << 5)
}
struct Efl.Model.Property_Event {
changed_properties: array<const(char) *> *; [[List of changed properties]]
invalidated_properties: array<const(char) *> *; [[Removed properties identified by name]]
}
struct Efl.Model.Load {
[[Structure to hold Efl_Model_Load_Status enum (and possible other data) to avoid ABI break.]]
status: Efl.Model.Load_Status;
}
interface Efl.Model.Base ()
{
legacy_prefix: null;
eo_prefix: efl_model;
methods {
@property load_status {
get {
[[Get a load emodel current status.
By convention this means get the current model status.
Possible values are defined Efl_Model_Load_Status enumerator.
See also \@ref Efl_Model_Load_Status, @.load
@since 1.14
]]
return: Efl.Model.Load_Status;
}
}
@property properties {
get {
[[Get properties from model.
@ -55,91 +21,58 @@ interface Efl.Model.Base ()
@since 1.14
]]
return: Efl.Model.Load_Status;
}
values {
properties: const(array<const(char)*>*); [[array of current properties]]
properties: const(array<const(char)*>)*; [[array of current properties]]
}
}
@property property {
set {
[[Set a property value of a given property name.
property_set {
[[Set a property value of a given property name.
The caller must ensure to call at least efl_model_prop_list
before being able to see/set properties. This function sets
a new property value into given property name. Once the
operation is completed the concrete implementation should
raise EFL_MODEL_EVENT_PROPERTIES_CHANGE event in order to
notify listeners of the new value of the property.
The caller must ensure to call at least efl_model_prop_list
before being able to see/set properties. This function sets
a new property value into given property name. Once the
operation is completed the concrete implementation should
raise EFL_MODEL_EVENT_PROPERTIES_CHANGE event in order to
notify listeners of the new value of the property.
If the model doesn't have the property then there are two
possibilities, either raise an error or create the new
property in model
If the model doesn't have the property then there are two
possibilities, either raise an error or create the new
property in model
See @.property.get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
See @.property_get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
@since 1.14
]]
return: Efl.Model.Load_Status;
}
get {
[[Retrieve the value of a given property name.
@since 1.14
]]
params {
@in property: const(char)*; [[Property name]]
@in value: const(generic_value)*; [[New value]]
@inout promise: promise<generic_value>*; [[Promise returning the recorded value or error]]
}
}
property_get {
[[Retrieve the value of a given property name.
property_get will only be available when load status is equal
to EFL_MODEL_LOAD_STATUS_LOADED.
At this point the caller is free to get values from properties.
The event EFL_MODEL_EVENT_PROPERTIES_CHANGE may be raised to
notify listeners of the property/value.
At this point the caller is free to get values from properties.
The event EFL_MODEL_EVENT_PROPERTIES_CHANGE may be raised to
notify listeners of the property/value.
See @.properties.get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
See @.properties.get, \@ref EFL_MODEL_EVENT_PROPERTIES_CHANGE
@since 1.14
]]
return: Efl.Model.Load_Status;
}
keys {
property: const(char)*; [[Property name]]
}
values {
value: const(generic_value)*; [[New value]]
}
}
@property children_slice {
get {
/* doc FIXME: example
Below are examples of both usage types: slices and full ranges.
@code
// Returns full list
eo_do(obj, efl_model_children_slice_get(0, 0, &children_accessor));
// Returns 5 items, counting from item #5
eo_do(obj, efl_model_children_slice_get(5, 5, &children_accessor));
@endcode
*/
@since 1.14
]]
params {
@in property: const(char)*; [[Property name]]
@inout value: promise<generic_value>*; [[Promise of the value that was got]]
}
}
children_slice_get {
[[Get children slice OR full range.
Before being able to get the children list the model status
must be on loaded status (EFL_MODEL_LOAD_STATUS_LOADED).
However there may be circunstancies where the model could be
in a different state, in such cases it is advisable to simply
return: its current state, which will be of course, different
than EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN.
When children accessor is returned as NULL one should then
test the current load status return:ed by @.children_slice.get
in order to check against an empty list or real error.
children_slice_get behaves in two different ways, it may
provide the slice if both $start AND $count are non-zero
OR full range otherwise.
The return:ed Eina_Accessor must be freed when it is no longer
needed and eo_unref() must be invoked for children if caller
wants a copy.
Since 'slice' is a range, for example if we have 20 childs a
slice could be the range from 3(start) to 4(count), see:
@ -155,24 +88,19 @@ interface Efl.Model.Base ()
Optionally the user can call children_count_get to know the
number of children so a valid range can be known in advance.
See @.children_count.get, @.load, @.load_status.get.
See @.children_count_get
@since 1.14
]]
return: Efl.Model.Load_Status;
}
keys {
start: uint; [[Range begin - start from here. If start and
params {
@in start: uint; [[Range begin - start from here. If start and
count are 0 slice is ignored.]]
count: uint; [[Range size. If count and start are 0 slice is
@in count: uint; [[Range size. If count and start are 0 slice is
ignored.]]
}
values {
children_accessor: accessor<list<Eo.Base*>*>*;
@inout promise: promise<accessor<list<Eo.Base*>*>*>*; [[Promise of the children]]
}
}
@property children_count {
get {
children_count_get {
[[Get children count.
When efl_model_load is completed efl_model_coildren_count_get
@ -181,80 +109,14 @@ interface Efl.Model.Base ()
range is known. Event EFL_MODEL_CHILDREN_COUNT_CHANGED is
emitted when count is finished.
See also @.children_slice.get, @.load, @.load_status.get.
See also @.children_slice_get.
@since 1.14
]]
return: Efl.Model.Load_Status;
}
values {
children_count: uint;
params {
@inout promise: promise<uint>*;
}
}
load {
[[Load emodel.
By convention this means loading data from an external source and
populating the models properties and children with it. For example
in the case of file system backed model, this means opening the
relevant files and reading the data from them(creating the
properties and children from it). the model emit
EFL_MODEL_EVENT_LOAD_STATUS after end with Efl_Model_Load_Status
This convention should be followed, but no guarantees of behaviour
by user defined types can be given.
Alternatively is possible to use properties_load to load only
properties and children_load to load only children. If
efl_model_load is called then calling properties_load
and/or children_load is not necessary.
See also \@ref Efl_Model_Load_Status, @.properties_load,
@.children_load, @.unload, @.load_status.get
@since 1.14
]]
}
unload {
[[Unload emodel.
By convention this means releasing data received/read from an
external source. For example of a database backed model this
might mean releasing the iterator for the currently loaded data
or deleting a temporary table. the model emit
EFL_MODEL_EVENT_LOAD_STATUS after end with model load status
This convention should be followed, but no guarantees of behaviour
by user defined types can be given.
See also \@ref Efl_Model_Load_Status, @.load, @.load_status.get
@since 1.14
]]
}
properties_load {
[[Properties emodel load.
By convention this means loading data from an external source and
populating the models properties only. This method is a subset
of @.load, meaning that it won't load children, it is a hint.
For loadind both properties and children use
efl_model_load instead.
@since 1.14
]]
}
children_load {
[[Children emodel load.
By convention this means loading data from an external source and
populating the models children only. This method is a subset of
@.load, meaning that it won't load properties. For loadind both
properties and children use efl_model_load instead.
@since 1.14
]]
}
child_add {
[[Add a new child.
@ -263,8 +125,6 @@ interface Efl.Model.Base ()
added the event \@ref EFL_MODEL_EVENT_CHILD_ADD is then raised
and the new child is kept along with other children.
See also @.load_status.get.
@since 1.14
]]
return: Eo.Base *;
@ -279,7 +139,6 @@ interface Efl.Model.Base ()
@since 1.14
]]
return: Efl.Model.Load_Status;
params {
@in child: Eo.Base*; [[Child to be removed]]
}
@ -287,8 +146,6 @@ interface Efl.Model.Base ()
}
events {
load,status: Efl.Model.Load_Status; [[Event dispatch when load status
changes]]
properties,changed: Efl.Model.Property_Event; [[Event dispatched when
properties list is
available.]]

View File

@ -3,81 +3,85 @@
#endif
#include "Efl.h"
#include "Efl_Model_Common.h"
EAPI void
efl_model_load_set(Efl_Model_Base *model, Efl_Model_Load *load, Efl_Model_Load_Status status)
EAPI Eina_Error EFL_MODEL_ERROR_UNKNOWN = 0;
EAPI Eina_Error EFL_MODEL_ERROR_NOT_SUPPORTED = 0;
EAPI Eina_Error EFL_MODEL_ERROR_NOT_FOUND = 0;
EAPI Eina_Error EFL_MODEL_ERROR_READ_ONLY = 0;
EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0;
EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0;
EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0;
static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error";
static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
static const char EFL_MODEL_ERROR_NOT_FOUND_STR[] = "Value not found";
static const char EFL_MODEL_ERROR_READ_ONLY_STR[] = "Value read only";
static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed";
static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied";
static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value";
EAPI int
efl_model_init()
{
Efl_Model_Load new_load = {.status = status};
EFL_MODEL_ERROR_INCORRECT_VALUE = eina_error_msg_static_register(
EFL_MODEL_ERROR_INCORRECT_VALUE_STR);
if ((load->status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)) &&
(new_load.status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)))
{
// Merge status
new_load.status = load->status | new_load.status;
EFL_MODEL_ERROR_UNKNOWN = eina_error_msg_static_register(
EFL_MODEL_ERROR_UNKNOWN_STR);
// Removes incompatible statuses (LOADING vs LOADED)
switch (status)
{
case EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES:
new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES;
break;
case EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES:
new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
break;
case EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN:
new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN;
break;
case EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN:
new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
break;
case EFL_MODEL_LOAD_STATUS_LOADED:
new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING;
break;
case EFL_MODEL_LOAD_STATUS_LOADING:
new_load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED;
break;
default: break;
}
}
EFL_MODEL_ERROR_NOT_SUPPORTED = eina_error_msg_static_register(
EFL_MODEL_ERROR_NOT_SUPPORTED_STR);
if (load->status != new_load.status)
{
load->status = new_load.status;
eo_event_callback_call(model, EFL_MODEL_BASE_EVENT_LOAD_STATUS, load);
}
EFL_MODEL_ERROR_NOT_FOUND = eina_error_msg_static_register(
EFL_MODEL_ERROR_NOT_FOUND_STR);
EFL_MODEL_ERROR_READ_ONLY = eina_error_msg_static_register(
EFL_MODEL_ERROR_READ_ONLY_STR);
EFL_MODEL_ERROR_INIT_FAILED = eina_error_msg_static_register(
EFL_MODEL_ERROR_INIT_FAILED_STR);
EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register(
EFL_MODEL_ERROR_PERMISSION_DENIED_STR);
return EINA_TRUE;
}
EAPI Eina_Accessor *
EAPI Eina_Accessor*
efl_model_list_slice(Eina_List *list, unsigned start, unsigned count)
{
fprintf(stderr, "efl_model_list_slice\n");
if ((start == 0) && (count == 0))
if (!list) return NULL;
if ((start == 0) && (count == 0)) /* this is full data */
{
fprintf(stderr, "efl_model_list_slice start == 0 count == 0\n");
/*
* children_accessor will be set to NULL by
* eina_list_accessor_new if the later fails.
*/
return eina_list_accessor_new(list);
}
Eina_List *nth_list = eina_list_nth_list(list, (start - 1));
if (!nth_list)
return NULL;
Eina_List *it, *result = NULL;
const void *data;
EINA_LIST_FOREACH(nth_list, it, data)
Eo *child;
Eina_List *l, *ln, *lr = NULL;
ln = eina_list_nth_list(list, (start-1));
if (!ln)
{
result = eina_list_append(result, data);
if (eina_list_count(result) == count)
return NULL;
}
EINA_LIST_FOREACH(ln, l, child)
{
eo_ref(child);
lr = eina_list_append(lr, child);
if (eina_list_count(lr) == count)
break;
}
return eina_list_accessor_new(result);
}
if (!lr) return NULL;
EAPI void
efl_model_error_notify(Efl_Model_Base *model)
{
Efl_Model_Load load = {.status = EFL_MODEL_LOAD_STATUS_ERROR};
eo_event_callback_call(model, EFL_MODEL_BASE_EVENT_LOAD_STATUS, &load);
// This may leak the children Eina_List.
return eina_list_accessor_new(lr);
}
EAPI void

View File

@ -17,42 +17,20 @@
#define MY_CLASS_NAME "Eio_Model"
static void _eio_prop_set_error_cb(void *, Eio_File *, int);
static void _eio_model_efl_model_base_properties_load(Eo *, Eio_Model_Data *);
static void _eio_model_efl_model_base_children_load(Eo *, Eio_Model_Data *);
static void _eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat);
static void _eio_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error);
static void
_load_set(Eio_Model_Data *priv, Efl_Model_Load_Status status)
_eio_stat_do(Eio_Model_Data *priv)
{
Efl_Model_Load load;
priv->stat_file = eio_file_direct_stat(priv->path, _eio_stat_done_cb, _eio_error_cb, priv);
}
load.status = status;
if ((priv->load.status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)) &&
(load.status & (EFL_MODEL_LOAD_STATUS_LOADED | EFL_MODEL_LOAD_STATUS_LOADING)))
{
load.status = priv->load.status | status;
switch (status)
{
case EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES:
load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES;
break;
case EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES:
load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
break;
case EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN:
load.status &= ~EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN;
break;
case EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN:
load.status &= ~EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
break;
default: break;
}
}
if (priv->load.status != load.status)
{
priv->load.status = load.status;
eo_event_callback_call(priv->obj, EFL_MODEL_BASE_EVENT_LOAD_STATUS, &load);
}
void
_accessor_free(void *data)
{
Eina_Accessor **ac = data;
eina_accessor_free(*ac);
}
/**
@ -62,25 +40,42 @@ _load_set(Eio_Model_Data *priv, Efl_Model_Load_Status status)
static void
_eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *stat)
{
Efl_Model_Property_Event evt;
Eio_Model_Data *priv = data;
EINA_SAFETY_ON_FALSE_RETURN(eo_ref_get(priv->obj));
_Eio_Model_Data *priv = data;
_Eio_Property_Promise* p;
Eina_List *l;
EINA_LIST_FOREACH(priv->property_promises, l, p)
{
Eina_Value* v = eina_promise_owner_buffer_get(p->promise);
switch(p->property)
{
case EIO_MODEL_PROP_IS_DIR:
eina_value_setup(v, EINA_VALUE_TYPE_CHAR);
eina_value_set(v, eio_file_is_dir(stat) ? EINA_TRUE : EINA_FALSE);
break;
case EIO_MODEL_PROP_IS_LNK:
eina_value_setup(v, EINA_VALUE_TYPE_CHAR);
eina_value_set(v, eio_file_is_lnk(stat) ? EINA_TRUE : EINA_FALSE);
break;
case EIO_MODEL_PROP_MTIME:
eina_value_setup(v, EINA_VALUE_TYPE_TIMEVAL);
eina_value_set(v, eio_file_mtime(stat));
break;
case EIO_MODEL_PROP_SIZE:
eina_value_setup(v, EINA_VALUE_TYPE_INT64);
eina_value_set(v, eio_file_size(stat));
break;
default:
break;
};
priv->is_dir = eio_file_is_dir(stat);
memset(&evt, 0, sizeof(Efl_Model_Property_Event));
eina_promise_owner_value_set(p->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
free(p);
}
eina_list_free(priv->property_promises);
priv->property_promises = NULL;
eina_value_set(priv->properties_value[EIO_MODEL_PROP_IS_DIR], eio_file_is_dir(stat));
eina_value_set(priv->properties_value[EIO_MODEL_PROP_IS_LNK], eio_file_is_lnk(stat));
eina_value_set(priv->properties_value[EIO_MODEL_PROP_MTIME], eio_file_mtime(stat));
eina_value_set(priv->properties_value[EIO_MODEL_PROP_SIZE], eio_file_size(stat));
evt.changed_properties = priv->properties_name;
eo_event_callback_call(priv->obj, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, &evt);
_load_set(priv, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
if (priv->load_pending & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
_eio_model_efl_model_base_children_load(priv->obj, priv);
eio_file_cancel(priv->stat_file);
priv->stat_file = NULL;
}
static void
@ -94,20 +89,11 @@ _eio_move_done_cb(void *data, Eio_File *handler EINA_UNUSED)
{
Efl_Model_Property_Event evt;
Eio_Model_Data *priv = data;
Eina_Array *properties;
Eina_Array *properties = eina_array_new(20);
EINA_SAFETY_ON_FALSE_RETURN(eo_ref_get(priv->obj));
memset(&evt, 0, sizeof(Efl_Model_Property_Event));
/**
* When mv is executed we update our values and
* notify both path and filename properties listeners.
*/
eina_value_set(priv->properties_value[EIO_MODEL_PROP_PATH], priv->path);
eina_value_set(priv->properties_value[EIO_MODEL_PROP_FILENAME], basename(priv->path));
properties = eina_array_new(2);
eina_array_push(properties, _eio_model_prop_names[EIO_MODEL_PROP_PATH]);
eina_array_push(properties, _eio_model_prop_names[EIO_MODEL_PROP_FILENAME]);
evt.changed_properties = properties;
@ -121,7 +107,15 @@ _eio_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error)
{
if (error != 0)
{
_Eio_Model_Data *priv = data;
_Eio_Property_Promise* p;
Eina_List *l;
WRN("%d: %s.", error, strerror(error));
EINA_LIST_FOREACH(priv->property_promises, l, p)
{
eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_UNKNOWN);
}
}
}
@ -245,60 +239,102 @@ _eio_error_unlink_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int
/**
* Interfaces impl.
*/
static Efl_Model_Load_Status
_eio_model_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
Eio_Model_Data *_pd, Eina_Array * const* properties)
static Eina_Array const *
_eio_model_efl_model_base_properties_get(Eo *obj EINA_UNUSED, Eio_Model_Data *_pd)
{
Eio_Model_Data *priv = _pd;
EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv->obj, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv->obj, NULL);
*(Eina_Array **)properties = priv->properties_name;
return priv->load.status;
return priv->properties_name;
}
/**
* Property Get
*/
static Efl_Model_Load_Status
_eio_model_efl_model_base_property_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char *property, const Eina_Value **value)
static void
_eio_model_efl_model_base_property_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char *property, Eina_Promise_Owner *promise)
{
unsigned int i;
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EFL_MODEL_LOAD_STATUS_ERROR);
_Eio_Property_Name property_name;
const char* value = NULL;
*value = NULL;
if (priv->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
EINA_SAFETY_ON_NULL_RETURN(priv);
if (property == NULL)
{
for (i = 0; i < EIO_MODEL_PROP_LAST; ++i)
{
if (!strcmp(property, _eio_model_prop_names[i]))
break;
}
if ( i < EIO_MODEL_PROP_LAST)
{
*value = priv->properties_value[i];
}
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
return;
}
return priv->load.status;
if(!strcmp("filename", property))
{
value = basename(priv->path);
property_name = EIO_MODEL_PROP_FILENAME;
}
else if(!strcmp("path", property))
{
value = priv->path;
property_name = EIO_MODEL_PROP_PATH;
}
else if(!strcmp("mtime", property))
property_name = EIO_MODEL_PROP_MTIME;
else if(!strcmp("is_dir", property))
property_name = EIO_MODEL_PROP_IS_DIR;
else if(!strcmp("is_lnk", property))
property_name = EIO_MODEL_PROP_IS_LNK;
else if(!strcmp("size", property))
property_name = EIO_MODEL_PROP_SIZE;
else
{
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
return;
}
switch(property_name)
{
case EIO_MODEL_PROP_FILENAME:
case EIO_MODEL_PROP_PATH:
{
Eina_Value* v = eina_promise_owner_buffer_get(promise);
eina_value_setup(v, EINA_VALUE_TYPE_STRING);
eina_value_set(v, value);
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
}
break;
default:
{
_Eio_Property_Promise* p = calloc(1, sizeof(_Eio_Property_Promise));
p->promise = promise;
p->property = property_name;;
priv->property_promises = eina_list_prepend(priv->property_promises, p);
if(!priv->stat_file)
_eio_stat_do(priv);
}
break;
}
}
/**
* Property Set
*/
static Efl_Model_Load_Status
_eio_model_efl_model_base_property_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char * property, const Eina_Value *value)
static void
_eio_model_efl_model_base_property_set(Eo *obj EINA_UNUSED,
Eio_Model_Data *priv,
const char * property,
const Eina_Value *value,
Eina_Promise_Owner *promise)
{
char *dest;
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN(property);
if (strcmp(property, "path") != 0)
return EINA_FALSE;
{
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
return;
}
dest = eina_value_to_string(value);
if (priv->path == NULL)
@ -307,56 +343,28 @@ _eio_model_efl_model_base_property_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv
INF("path '%s' with filename '%s'.", priv->path, basename(priv->path));
eina_value_set(priv->properties_value[EIO_MODEL_PROP_PATH], priv->path);
eina_value_set(priv->properties_value[EIO_MODEL_PROP_FILENAME], basename(priv->path));
_eio_monitors_list_load(priv);
_eio_move_done_cb(priv, NULL);
if (priv->load_pending & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
_eio_model_efl_model_base_properties_load(obj, priv);
else if (priv->load_pending & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
_eio_model_efl_model_base_children_load(obj, priv);
return priv->load.status;
}
else
{
priv->move_file = eio_file_move(priv->path, dest, _eio_progress_cb, _eio_move_done_cb, _eio_prop_set_error_cb, priv);
free(priv->path);
priv->path = dest;
}
priv->file = eio_file_move(priv->path, dest, _eio_progress_cb, _eio_move_done_cb, _eio_prop_set_error_cb, priv);
free(priv->path);
priv->path = dest;
return priv->load.status;
eina_promise_owner_value_set(promise, &value, NULL);
}
/**
* Children Count Get
*/
static Efl_Model_Load_Status
_eio_model_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, unsigned int *children_count)
{
/**< eina_list_count returns 'unsigned int' */
*children_count = eina_list_count(priv->children_list);
return priv->load.status;
}
/**
* Properties Load
*/
static void
_eio_model_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
_eio_model_efl_model_base_children_count_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eina_Promise_Owner *promise)
{
if (priv->path == NULL)
{
priv->load_pending |= EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
return;
}
priv->load_pending &= ~EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES;
if (!(priv->load.status & (EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES | EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES)))
{
_load_set(priv, EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES);
priv->file = eio_file_direct_stat(priv->path, _eio_stat_done_cb, _eio_error_cb, priv);
}
unsigned int c = eina_list_count(priv->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
}
static void
@ -419,14 +427,28 @@ _eio_main_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina
static void
_eio_done_children_load_cb(void *data, Eio_File *handler EINA_UNUSED)
{
unsigned long count;
Eio_Model_Data *priv = data;
EINA_SAFETY_ON_NULL_RETURN(priv);
count = eina_list_count(priv->children_list);
_load_set(priv, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
eio_file_cancel(priv->listing_file);
priv->listing_file = NULL;
priv->is_listed = EINA_TRUE;
priv->is_listing = EINA_FALSE;
eo_event_callback_call(priv->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count);
Eina_List* i;
_Eio_Children_Slice_Promise* p;
EINA_LIST_FOREACH(priv->children_promises, i, p)
{
Eina_Accessor* accessor = efl_model_list_slice(priv->children_list, p->start, p->count);
if (accessor)
eina_promise_owner_value_set(p->promise, &accessor, &_accessor_free);
else
eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_NOT_FOUND);
free(p);
}
eina_list_free(priv->children_promises);
priv->children_promises = NULL;
}
static void
@ -439,71 +461,6 @@ _eio_error_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, int error
EINA_LIST_FREE(priv->children_list, child)
eo_unref(child);
_load_set(priv, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
}
/**
* Children Load
*/
static void
_eio_model_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
{
if (priv->path == NULL)
{
priv->load_pending |= EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
return;
}
priv->load_pending &= ~EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
if (priv->children_list == NULL && priv->is_dir &&
!(priv->load.status & (EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN | EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN)))
{
_eio_model_efl_model_base_monitor_add(priv);
_load_set(priv, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
eio_file_direct_ls(priv->path, _eio_filter_children_load_cb,
_eio_main_children_load_cb, _eio_done_children_load_cb,
_eio_error_children_load_cb, priv);
}
}
/**
* Load
*/
static void
_eio_model_efl_model_base_load(Eo *obj, Eio_Model_Data *priv)
{
priv->load_pending |= EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN;
_eio_model_efl_model_base_properties_load(obj, priv);
}
/**
* Load status get
*/
static Efl_Model_Load_Status
_eio_model_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
{
return priv->load.status;
}
/**
* Unload
*/
static void
_eio_model_efl_model_base_unload(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
{
if (!(priv->load.status & EFL_MODEL_LOAD_STATUS_UNLOADED))
{
Eo *child;
EINA_LIST_FREE(priv->children_list, child)
{
eo_unref(child);
}
_load_set(priv, EFL_MODEL_LOAD_STATUS_UNLOADED);
}
}
static void
@ -546,80 +503,64 @@ _eio_model_efl_model_base_child_del_stat(void* data, Eio_File* handler EINA_UNUS
/**
* Child Remove
*/
static Efl_Model_Load_Status
static void
_eio_model_efl_model_base_child_del(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eo *child)
{
Eio_Model_Data *child_priv;
EINA_SAFETY_ON_NULL_RETURN_VAL(child, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN(child);
child_priv = eo_data_scope_get(child, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN_VAL(child_priv, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN(child_priv);
eio_file_direct_stat(child_priv->path,
&_eio_model_efl_model_base_child_del_stat,
&_eio_error_unlink_cb,
child);
priv->del_file = eio_file_direct_stat(child_priv->path,
&_eio_model_efl_model_base_child_del_stat,
&_eio_error_unlink_cb,
child);
eo_ref(child);
return priv->load.status;
}
/**
* Children Slice Get
*/
static Efl_Model_Load_Status
static void
_eio_model_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv,
unsigned start, unsigned count, Eina_Accessor **children_accessor)
unsigned start, unsigned count, Eina_Promise_Owner *promise)
{
Eo *child;
Eina_List *l, *ln, *lr = NULL;
/**
* children must be already loaded otherwise we do nothing
* and parameter is set to NULL.
*/
if (!(priv->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN))
if (!(priv->is_listed))
{
/**
* Status should be in either unloaded state or unitialized
* so we simply return without much alarm.
*/
*children_accessor = NULL;
return priv->load.status;
_Eio_Children_Slice_Promise* p = calloc(1, sizeof(struct _Eio_Children_Slice_Promise));
p->promise = promise;
p->start = start;
p->count = count;
priv->children_promises = eina_list_prepend(priv->children_promises, p);
_eio_model_efl_model_base_monitor_add(priv);
if (priv->is_listing == EINA_FALSE)
{
priv->is_listing = EINA_TRUE;
eio_file_direct_ls(priv->path, _eio_filter_children_load_cb,
_eio_main_children_load_cb, _eio_done_children_load_cb,
_eio_error_children_load_cb, priv);
}
return;
}
if ((start == 0) && (count == 0)) /* this is full data */
{
/*
* children_accessor will be set to NULL by
* eina_list_accessor_new if the later fails.
*/
*children_accessor = eina_list_accessor_new(priv->children_list);
}
else /* this is only slice */
{
ln = eina_list_nth_list(priv->children_list, (start-1));
if (!ln)
{
*children_accessor = NULL;
ERR("children not found !");
return priv->load.status;
}
EINA_LIST_FOREACH(ln, l, child)
{
eo_ref(child);
lr = eina_list_append(lr, child);
if (eina_list_count(lr) == count)
break;
}
// This may leak the children Eina_List.
*children_accessor = eina_list_accessor_new(lr);
}
return priv->load.status;
Eina_Accessor* accessor = efl_model_list_slice(priv->children_list, start, count);
if (accessor)
eina_promise_owner_value_set(promise, &accessor, &_accessor_free);
else
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_FOUND);
}
/**
* Class definitions
*/
@ -629,20 +570,13 @@ _eio_model_eo_base_constructor(Eo *obj, Eio_Model_Data *priv)
obj = eo_constructor(eo_super(obj, MY_CLASS));
unsigned int i;
priv->obj = obj;
priv->is_listed = priv->is_listing = EINA_FALSE;
priv->properties_name = eina_array_new(EIO_MODEL_PROP_LAST);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv->properties_name, NULL);
for (i = 0; i < EIO_MODEL_PROP_LAST; ++i)
eina_array_push(priv->properties_name, _eio_model_prop_names[i]);
priv->properties_value[EIO_MODEL_PROP_FILENAME] = eina_value_new(EINA_VALUE_TYPE_STRING);
priv->properties_value[EIO_MODEL_PROP_PATH] = eina_value_new(EINA_VALUE_TYPE_STRING);
priv->properties_value[EIO_MODEL_PROP_MTIME] = eina_value_new(EINA_VALUE_TYPE_TIMEVAL);
priv->properties_value[EIO_MODEL_PROP_IS_DIR] = eina_value_new(EINA_VALUE_TYPE_INT);
priv->properties_value[EIO_MODEL_PROP_IS_LNK] = eina_value_new(EINA_VALUE_TYPE_INT);
priv->properties_value[EIO_MODEL_PROP_SIZE] = eina_value_new(EINA_VALUE_TYPE_INT64);
priv->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
priv->monitor = NULL;
eina_spinlock_new(&priv->filter_lock);
@ -654,9 +588,6 @@ _eio_model_path_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, const char *path)
{
priv->path = strdup(path);
eina_value_set(priv->properties_value[EIO_MODEL_PROP_PATH], priv->path);
eina_value_set(priv->properties_value[EIO_MODEL_PROP_FILENAME], basename(priv->path));
priv->monitor = NULL;
_eio_monitors_list_load(priv);
}
@ -665,7 +596,7 @@ static void
_eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv)
{
Eo *child;
unsigned int i;
/* unsigned int i; */
if (priv->monitor)
eio_monitor_del(priv->monitor);
@ -675,11 +606,6 @@ _eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv)
if (priv->properties_name)
eina_array_free(priv->properties_name);
for (i = 0; i < EIO_MODEL_PROP_LAST; ++i)
{
eina_value_free(priv->properties_value[i]);
}
EINA_LIST_FREE(priv->children_list, child)
eo_unref(child);

View File

@ -15,7 +15,7 @@ class Eio.Model (Eo.Base, Efl.Model.Base)
by returning either EINA_FALSE, to abort the notification or
EINA_TRUE to keep it.
See also @Efl.Model.Base.children_slice.get.
See also @Efl.Model.Base.children_slice_get.
@since 1.11
]]
@ -38,16 +38,11 @@ class Eio.Model (Eo.Base, Efl.Model.Base)
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Model.Base.properties.get;
Efl.Model.Base.properties_load;
Efl.Model.Base.property.set;
Efl.Model.Base.property.get;
Efl.Model.Base.load;
Efl.Model.Base.load_status.get;
Efl.Model.Base.unload;
Efl.Model.Base.property_set;
Efl.Model.Base.property_get;
Efl.Model.Base.child_add;
Efl.Model.Base.child_del;
Efl.Model.Base.children_slice.get;
Efl.Model.Base.children_count.get;
Efl.Model.Base.children_load;
Efl.Model.Base.children_slice_get;
Efl.Model.Base.children_count_get;
}
}

View File

@ -14,7 +14,7 @@ struct _Eio_Model_Monitor_Data
int mon_event_child_del[3]; /**< plus EIO_MONITOR_ERROR */
};
enum {
typedef enum _Eio_Property_Name {
EIO_MODEL_PROP_FILENAME = 0,
EIO_MODEL_PROP_PATH,
EIO_MODEL_PROP_MTIME,
@ -22,7 +22,7 @@ enum {
EIO_MODEL_PROP_IS_LNK,
EIO_MODEL_PROP_SIZE,
EIO_MODEL_PROP_LAST
};
} _Eio_Property_Name;
static const char* _eio_model_prop_names[] =
{
@ -34,18 +34,37 @@ static const char* _eio_model_prop_names[] =
[EIO_MODEL_PROP_SIZE] = "size"
};
typedef struct _Eio_Property_Promise _Eio_Property_Promise;
struct _Eio_Property_Promise
{
_Eio_Property_Name property;
Eina_Promise_Owner* promise;
};
typedef struct _Eio_Children_Slice_Promise _Eio_Children_Slice_Promise;
struct _Eio_Children_Slice_Promise
{
unsigned start;
unsigned count;
Eina_Promise_Owner* promise;
};
typedef struct _Eio_Model_Data _Eio_Model_Data;
struct _Eio_Model_Data
{
Eo *obj;
char *path;
Eina_Array *properties_name;
Eina_Value *properties_value[EIO_MODEL_PROP_LAST];
Efl_Model_Load load;
int load_pending;
Eina_Bool is_listed : 1;
Eina_Bool is_listing : 1;
Eina_List *children_list;
Eina_List *property_promises;
Eina_List *children_promises;
/**< EIO data */
Eio_File *file;
Eina_Bool is_dir;
Eio_File *stat_file;
Eio_File *listing_file;
Eio_File *move_file;
Eio_File *del_file;
Eio_Monitor *monitor;
Eio_Model_Monitor_Data mon;
int cb_count_child_add; /**< monitor reference counter for child add event */

View File

@ -5,6 +5,7 @@
#include "eldbus_model_arguments_private.h"
#include "eldbus_model_private.h"
#include <Ecore.h>
#include <Eina.h>
#include <Eldbus.h>
@ -13,8 +14,7 @@
#define ARGUMENT_FORMAT "arg%u"
static void _eldbus_model_arguments_efl_model_base_properties_load(Eo *, Eldbus_Model_Arguments_Data *);
static void _eldbus_model_arguments_efl_model_base_children_load(Eo *, Eldbus_Model_Arguments_Data *);
static void _eldbus_model_arguments_properties_load(Eldbus_Model_Arguments_Data *);
static void _eldbus_model_arguments_unload(Eldbus_Model_Arguments_Data *);
static Eina_Bool _eldbus_model_arguments_is_input_argument(Eldbus_Model_Arguments_Data *, const char *);
static Eina_Bool _eldbus_model_arguments_is_output_argument(Eldbus_Model_Arguments_Data *, const char *);
@ -33,7 +33,6 @@ _eldbus_model_arguments_eo_base_constructor(Eo *obj, Eldbus_Model_Arguments_Data
obj = eo_constructor(eo_super(obj, MY_CLASS));
pd->obj = obj;
pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
pd->properties_array = NULL;
pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_arguments_hash_free));
pd->pending_list = NULL;
@ -71,31 +70,23 @@ _eldbus_model_arguments_eo_base_destructor(Eo *obj, Eldbus_Model_Arguments_Data
eo_destructor(eo_super(obj, MY_CLASS));
}
static Efl_Model_Load_Status
static Eina_Array const *
_eldbus_model_arguments_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
Eina_Array * const* properties_array)
Eldbus_Model_Arguments_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
{
ERR("%s", "o not loaded.");
return EFL_MODEL_LOAD_STATUS_ERROR;
}
*(Eina_Array**)properties_array = pd->properties_array;
return pd->load.status;
_eldbus_model_arguments_properties_load(pd);
return pd->properties_array;
}
static void
_eldbus_model_arguments_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd)
_eldbus_model_arguments_properties_load(Eldbus_Model_Arguments_Data *pd)
{
unsigned int arguments_count;
unsigned int i;
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
if (pd->properties_array)
return;
arguments_count = eina_list_count(pd->arguments);
@ -120,86 +111,55 @@ _eldbus_model_arguments_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldb
value = eina_value_new(type);
eina_hash_add(pd->properties_hash, name, value);
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
static Efl_Model_Load_Status
static void
_eldbus_model_arguments_efl_model_base_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
const char *property,
Eina_Value const* value)
Eina_Value const* value,
Eina_Promise_Owner *promise)
{
Eina_Value *prop_value;
Eina_Bool ret;
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
DBG("(%p): property=%s", obj, property);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
return EFL_MODEL_LOAD_STATUS_ERROR;
_eldbus_model_arguments_properties_load(pd);
if (!_eldbus_model_arguments_is_input_argument(pd, property))
{
WRN("Property (argument) not found or it is for output only: %s", property);
return EFL_MODEL_LOAD_STATUS_ERROR;
}
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);
prop_value = eina_hash_find(pd->properties_hash, property);
EINA_SAFETY_ON_NULL_RETURN_VAL(prop_value, EFL_MODEL_LOAD_STATUS_ERROR);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(prop_value, promise, EFL_MODEL_ERROR_NOT_FOUND);
eina_value_flush(prop_value);
ret = eina_value_copy(value, prop_value);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EFL_MODEL_LOAD_STATUS_ERROR);
return pd->load.status;
eina_value_copy(value, prop_value);
eina_promise_owner_value_set(promise, prop_value, NULL);
}
static Efl_Model_Load_Status
static void
_eldbus_model_arguments_efl_model_base_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
const char *property,
Eina_Value const ** value)
Eina_Promise_Owner *promise)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN(promise);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
DBG("(%p): property=%s", obj, property);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
return EFL_MODEL_LOAD_STATUS_ERROR;
_eldbus_model_arguments_properties_load(pd);
if (!_eldbus_model_arguments_is_output_argument(pd, property))
{
WRN("Property (argument) not found or it is for input only: %s", property);
return EFL_MODEL_LOAD_STATUS_ERROR;
}
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);
*value = eina_hash_find(pd->properties_hash, property);
EINA_SAFETY_ON_NULL_RETURN_VAL(*value, EFL_MODEL_LOAD_STATUS_ERROR);
Eina_Value* value = eina_hash_find(pd->properties_hash, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_NOT_FOUND);
return pd->load.status;
}
static void
_eldbus_model_arguments_efl_model_base_load(Eo *obj, Eldbus_Model_Arguments_Data *pd EINA_UNUSED)
{
efl_model_properties_load(obj);
efl_model_children_load(obj);
}
static Efl_Model_Load_Status
_eldbus_model_arguments_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd)
{
return pd->load.status;
}
static void
_eldbus_model_arguments_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd)
{
_eldbus_model_arguments_unload(pd);
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED);
eina_value_copy(value, eina_promise_owner_buffer_get(promise));
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
}
static Eo *
@ -208,41 +168,30 @@ _eldbus_model_arguments_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Mod
return NULL;
}
static Efl_Model_Load_Status
static void
_eldbus_model_arguments_efl_model_base_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
return EFL_MODEL_LOAD_STATUS_ERROR;
}
static Efl_Model_Load_Status
_eldbus_model_arguments_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
unsigned start EINA_UNUSED,
unsigned count EINA_UNUSED,
Eina_Accessor **children_accessor)
{
*children_accessor = NULL;
return pd->load.status;
}
static Efl_Model_Load_Status
_eldbus_model_arguments_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd,
unsigned *children_count)
{
*children_count = 0;
return pd->load.status;
}
static void
_eldbus_model_arguments_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Arguments_Data *pd)
_eldbus_model_arguments_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
unsigned start EINA_UNUSED,
unsigned count EINA_UNUSED,
Eina_Promise_Owner *promise)
{
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
return;
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
static void
_eldbus_model_arguments_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
Eina_Promise_Owner *promise)
{
unsigned count = 0;
eina_promise_owner_value_set(promise, &count, NULL);
}
static const char *
@ -289,11 +238,13 @@ eldbus_model_arguments_process_arguments(Eldbus_Model_Arguments_Data *pd,
unsigned int i = 0;
Eina_Bool result = EINA_FALSE;
_eldbus_model_arguments_properties_load(pd);
pd->pending_list = eina_list_remove(pd->pending_list, pending);
if (eldbus_message_error_get(msg, &error_name, &error_text))
{
ERR("%s: %s", error_name, error_text);
efl_model_error_notify(pd->obj);
//efl_model_error_notify(pd->obj);
return EINA_FALSE;
}
@ -350,6 +301,8 @@ _eldbus_model_arguments_property_set(Eldbus_Model_Arguments_Data *pd,
Eina_Value value;
Eina_Bool ret;
_eldbus_model_arguments_properties_load(pd);
prop_value = eina_hash_find(pd->properties_hash, property);
EINA_SAFETY_ON_NULL_RETURN_VAL(prop_value, EINA_FALSE);
@ -372,6 +325,8 @@ _eldbus_model_arguments_is(Eldbus_Model_Arguments_Data *pd,
Eldbus_Introspection_Argument *argument_introspection;
unsigned int i;
_eldbus_model_arguments_properties_load(pd);
i = _eldbus_model_arguments_argument_index_get(pd, argument);
if (i >= eina_array_count(pd->properties_array))
{
@ -404,6 +359,7 @@ _eldbus_model_arguments_argument_index_get(Eldbus_Model_Arguments_Data *pd, cons
Eina_Stringshare *name;
Eina_Array_Iterator it;
unsigned int i = 0;
_eldbus_model_arguments_properties_load(pd);
EINA_ARRAY_ITER_NEXT(pd->properties_array, i, name, it)
{

View File

@ -27,17 +27,12 @@ class Eldbus.Model_Arguments (Eo.Base, Efl.Model.Base) {
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Model.Base.properties.get;
Efl.Model.Base.properties_load;
Efl.Model.Base.property.set;
Efl.Model.Base.property.get;
Efl.Model.Base.load;
Efl.Model.Base.load_status.get;
Efl.Model.Base.unload;
Efl.Model.Base.property_set;
Efl.Model.Base.property_get;
Efl.Model.Base.child_add;
Efl.Model.Base.child_del;
Efl.Model.Base.children_slice.get;
Efl.Model.Base.children_count.get;
Efl.Model.Base.children_load;
Efl.Model.Base.children_slice_get;
Efl.Model.Base.children_count_get;
}
constructors {
.constructor;

View File

@ -13,7 +13,6 @@ typedef struct _Eldbus_Model_Arguments_Data Eldbus_Model_Arguments_Data;
struct _Eldbus_Model_Arguments_Data
{
Eo *obj;
Efl_Model_Load load;
Eldbus_Proxy *proxy;
Eina_Array *properties_array;
Eina_Hash *properties_hash;

View File

@ -2,6 +2,7 @@
# include <config.h>
#endif
#include <Ecore.h>
#include "eldbus_model_connection_private.h"
#include "eldbus_model_private.h"
@ -10,8 +11,7 @@
#define UNIQUE_NAME_PROPERTY "unique_name"
static void _eldbus_model_connection_efl_model_base_properties_load(Eo *, Eldbus_Model_Connection_Data *);
static void _eldbus_model_connection_efl_model_base_children_load(Eo *, Eldbus_Model_Connection_Data *);
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 *);
@ -23,7 +23,7 @@ _eldbus_model_connection_eo_base_constructor(Eo *obj, Eldbus_Model_Connection_Da
obj = eo_constructor(eo_super(obj, MY_CLASS));
pd->obj = obj;
pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
pd->is_listed = EINA_FALSE;
pd->connection = NULL;
pd->properties_array = NULL;
pd->children_list = NULL;
@ -58,104 +58,66 @@ _eldbus_model_connection_eo_base_destructor(Eo *obj, Eldbus_Model_Connection_Dat
eo_destructor(eo_super(obj, MY_CLASS));
}
static Efl_Model_Load_Status
static Eina_Array const *
_eldbus_model_connection_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
Eina_Array * const* properties_array)
Eldbus_Model_Connection_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
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, EFL_MODEL_LOAD_STATUS_ERROR);
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, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
}
*(Eina_Array**)properties_array = pd->properties_array;
return pd->load.status;
return pd->properties_array;
}
static void
_eldbus_model_connection_efl_model_base_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd EINA_UNUSED,
const char *property,
Eina_Value const* value EINA_UNUSED,
Eina_Promise_Owner *promise)
{
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_READ_ONLY);
}
static void
_eldbus_model_connection_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
const char *unique_name;
Eina_Bool ret;
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
return;
if (!pd->connection)
_eldbus_model_connection_connect(pd);
pd->unique_name = eina_value_new(EINA_VALUE_TYPE_STRING);
EINA_SAFETY_ON_NULL_RETURN(pd->unique_name);
unique_name = eldbus_connection_unique_name_get(pd->connection);
ret = eina_value_set(pd->unique_name, unique_name);
EINA_SAFETY_ON_FALSE_RETURN(ret);
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
static Efl_Model_Load_Status
_eldbus_model_connection_efl_model_base_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd EINA_UNUSED,
const char *property EINA_UNUSED,
Eina_Value const* value EINA_UNUSED)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
DBG("(%p): property=%s", obj, property);
return EFL_MODEL_LOAD_STATUS_ERROR;
}
static Efl_Model_Load_Status
_eldbus_model_connection_efl_model_base_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
const char *property,
Eina_Value const **value)
Eina_Promise_Owner *promise)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN(promise);
DBG("(%p): property=%s", obj, property);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
return EFL_MODEL_LOAD_STATUS_ERROR;
if (strcmp(property, UNIQUE_NAME_PROPERTY) != 0)
return EFL_MODEL_LOAD_STATUS_ERROR;
*value = pd->unique_name;
return pd->load.status;
}
static void
_eldbus_model_connection_efl_model_base_load(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
if (!pd->connection)
_eldbus_model_connection_connect(pd);
_eldbus_model_connection_efl_model_base_properties_load(obj, pd);
_eldbus_model_connection_efl_model_base_children_load(obj, pd);
}
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
static Efl_Model_Load_Status
_eldbus_model_connection_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
return pd->load.status;
}
if (pd->unique_name == NULL)
{
const char *unique_name;
static void
_eldbus_model_connection_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
{
_eldbus_model_connection_clear(pd);
unique_name = eldbus_connection_unique_name_get(pd->connection);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND);
pd->unique_name = strdup(unique_name);
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED);
Eina_Value* v = eina_promise_owner_buffer_get(promise);
eina_value_setup(v, EINA_VALUE_TYPE_STRING);
eina_value_set(v, pd->unique_name);
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
}
static Eo *
@ -164,56 +126,70 @@ _eldbus_model_connection_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Mo
return NULL;
}
static Efl_Model_Load_Status
static void
_eldbus_model_connection_efl_model_base_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
return EFL_MODEL_LOAD_STATUS_ERROR;
}
static Efl_Model_Load_Status
static void
_eldbus_model_connection_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
unsigned start,
unsigned count,
Eina_Accessor **children_accessor)
{
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN))
{
WRN("(%p): Children not loaded", obj);
*children_accessor = NULL;
return pd->load.status;
}
*children_accessor = efl_model_list_slice(pd->children_list, start, count);
return pd->load.status;
}
static Efl_Model_Load_Status
_eldbus_model_connection_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
unsigned *children_count)
{
*children_count = eina_list_count(pd->children_list);
return pd->load.status;
}
static void
_eldbus_model_connection_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Connection_Data *pd)
Eina_Promise_Owner *promise)
{
_Eldbus_Children_Slice_Promise* data;
Eldbus_Pending *pending;
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
return;
if (!pd->connection)
_eldbus_model_connection_connect(pd);
pending = eldbus_names_list(pd->connection, &_eldbus_model_connection_names_list_cb, pd);
pd->pending_list = eina_list_append(pd->pending_list, pending);
if (pd->is_listed)
{
Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
eina_promise_owner_value_set(promise, &ac, (Eina_Promise_Free_Cb)&_accessor_free);
return;
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
data = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
EINA_SAFETY_ON_NULL_RETURN(data);
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);
}
}
static void
_eldbus_model_connection_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Connection_Data *pd,
Eina_Promise_Owner *promise)
{
Eldbus_Pending *pending;
if (!pd->connection)
_eldbus_model_connection_connect(pd);
if (pd->is_listed)
{
unsigned int c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
return;
}
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);
}
}
static const char *
@ -297,7 +273,7 @@ _eldbus_model_connection_clear(Eldbus_Model_Connection_Data *pd)
if (!pd->connection)
return;
eina_value_free(pd->unique_name);
free(pd->unique_name);
pd->unique_name = NULL;
EINA_LIST_FREE(pd->children_list, child)
@ -321,17 +297,19 @@ _eldbus_model_connection_names_list_cb(void *data,
Eldbus_Pending *pending)
{
Eldbus_Model_Connection_Data *pd = (Eldbus_Model_Connection_Data*)data;
_Eldbus_Children_Slice_Promise * p;
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);
if (eldbus_message_error_get(msg, &error_name, &error_text))
{
ERR("%s: %s", error_name, error_text);
efl_model_error_notify(pd->obj);
//efl_model_error_notify(pd->obj);
return;
}
@ -350,11 +328,29 @@ _eldbus_model_connection_names_list_cb(void *data,
pd->children_list = eina_list_append(pd->children_list, child);
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
count = eina_list_count(pd->children_list);
if (count)
eo_event_callback_call(pd->obj, EFL_MODEL_BASE_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);
eina_promise_owner_value_set(p->promise, &ac, (Eina_Promise_Free_Cb)&_accessor_free);
free(p);
}
eina_list_free(pd->children_promises);
Eina_Promise_Owner *ep;
EINA_LIST_FOREACH(pd->count_promises, i, ep)
{
unsigned c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(ep, &c, NULL);
}
eina_list_free(pd->count_promises);
}
#include "eldbus_model_connection.eo.c"

View File

@ -36,17 +36,12 @@ class Eldbus.Model_Connection (Eo.Base, Efl.Model.Base) {
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Model.Base.properties.get;
Efl.Model.Base.properties_load;
Efl.Model.Base.property.set;
Efl.Model.Base.property.get;
Efl.Model.Base.load;
Efl.Model.Base.load_status.get;
Efl.Model.Base.unload;
Efl.Model.Base.property_set;
Efl.Model.Base.property_get;
Efl.Model.Base.child_add;
Efl.Model.Base.child_del;
Efl.Model.Base.children_slice.get;
Efl.Model.Base.children_count.get;
Efl.Model.Base.children_load;
Efl.Model.Base.children_slice_get;
Efl.Model.Base.children_count_get;
}
constructors {
.constructor;

View File

@ -13,14 +13,16 @@ typedef struct _Eldbus_Model_Connection_Data Eldbus_Model_Connection_Data;
struct _Eldbus_Model_Connection_Data
{
Eo *obj;
Efl_Model_Load load;
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_Connection_Type type;
Eina_Stringshare *address;
bool private;
Eina_Value *unique_name;
char *unique_name;
Eina_List *pending_list;
};

View File

@ -40,7 +40,7 @@ _eldbus_model_method_constructor(Eo *obj EINA_UNUSED,
pd->method = method;
}
static Efl_Model_Load_Status
static void
_eldbus_model_method_call(Eo *obj EINA_UNUSED, Eldbus_Model_Method_Data *pd EINA_UNUSED)
{
Eldbus_Model_Arguments_Data *data = eo_data_scope_get(obj, ELDBUS_MODEL_ARGUMENTS_CLASS);
@ -82,11 +82,10 @@ _eldbus_model_method_call(Eo *obj EINA_UNUSED, Eldbus_Model_Method_Data *pd EINA
pending = eldbus_proxy_send(data->proxy, msg, _eldbus_model_method_call_cb, pd, -1);
data->pending_list = eina_list_append(data->pending_list, pending);
return data->load.status;
return;
on_error:
eldbus_message_unref(msg);
return EFL_MODEL_LOAD_STATUS_ERROR;
}
static void

View File

@ -19,10 +19,8 @@ class Eldbus.Model_Method (Eldbus.Model_Arguments) {
The event EMODEL_EVENT_PROPERTIES_CHANGED is raised for output arguments (properties).
The event ELDBUS_MODEL_METHOD_EVENT_METHOD_CALLED is raised for a successful call. Otherwise
the event EMODEL_EVENT_LOAD_STATUS with the status set to EMODEL_LOAD_STATUS_ERROR is raised.
@since 1.16]]
return: Efl.Model.Load_Status; [[#Emodel_Load_Status on success, #EMODEL_LOAD_STATUS_ERROR otherwise.]]
}
}
implements {

View File

@ -5,6 +5,7 @@
#include "eldbus_model_object_private.h"
#include "eldbus_model_private.h"
#include <Ecore.h>
#include <Eina.h>
#define MY_CLASS ELDBUS_MODEL_OBJECT_CLASS
@ -12,8 +13,6 @@
#define UNIQUE_NAME_PROPERTY "unique_name"
static void _eldbus_model_object_efl_model_base_properties_load(Eo *, Eldbus_Model_Object_Data *);
static void _eldbus_model_object_efl_model_base_children_load(Eo *, Eldbus_Model_Object_Data *);
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 *);
@ -23,13 +22,20 @@ static void _eldbus_model_object_introspect_nodes(Eldbus_Model_Object_Data *, co
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 *);
void
_accessor_free(void *data)
{
Eina_Accessor **ac = data;
eina_accessor_free(*ac);
}
static Eo_Base*
_eldbus_model_object_eo_base_constructor(Eo *obj, Eldbus_Model_Object_Data *pd)
{
obj = eo_constructor(eo_super(obj, MY_CLASS));
pd->obj = obj;
pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
pd->is_listed = EINA_FALSE;
pd->connection = NULL;
pd->object_list = NULL;
pd->properties_array = NULL;
@ -93,104 +99,67 @@ _eldbus_model_object_eo_base_destructor(Eo *obj, Eldbus_Model_Object_Data *pd)
eo_destructor(eo_super(obj, MY_CLASS));
}
static Efl_Model_Load_Status
static Eina_Array const *
_eldbus_model_object_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
Eina_Array * const* properties_array)
Eldbus_Model_Object_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
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, EFL_MODEL_LOAD_STATUS_ERROR);
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, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, NULL);
}
*(Eina_Array**)properties_array = pd->properties_array;
return pd->load.status;
return pd->properties_array;
}
static void
_eldbus_model_object_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
{
const char *unique_name;
Eina_Bool ret;
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
return;
if (!pd->connection)
_eldbus_model_object_connect(pd);
pd->unique_name = eina_value_new(EINA_VALUE_TYPE_STRING);
EINA_SAFETY_ON_NULL_RETURN(pd->unique_name);
unique_name = eldbus_connection_unique_name_get(pd->connection);
ret = eina_value_set(pd->unique_name, unique_name);
EINA_SAFETY_ON_FALSE_RETURN(ret);
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
static Efl_Model_Load_Status
_eldbus_model_object_efl_model_base_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd EINA_UNUSED,
const char *property EINA_UNUSED,
Eina_Value const* value EINA_UNUSED)
const char *property,
const Eina_Value *value EINA_UNUSED,
Eina_Promise_Owner *promise)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
DBG("(%p): property=%s", obj, property);
return EFL_MODEL_LOAD_STATUS_ERROR;
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
eina_promise_owner_error_set(promise, EFL_MODEL_ERROR_NOT_SUPPORTED);
}
static Efl_Model_Load_Status
static void
_eldbus_model_object_efl_model_base_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
const char *property,
Eina_Value const**value)
Eina_Promise_Owner *promise)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN(promise);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
DBG("(%p): property=%s", obj, property);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
return EFL_MODEL_LOAD_STATUS_ERROR;
if (strcmp(property, UNIQUE_NAME_PROPERTY) != 0)
return EFL_MODEL_LOAD_STATUS_ERROR;
*value = pd->unique_name;
return pd->load.status;
}
static void
_eldbus_model_object_efl_model_base_load(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
{
if (!pd->connection)
_eldbus_model_object_connect(pd);
_eldbus_model_object_efl_model_base_properties_load(obj, pd);
_eldbus_model_object_efl_model_base_children_load(obj, pd);
}
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET((strcmp(property, UNIQUE_NAME_PROPERTY) == 0), promise, EFL_MODEL_ERROR_NOT_FOUND);
static Efl_Model_Load_Status
_eldbus_model_object_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
{
return pd->load.status;
}
if (pd->unique_name == NULL)
{
const char *unique_name;
static void
_eldbus_model_object_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
{
_eldbus_model_object_clear(pd);
unique_name = eldbus_connection_unique_name_get(pd->connection);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(unique_name, promise, EFL_MODEL_ERROR_NOT_FOUND);
pd->unique_name = strdup(unique_name);
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED);
Eina_Value* v = eina_promise_owner_buffer_get(promise);
eina_value_setup(v, EINA_VALUE_TYPE_STRING);
eina_value_set(v, pd->unique_name);
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
}
static Eo *
@ -199,56 +168,61 @@ _eldbus_model_object_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_
return NULL;
}
static Efl_Model_Load_Status
static void
_eldbus_model_object_efl_model_base_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
return EFL_MODEL_LOAD_STATUS_ERROR;
}
static Efl_Model_Load_Status
static void
_eldbus_model_object_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
unsigned start,
unsigned count,
Eina_Accessor **children_accessor)
Eina_Promise_Owner *promise)
{
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN))
{
WRN("(%p): Children not loaded", obj);
*children_accessor = NULL;
return pd->load.status;
}
else
WRN("(%p): Children already loaded", obj);
*children_accessor = efl_model_list_slice(pd->children_list, start, count);
return pd->load.status;
}
static Efl_Model_Load_Status
_eldbus_model_object_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
unsigned *children_count)
{
*children_count = eina_list_count(pd->children_list);
return pd->load.status;
}
static void
_eldbus_model_object_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Object_Data *pd)
{
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
return;
_Eldbus_Children_Slice_Promise* p;
if (!pd->connection)
_eldbus_model_object_connect(pd);
if (!_eldbus_model_object_introspect(pd, pd->bus, pd->path))
return;
if (pd->is_listed)
{
Eina_Accessor* ac = efl_model_list_slice(pd->children_list, start, count);
eina_promise_owner_value_set(promise, &ac, &_accessor_free);
return;
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
p = calloc(1, sizeof(struct _Eldbus_Children_Slice_Promise));
EINA_SAFETY_ON_NULL_RETURN(p);
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);
}
static void
_eldbus_model_object_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Object_Data *pd,
Eina_Promise_Owner *promise)
{
if (!pd->connection)
_eldbus_model_object_connect(pd);
if (pd->is_listed)
{
unsigned int c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
return;
}
pd->count_promises = eina_list_prepend(pd->count_promises, promise);
if (pd->pending_list == NULL)
_eldbus_model_object_introspect(pd, pd->bus, pd->path);
}
static const char *
@ -358,7 +332,7 @@ _eldbus_model_object_clear(Eldbus_Model_Object_Data *pd)
if (!pd->connection)
return;
eina_value_free(pd->unique_name);
free(pd->unique_name);
pd->unique_name = NULL;
EINA_LIST_FREE(pd->children_list, child)
@ -432,7 +406,7 @@ _eldbus_model_object_introspect_cb(void *data,
if (eldbus_message_error_get(msg, &error_name, &error_text))
{
ERR("%s: %s", error_name, error_text);
efl_model_error_notify(pd->obj);
//efl_model_error_notify(pd->obj);
return;
}
@ -456,13 +430,26 @@ _eldbus_model_object_introspect_cb(void *data,
if (eina_list_count(pd->pending_list) == 0)
{
unsigned int count;
Eina_List* i;
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
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);
eina_promise_owner_value_set(p->promise, &ac, &_accessor_free);
free(p);
}
eina_list_free(pd->children_promises);
Eina_Promise_Owner *ep;
EINA_LIST_FOREACH(pd->count_promises, i, ep)
{
unsigned c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(ep, &c, NULL);
}
eina_list_free(pd->count_promises);
count = eina_list_count(pd->children_list);
if (count)
eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count);
}
}

View File

@ -63,17 +63,12 @@ class Eldbus.Model_Object (Eo.Base, Efl.Model.Base) {
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Model.Base.properties.get;
Efl.Model.Base.properties_load;
Efl.Model.Base.property.set;
Efl.Model.Base.property.get;
Efl.Model.Base.load;
Efl.Model.Base.load_status.get;
Efl.Model.Base.unload;
Efl.Model.Base.property_set;
Efl.Model.Base.property_get;
Efl.Model.Base.child_add;
Efl.Model.Base.child_del;
Efl.Model.Base.children_slice.get;
Efl.Model.Base.children_count.get;
Efl.Model.Base.children_load;
Efl.Model.Base.children_slice_get;
Efl.Model.Base.children_count_get;
}
constructors {
.constructor;

View File

@ -5,25 +5,26 @@
#include <stdbool.h>
typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
/**
* eldbus_model_object
*/
typedef struct _Eldbus_Model_Object_Data Eldbus_Model_Object_Data;
struct _Eldbus_Model_Object_Data
{
Eo *obj;
Efl_Model_Load load;
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_Stringshare *bus;
Eina_Stringshare *path;
Eina_Value *unique_name;
char *unique_name;
Eina_List *pending_list;
Eldbus_Introspection_Node *introspection;
};

View File

@ -3,12 +3,42 @@
#include "eldbus_private.h"
#include <Ecore.h>
#include <Eina.h>
#include <Eo.h>
#include <Efl.h>
typedef struct _Eldbus_Children_Slice_Promise _Eldbus_Children_Slice_Promise;
struct _Eldbus_Children_Slice_Promise
{
unsigned start;
unsigned count;
Eina_Promise_Owner* promise;
};
typedef struct _Eldbus_Property_Promise _Eldbus_Property_Promise;
struct _Eldbus_Property_Promise
{
char *property;
Eina_Promise_Owner* promise;
};
void _accessor_free(void *data);
/* logging support */
extern int eldbus_model_log_dom;
#define ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(exp, promise, err) \
do \
{ \
if (EINA_UNLIKELY(!(exp))) \
{ \
eina_promise_owner_error_set(promise, err); \
return; \
} \
} \
while(0)
#ifdef CRI
# undef CRI
#endif

View File

@ -10,9 +10,7 @@
#define MY_CLASS ELDBUS_MODEL_PROXY_CLASS
#define MY_CLASS_NAME "Eldbus_Model_Proxy"
static void _eldbus_model_proxy_efl_model_base_properties_load(Eo *, Eldbus_Model_Proxy_Data *);
static void _eldbus_model_proxy_efl_model_base_children_load(Eo *, Eldbus_Model_Proxy_Data *);
static bool _eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *);
static Eina_Bool _eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *);
static void _eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *);
static void _eldbus_model_proxy_property_get_all_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
static void _eldbus_model_proxy_property_set_cb(void *, const Eldbus_Message *, Eldbus_Pending *);
@ -50,14 +48,15 @@ _eldbus_model_proxy_eo_base_constructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
obj = eo_constructor(eo_super(obj, MY_CLASS));
pd->obj = obj;
pd->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
pd->object = NULL;
pd->proxy = NULL;
pd->is_listed = pd->is_loaded = EINA_FALSE;
pd->properties_array = NULL;
pd->properties_hash = eina_hash_string_superfast_new(EINA_FREE_CB(_eldbus_model_proxy_hash_free));
pd->children_list = NULL;
pd->name = NULL;
pd->pending_list = NULL;
pd->promise_list = NULL;
pd->monitoring = false;
pd->interface = NULL;
@ -91,210 +90,143 @@ _eldbus_model_proxy_eo_base_destructor(Eo *obj, Eldbus_Model_Proxy_Data *pd)
eo_destructor(eo_super(obj, MY_CLASS));
}
static Efl_Model_Load_Status
static Eina_Array const *
_eldbus_model_proxy_efl_model_base_properties_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd,
Eina_Array * const* properties_array)
Eldbus_Model_Proxy_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->obj, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
{
WRN("%s", "Properties not loaded.");
return EFL_MODEL_LOAD_STATUS_ERROR;
}
*(Eina_Array**)properties_array = pd->properties_array;
return pd->load.status;
_eldbus_model_proxy_load(pd);
return pd->properties_array;
}
static void
_eldbus_model_proxy_efl_model_base_properties_load(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
{
Eldbus_Introspection_Property *property;
Eina_List *it;
Eldbus_Pending *pending;
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
return;
if (!_eldbus_model_proxy_load(pd))
return;
const unsigned int properties_count = eina_list_count(pd->interface->properties);
pd->properties_array = eina_array_new(properties_count);
EINA_SAFETY_ON_NULL_RETURN(pd->properties_array);
if (!properties_count)
{
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
return;
}
EINA_LIST_FOREACH(pd->interface->properties, it, property)
{
Eina_Stringshare *name;
Eina_Bool ret;
name = eina_stringshare_add(property->name);
ret = eina_array_push(pd->properties_array, name);
EINA_SAFETY_ON_FALSE_RETURN(ret);
}
pending = eldbus_proxy_property_get_all(pd->proxy, _eldbus_model_proxy_property_get_all_cb, pd);
pd->pending_list = eina_list_append(pd->pending_list, pending);
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES);
}
static Efl_Model_Load_Status
_eldbus_model_proxy_efl_model_base_property_set(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd,
const char *property,
Eina_Value const* value)
Eina_Value const* value,
Eina_Promise_Owner *promise)
{
Eldbus_Model_Proxy_Property_Set_Data *data;
const char *signature;
Eldbus_Pending *pending;
Eina_Bool ret;
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
DBG("(%p): property=%s", obj, property);
ret = _eldbus_model_proxy_load(pd);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
if (!_eldbus_model_proxy_is_property_writeable(pd, property))
{
WRN("Property is read-only: %s", property);
return EFL_MODEL_LOAD_STATUS_ERROR;
}
ret = _eldbus_model_proxy_is_property_writeable(pd, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY);
data = _eldbus_model_proxy_property_set_data_new(pd, property, value);
EINA_SAFETY_ON_NULL_RETURN_VAL(data, EFL_MODEL_LOAD_STATUS_ERROR);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(data, promise, EFL_MODEL_ERROR_UNKNOWN);
signature = _eldbus_model_proxy_property_type_get(pd, property);
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EFL_MODEL_LOAD_STATUS_ERROR);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(data, promise, EFL_MODEL_ERROR_UNKNOWN);
pd->promises_set = eina_list_append(pd->promises_set, promise);
pending = eldbus_proxy_property_value_set
(pd->proxy, property, signature, (Eina_Value*)value, _eldbus_model_proxy_property_set_cb, data);
pd->pending_list = eina_list_append(pd->pending_list, pending);
return pd->load.status;
}
static Efl_Model_Load_Status
static void
_eldbus_model_proxy_efl_model_base_property_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd,
const char *property,
Eina_Value const **value)
Eina_Promise_Owner *promise)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EFL_MODEL_LOAD_STATUS_ERROR);
EINA_SAFETY_ON_NULL_RETURN_VAL(value, EFL_MODEL_LOAD_STATUS_ERROR);
Eina_Bool ret;
EINA_SAFETY_ON_NULL_RETURN(promise);
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
return EFL_MODEL_LOAD_STATUS_ERROR;
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
if (!_eldbus_model_proxy_is_property_readable(pd, property))
ret = _eldbus_model_proxy_load(pd);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
if (!pd->is_loaded)
{
WRN("Property is write-only: %s", property);
return EFL_MODEL_LOAD_STATUS_ERROR;
Eldbus_Pending *pending;
_Eldbus_Property_Promise *p = calloc(1, sizeof(_Eldbus_Property_Promise));
EINA_SAFETY_ON_NULL_RETURN(p);
p->promise = promise;
p->property = strdup(property);
pd->promise_list = eina_list_append(pd->promise_list, p);
if (!pd->pending_list)
{
pending = eldbus_proxy_property_get_all(pd->proxy, _eldbus_model_proxy_property_get_all_cb, pd);
pd->pending_list = eina_list_append(pd->pending_list, pending);
}
return;
}
*value = eina_hash_find(pd->properties_hash, property);
Eina_Value* value = eina_hash_find(pd->properties_hash, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_NOT_FOUND);
if(!*value)
{
*value = &pd->tmp_value;
return EFL_MODEL_LOAD_STATUS_ERROR;
}
ret = _eldbus_model_proxy_is_property_writeable(pd, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY);
return pd->load.status;
}
static void
_eldbus_model_proxy_efl_model_base_load(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
{
if (!_eldbus_model_proxy_load(pd))
return;
_eldbus_model_proxy_efl_model_base_properties_load(obj, pd);
_eldbus_model_proxy_efl_model_base_children_load(obj, pd);
}
static Efl_Model_Load_Status
_eldbus_model_proxy_efl_model_base_load_status_get(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
{
return pd->load.status;
}
static void
_eldbus_model_proxy_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
{
_eldbus_model_proxy_unload(pd);
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_UNLOADED);
eina_value_copy(value, eina_promise_owner_buffer_get(promise));
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
}
static Eo *
_eldbus_model_proxy_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd EINA_UNUSED)
_eldbus_model_proxy_efl_model_base_child_add(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd EINA_UNUSED)
{
return NULL;
}
static Efl_Model_Load_Status
static void
_eldbus_model_proxy_efl_model_base_child_del(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd EINA_UNUSED,
Eo *child EINA_UNUSED)
{
return EFL_MODEL_LOAD_STATUS_ERROR;
}
static Efl_Model_Load_Status
static void
_eldbus_model_proxy_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd,
unsigned start,
unsigned count,
Eina_Accessor **children_accessor)
Eina_Promise_Owner *promise)
{
if (!(pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN))
Eina_Bool ret = _eldbus_model_proxy_load(pd);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
if (!pd->is_listed)
{
WRN("(%p): Children not loaded", obj);
*children_accessor = NULL;
return pd->load.status;
_eldbus_model_proxy_create_methods_children(pd);
_eldbus_model_proxy_create_signals_children(pd);
pd->is_listed = EINA_TRUE;
}
*children_accessor = efl_model_list_slice(pd->children_list, start, count);
return pd->load.status;
}
static Efl_Model_Load_Status
_eldbus_model_proxy_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd,
unsigned *children_count)
{
*children_count = eina_list_count(pd->children_list);
return pd->load.status;
Eina_Accessor *ac = efl_model_list_slice(pd->children_list, start, count);
eina_promise_owner_value_set(promise, &ac, (Eina_Promise_Free_Cb)&_accessor_free);
}
static void
_eldbus_model_proxy_efl_model_base_children_load(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
_eldbus_model_proxy_efl_model_base_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Proxy_Data *pd,
Eina_Promise_Owner *promise)
{
unsigned int count;
Eina_Bool ret = _eldbus_model_proxy_load(pd);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_INIT_FAILED);
if (pd->load.status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
return;
if (!pd->is_listed)
{
_eldbus_model_proxy_create_methods_children(pd);
_eldbus_model_proxy_create_signals_children(pd);
pd->is_listed = EINA_TRUE;
}
if (!_eldbus_model_proxy_load(pd))
return;
_eldbus_model_proxy_create_methods_children(pd);
_eldbus_model_proxy_create_signals_children(pd);
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
count = eina_list_count(pd->children_list);
if (count)
eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count);
unsigned int c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
}
static void
@ -323,7 +255,8 @@ _eldbus_model_proxy_create_methods_children(Eldbus_Model_Proxy_Data *pd)
method_name = method->name;
if (!method_name) continue;
INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s", pd->obj, bus, path, interface_name, method_name);
INF("(%p) Creating method child: bus = %s, path = %s, method = %s::%s",
pd->obj, bus, path, interface_name, method_name);
child = eo_add(ELDBUS_MODEL_METHOD_CLASS, NULL, eldbus_model_method_constructor(eo_self, pd->proxy, method));
@ -357,7 +290,8 @@ _eldbus_model_proxy_create_signals_children(Eldbus_Model_Proxy_Data *pd)
signal_name = signal->name;
if (!signal_name) continue;
DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s", pd->obj, bus, path, interface_name, signal_name);
DBG("(%p) Creating signal child: bus = %s, path = %s, signal = %s::%s",
pd->obj, bus, path, interface_name, signal_name);
child = eo_add(ELDBUS_MODEL_SIGNAL_CLASS, NULL, eldbus_model_signal_constructor(eo_self, pd->proxy, signal));
@ -371,22 +305,42 @@ _eldbus_model_proxy_name_get(Eo *obj EINA_UNUSED, Eldbus_Model_Proxy_Data *pd)
return pd->name;
}
static bool
static Eina_Bool
_eldbus_model_proxy_load(Eldbus_Model_Proxy_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
Eldbus_Introspection_Property *property;
Eina_List *it;
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EINA_FALSE);
if (pd->proxy)
return true;
return EINA_TRUE;
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->object, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->name, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->interface, EINA_FALSE);
pd->proxy = eldbus_proxy_get(pd->object, pd->name);
if (!pd->proxy)
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->proxy, EINA_FALSE);
const unsigned int properties_count = eina_list_count(pd->interface->properties);
pd->properties_array = eina_array_new(properties_count);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->properties_array, EINA_FALSE);
if (!properties_count) return EINA_TRUE;
EINA_LIST_FOREACH(pd->interface->properties, it, property)
{
ERR("Cannot get proxy for interface: %s", pd->name);
return false;
Eina_Stringshare *name;
Eina_Bool ret;
name = eina_stringshare_add(property->name);
ret = eina_array_push(pd->properties_array, name);
EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, EINA_FALSE);
}
return true;
return EINA_TRUE;
}
static void
@ -401,7 +355,9 @@ _eldbus_model_proxy_unload(Eldbus_Model_Proxy_Data *pd)
eo_unref(child);
EINA_LIST_FREE(pd->pending_list, pending)
{
eldbus_pending_cancel(pending);
}
if (pd->properties_array)
{
@ -491,18 +447,6 @@ _eldbus_model_proxy_property_invalidated_cb(void *data,
Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
Eldbus_Proxy_Event_Property_Changed *event = (Eldbus_Proxy_Event_Property_Changed*)event_info;
#if 0
Efl_Model_Property_Event evt = {0};
// TODO: eldbus_proxy_property_get(event->name) ?
evt.invalidated_properties = eina_array_new(1);
EINA_SAFETY_ON_NULL_RETURN(evt.invalidated_properties);
eina_array_push(evt.invalidated_properties, event->name);
eina_array_free(evt.invalidated_properties);
#endif
efl_model_property_invalidated_notify(pd->obj, event->name);
}
@ -524,7 +468,14 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
if (eldbus_message_error_get(msg, &error_name, &error_text))
{
ERR("%s: %s", error_name, error_text);
efl_model_error_notify(pd->obj);
Eina_List* i;
_Eldbus_Property_Promise* p;
EINA_LIST_FOREACH(pd->promise_list, i, p)
{
eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_UNKNOWN);
free(p->property);
}
eina_list_free(pd->promise_list);
return;
}
@ -577,6 +528,28 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
EINA_SAFETY_ON_FALSE_GOTO(ret, on_error);
}
pd->is_loaded = EINA_TRUE;
Eina_List* i;
_Eldbus_Property_Promise* p;
EINA_LIST_FOREACH(pd->promise_list, i, p)
{
Eina_Value* value = eina_hash_find(pd->properties_hash, p->property);
if (!value || !_eldbus_model_proxy_is_property_readable(pd, p->property))
{
eina_promise_owner_error_set(p->promise, EFL_MODEL_ERROR_READ_ONLY);
free(p->property);
continue;
}
free(p->property);
eina_value_copy(value, eina_promise_owner_buffer_get(p->promise));
eina_promise_owner_value_set(p->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
}
eina_list_free(pd->promise_list);
_eldbus_model_proxy_start_monitor(pd);
if (eina_array_count(changed_properties))
@ -588,8 +561,6 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
eo_event_callback_call(pd->obj, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, &evt);
}
efl_model_load_set(pd->obj, &pd->load, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
on_error:
eina_array_free(changed_properties);
}
@ -611,7 +582,6 @@ _eldbus_model_proxy_property_set_cb(void *data,
if (eldbus_message_error_get(msg, &error_name, &error_text))
{
ERR("%s: %s", error_name, error_text);
efl_model_error_notify(pd->obj);
goto on_error;
}
@ -622,6 +592,7 @@ _eldbus_model_proxy_property_set_cb(void *data,
ret = eina_value_copy(&property_set_data->value, prop_value);
EINA_SAFETY_ON_FALSE_GOTO(ret, on_error);
on_error:
{
Efl_Model_Property_Event evt = {
.changed_properties = pd->properties_array
@ -631,7 +602,6 @@ _eldbus_model_proxy_property_set_cb(void *data,
efl_model_property_changed_notify(pd->obj, property_set_data->property);
}
on_error:
_eldbus_model_proxy_property_set_data_free(property_set_data);
}

View File

@ -26,17 +26,12 @@ class Eldbus.Model_Proxy (Eo.Base, Efl.Model.Base) {
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Model.Base.properties.get;
Efl.Model.Base.properties_load;
Efl.Model.Base.property.set;
Efl.Model.Base.property.get;
Efl.Model.Base.load;
Efl.Model.Base.load_status.get;
Efl.Model.Base.unload;
Efl.Model.Base.property_set;
Efl.Model.Base.property_get;
Efl.Model.Base.child_add;
Efl.Model.Base.child_del;
Efl.Model.Base.children_slice.get;
Efl.Model.Base.children_count.get;
Efl.Model.Base.children_load;
Efl.Model.Base.children_slice_get;
Efl.Model.Base.children_count_get;
}
constructors {
.constructor;

View File

@ -13,7 +13,8 @@ typedef struct _Eldbus_Model_Proxy_Data Eldbus_Model_Proxy_Data;
struct _Eldbus_Model_Proxy_Data
{
Eo *obj;
Efl_Model_Load load;
Eina_Bool is_listed : 1;
Eina_Bool is_loaded : 1;
Eldbus_Object *object;
Eldbus_Proxy *proxy;
Eina_Array *properties_array;
@ -21,6 +22,8 @@ struct _Eldbus_Model_Proxy_Data
Eina_List *children_list;
Eina_Stringshare *name;
Eina_List *pending_list;
Eina_List *promise_list;
Eina_List *promises_set;
bool monitoring;
const Eldbus_Introspection_Interface *interface;
Eina_Value tmp_value;

View File

@ -6,6 +6,7 @@
#include "eldbus_model_signal_private.h"
#include "eldbus_model_private.h"
#include <Ecore.h>
#include <Eina.h>
#define MY_CLASS ELDBUS_MODEL_SIGNAL_CLASS
@ -38,6 +39,7 @@ _eldbus_model_signal_constructor(Eo *obj EINA_UNUSED,
eldbus_model_arguments_constructor(eo_super(obj, MY_CLASS), proxy, signal->name, signal->arguments);
pd->signal = signal;
_eldbus_model_signal_callback_add(pd);
}
static void
@ -48,26 +50,6 @@ _eldbus_model_signal_eo_base_destructor(Eo *obj, Eldbus_Model_Signal_Data *pd)
eo_destructor(eo_super(obj, MY_CLASS));
}
static void
_eldbus_model_signal_efl_model_base_properties_load(Eo *obj, Eldbus_Model_Signal_Data *pd)
{
Eldbus_Model_Arguments_Data *args_data = eo_data_scope_get(pd->obj, ELDBUS_MODEL_ARGUMENTS_CLASS);
EINA_SAFETY_ON_NULL_RETURN(args_data);
if (args_data->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
return;
_eldbus_model_signal_callback_add(pd);
efl_model_properties_load(eo_super(obj, MY_CLASS));
}
static void
_eldbus_model_signal_efl_model_base_unload(Eo *obj EINA_UNUSED, Eldbus_Model_Signal_Data *pd)
{
_eldbus_model_signal_callback_del(pd);
efl_model_unload(eo_super(obj, MY_CLASS));
}
static void
_eldbus_model_signal_callback_add(Eldbus_Model_Signal_Data *pd)

View File

@ -16,8 +16,6 @@ class Eldbus.Model_Signal (Eldbus.Model_Arguments) {
implements {
Eo.Base.constructor;
Eo.Base.destructor;
Efl.Model.Base.properties_load;
Efl.Model.Base.unload;
}
constructors {
.constructor;

View File

@ -16,12 +16,13 @@
typedef struct _Elm_View_Form_Data Elm_View_Form_Data;
typedef struct _Elm_View_Form_Widget Elm_View_Form_Widget;
typedef struct _Elm_View_Form_Promise Elm_View_Form_Promise;
/**
* @brief Local-use callbacks
*/
typedef void (*Elm_View_Form_Event_Cb)(Elm_View_Form_Widget *, Elm_View_Form_Data *, Evas_Object *);
typedef void (*Elm_View_Form_Widget_Object_Set_Cb)(Eo *, Evas_Object *, const Eina_Value *, const char *);
typedef void (*Elm_View_Form_Widget_Object_Set_Cb)(Evas_Object *, const Eina_Value *, const char *);
struct _Elm_View_Form_Widget
{
@ -34,20 +35,66 @@ struct _Elm_View_Form_Widget
struct _Elm_View_Form_Data
{
Eo *model_obj;
Eina_Value *properties;
Eina_List *l;
Eina_List *widgets;
};
struct _Elm_View_Form_Promise
{
Elm_View_Form_Data *priv;
Eina_Stringshare *property_name;
};
static void
_efl_promise_then_widget(Elm_View_Form_Widget *w, Eina_Value *value)
{
w->widget_obj_set_cb(w->widget_obj, value, w->widget_propname);
}
static void
_efl_promise_error_widget(void *data EINA_UNUSED, const Eina_Error *err EINA_UNUSED)
{
}
static void
_efl_model_promise_then_cb(Elm_View_Form_Promise *p, Eina_Value *value)
{
EINA_SAFETY_ON_NULL_RETURN(p);
Elm_View_Form_Data *priv = p->priv;
Elm_View_Form_Widget *w = NULL;
Eina_List *l = NULL;
EINA_LIST_FOREACH(priv->widgets, l, w)
{
if (!strcmp(w->widget_propname, p->property_name))
{
w->widget_obj_set_cb(w->widget_obj, value, w->widget_propname);
}
}
eina_stringshare_del(p->property_name);
free(p);
}
static void
_efl_model_promise_error_cb(Elm_View_Form_Promise *p, const Eina_Error *error EINA_UNUSED)
{
EINA_SAFETY_ON_NULL_RETURN(p);
eina_stringshare_del(p->property_name);
free(p);
}
static Eina_Bool
_efl_model_properties_change_cb(void *data, const Eo_Event *event)
{
const Efl_Model_Property_Event *evt = event->info;
const Eina_Value *value;
Eina_Promise *promise;
const char *prop;
unsigned int i;
Elm_View_Form_Data *priv = data;
Eina_List *l = NULL;
Elm_View_Form_Widget *w = NULL;
Elm_View_Form_Promise *p = NULL;
Eina_Array_Iterator it;
EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_TRUE);
@ -57,16 +104,14 @@ _efl_model_properties_change_cb(void *data, const Eo_Event *event)
return EINA_TRUE;
//update all widgets with this property
EINA_LIST_FOREACH(priv->l, l, w)
EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
{
EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
{
if (!strcmp(w->widget_propname, prop))
{
efl_model_property_get(priv->model_obj, prop, &value);
w->widget_obj_set_cb(priv->model_obj, w->widget_obj, value, w->widget_propname);
}
}
p = calloc(1, sizeof(Elm_View_Form_Promise));
p->property_name = eina_stringshare_add(prop);
p->priv = priv;
efl_model_property_get(priv->model_obj, prop, &promise);
eina_promise_then(promise, (Eina_Promise_Cb)&_efl_model_promise_then_cb,
(Eina_Promise_Error_Cb)&_efl_model_promise_error_cb, p);
}
return EINA_TRUE;
@ -75,14 +120,17 @@ _efl_model_properties_change_cb(void *data, const Eo_Event *event)
static void
_update_model_properties(Elm_View_Form_Data *priv)
{
const Eina_Value *value;
Eina_List *l;
Elm_View_Form_Widget *w;
Eina_Promise *promise;
//update all widgets property
EINA_LIST_FOREACH(priv->l, l, w)
if (priv->model_obj == NULL)
return;
EINA_LIST_FOREACH(priv->widgets, l, w)
{
efl_model_property_get(priv->model_obj, w->widget_propname, &value);
w->widget_obj_set_cb(priv->model_obj, w->widget_obj, value, w->widget_propname);
efl_model_property_get(priv->model_obj, w->widget_propname, &promise);
eina_promise_then(promise, (Eina_Promise_Cb)&_efl_promise_then_widget, &_efl_promise_error_widget, w);
}
}
@ -91,7 +139,7 @@ _update_model_properties(Elm_View_Form_Data *priv)
* Works, so far, for widget(s): Entry, Label
*/
static void
_elm_evas_object_text_set_cb(Eo *obj EINA_UNUSED, Evas_Object *widget, const Eina_Value *value, const char *propname EINA_UNUSED)
_elm_evas_object_text_set_cb(Evas_Object *widget, const Eina_Value *value, const char *propname EINA_UNUSED)
{
const char *c_text = NULL;
char *text = NULL;
@ -113,7 +161,7 @@ _elm_evas_object_text_set_cb(Eo *obj EINA_UNUSED, Evas_Object *widget, const Ein
}
static void
_elm_evas_object_thumb_set_cb(Eo *obj EINA_UNUSED, Evas_Object *thumb, const Eina_Value *value, const char *propname EINA_UNUSED)
_elm_evas_object_thumb_set_cb(Evas_Object *thumb, const Eina_Value *value, const char *propname EINA_UNUSED)
{
char *filename = NULL;
@ -141,7 +189,7 @@ _elm_evas_object_text_changed_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o
Elm_View_Form_Data *priv = (Elm_View_Form_Data *)data;
Elm_View_Form_Widget *w = NULL;
EINA_LIST_FOREACH(priv->l, l, w)
EINA_LIST_FOREACH(priv->widgets, l, w)
{
if (w->widget_obj == obj)
break;
@ -150,7 +198,7 @@ _elm_evas_object_text_changed_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o
EINA_SAFETY_ON_NULL_RETURN(w);
eina_value_setup(&value, EINA_VALUE_TYPE_STRING);
eina_value_set(&value, elm_object_text_get(obj));
efl_model_property_set(priv->model_obj, w->widget_propname, &value);
efl_model_property_set(priv->model_obj, w->widget_propname, &value, NULL);
eina_value_flush(&value);
}
/**
@ -161,13 +209,13 @@ _elm_evas_object_text_changed_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o
static Eina_Bool
_elm_view_widget_add(Elm_View_Form_Data *priv, const char *propname, Evas_Object *widget_obj)
{
const Eina_Value *value = NULL;
Eina_Promise *promise = NULL;
Elm_View_Form_Widget *w = calloc(1, sizeof(Elm_View_Form_Widget));
EINA_SAFETY_ON_NULL_RETURN_VAL(w, EINA_FALSE);
w->widget_propname = eina_stringshare_add(propname);
w->widget_obj = widget_obj;
priv->l = eina_list_append(priv->l, w);
priv->widgets = eina_list_append(priv->widgets, w);
if(eo_isa(widget_obj, ELM_ENTRY_CLASS))
{
@ -188,12 +236,12 @@ _elm_view_widget_add(Elm_View_Form_Data *priv, const char *propname, Evas_Object
EINA_SAFETY_ON_NULL_RETURN_VAL(NULL, EINA_FALSE);
}
efl_model_property_get(priv->model_obj, propname, &value);
if (value)
if (priv->model_obj != NULL)
{
w->widget_obj_set_cb(priv->model_obj, w->widget_obj, value, w->widget_propname);
efl_model_property_get(priv->model_obj, w->widget_propname, &promise);
eina_promise_then(promise, (Eina_Promise_Cb)&_efl_promise_then_widget,
&_efl_promise_error_widget, priv);
}
return EINA_TRUE;
}
/**
@ -211,7 +259,7 @@ _elm_view_form_eo_base_constructor(Eo *obj EINA_UNUSED, Elm_View_Form_Data *_pd)
priv->model_obj = NULL;
eo_constructor(eo_super(obj, MY_CLASS));
return obj;
}
@ -222,11 +270,13 @@ static void
_elm_view_form_eo_base_destructor(Eo *obj, Elm_View_Form_Data *priv)
{
Elm_View_Form_Widget *w = NULL;
EINA_LIST_FREE(priv->l, w)
EINA_LIST_FREE(priv->widgets, w)
{
eina_stringshare_del(w->widget_propname);
free(w);
w = NULL;
}
priv->widgets = NULL;
eo_destructor(eo_super(obj, MY_CLASS));
}

View File

@ -17,6 +17,9 @@ typedef struct _Elm_View_List_Data Elm_View_List_Data;
struct _View_List_ItemData;
typedef struct _View_List_ItemData View_List_ItemData;
struct _View_List_ValueItem;
typedef struct _View_List_ValueItem View_List_ValueItem;
struct _Elm_View_List_Data
{
Eo *view;
@ -30,15 +33,21 @@ struct _Elm_View_List_Data
struct _View_List_ItemData
{
Elm_View_List_Data *priv;
Elm_Object_Item *item;
Eo *model;
View_List_ItemData *parent;
Efl_Model_Load_Status status;
Elm_View_List_Data *priv;
Elm_Object_Item *item;
Eo *model;
View_List_ItemData *parent;
Eina_List *values;
};
struct _View_List_ValueItem
{
Eina_Stringshare *part;
Eina_Value *value;
Elm_Object_Item *item;
};
static void _efl_model_load_children(View_List_ItemData *);
static Eina_Bool _efl_model_load_status_change_cb(void *, const Eo_Event *event);
static Eina_Bool _efl_model_children_count_change_cb(void *, const Eo_Event *event);
static Eina_Bool _efl_model_properties_change_cb(void *, const Eo_Event *event);
@ -48,7 +57,6 @@ static Eina_Bool _contracted_cb(void *data EINA_UNUSED, const Eo_Event *event);
/* --- Genlist Callbacks --- */
EO_CALLBACKS_ARRAY_DEFINE(model_callbacks,
{ EFL_MODEL_BASE_EVENT_LOAD_STATUS, _efl_model_load_status_change_cb },
{ EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, _efl_model_children_count_change_cb });
EO_CALLBACKS_ARRAY_DEFINE(genlist_callbacks,
{ ELM_GENLIST_EVENT_EXPAND_REQUEST, _expand_request_cb },
@ -60,7 +68,7 @@ _item_sel_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNU
{
View_List_ItemData *idata = data;
EINA_SAFETY_ON_NULL_RETURN(data);
EINA_SAFETY_ON_NULL_RETURN(idata);
eo_event_callback_call(idata->priv->view, ELM_VIEW_LIST_EVENT_MODEL_SELECTED, idata->model);
}
@ -84,23 +92,96 @@ _item_del(void *data, Evas_Object *obj EINA_UNUSED)
free(idata);
}
static void
_property_get_cb(View_List_ValueItem *vitem, Eina_Value *value)
{
vitem->value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, vitem->value);
if (vitem->item)
elm_genlist_item_update(vitem->item);
}
static void
_property_get_error_cb(View_List_ValueItem *vitem, const Eina_Error *err EINA_UNUSED)
{
eina_stringshare_del(vitem->part);
}
static Eina_Value *
_item_get_value(View_List_ItemData *idata, const char *part)
{
View_List_ValueItem *vitem = NULL;
Eina_Value *value = NULL;
Eina_List *l, *ln;
EINA_LIST_FOREACH_SAFE(idata->values, l, ln, vitem)
{
if (vitem->part == NULL)
{
free(vitem);
unsigned i = eina_list_count(idata->values);
if (i == 1)
{
idata->values = eina_list_remove(idata->values, vitem);
idata->values = NULL;
break;
}
idata->values = eina_list_remove_list(idata->values, l);
continue;
}
if (strcmp(vitem->part, part) == 0)
{
value = vitem->value;
break;
}
}
if (value == NULL)
{
Eina_Promise *promise;
vitem = calloc(1, sizeof(View_List_ItemData));
const char *prop = eina_hash_find(idata->priv->prop_con, part);
if (prop == NULL) prop = part;
vitem->part = eina_stringshare_add(part);
vitem->item = idata->item;
idata->values = eina_list_append(idata->values, vitem);
efl_model_property_get(idata->model, prop, &promise);
eina_promise_then(promise, (Eina_Promise_Cb)&_property_get_cb,
(Eina_Promise_Error_Cb)&_property_get_error_cb, vitem);
}
else
{
unsigned i = eina_list_count(idata->values);
idata->values = eina_list_remove(idata->values, vitem);
if (i == 1) idata->values = NULL;
eina_stringshare_del(vitem->part);
free(vitem);
}
return value;
}
static Evas_Object *
_item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
{
const Eina_Value *value = NULL;
const Eina_Value_Type *vtype;
Evas_Object *content = NULL;
View_List_ItemData *idata = data;
EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
Elm_View_List_Data *priv = idata->priv;
const char *prop = eina_hash_find(priv->prop_con, part);
if (prop == NULL) prop = part;
if (!idata->item)
return NULL;
Eina_Value *value = _item_get_value(idata, part);
efl_model_property_get(idata->model, prop, &value);
if (value == NULL)
return content;
return NULL;
vtype = eina_value_type_get(value);
if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE)
@ -125,12 +206,12 @@ _item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
eina_value_get(value, &out);
if (out.memory != NULL)
{
content = elm_image_add(obj);
//XXX: need copy memory??
elm_image_memfile_set(content, out.memory, out.size, NULL, NULL);
content = elm_image_add(obj);
//XXX: need copy memory??
elm_image_memfile_set(content, out.memory, out.size, NULL, NULL);
}
}
eina_value_flush(value);
return content;
}
@ -138,21 +219,21 @@ _item_content_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
static char *
_item_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
{
const Eina_Value *value = NULL;
char *text = NULL;
View_List_ItemData *idata = data;
EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
Elm_View_List_Data *priv = idata->priv;
EINA_SAFETY_ON_NULL_RETURN_VAL(idata->model, NULL);
if (!idata->item)
return text;
const char *prop = eina_hash_find(priv->prop_con, part);
if (prop == NULL) prop = part;
Eina_Value *value = _item_get_value(idata, part);
efl_model_property_get(idata->model, prop, &value);
if (value)
text = eina_value_to_string(value);
{
text = eina_value_to_string(value);
eina_value_flush(value);
}
return text;
}
@ -162,21 +243,13 @@ _expand_request_cb(void *data EINA_UNUSED, const Eo_Event *event)
{
Elm_Object_Item *item = event->info;
View_List_ItemData *idata = elm_object_item_data_get(item);
Efl_Model_Load_Status st = EFL_MODEL_LOAD_STATUS_ERROR;
EINA_SAFETY_ON_NULL_RETURN_VAL(idata, EINA_TRUE);
st = efl_model_load_status_get(idata->model);
eo_event_callback_array_add(idata->model, model_callbacks(), idata);
if (st & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
{
_efl_model_load_children(idata);
}
else
{
efl_model_children_load(idata->model);
}
_efl_model_load_children(idata);
return EINA_TRUE;
}
@ -212,7 +285,6 @@ _genlist_deleted(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_
}
}
/* --- Efl_Model Callbacks --- */
static Eina_Bool
_efl_model_properties_change_cb(void *data, const Eo_Event *event)
@ -230,42 +302,42 @@ _efl_model_properties_change_cb(void *data, const Eo_Event *event)
}
static void
_efl_model_load_children(View_List_ItemData *pdata)
_efl_model_load_children_then(View_List_ItemData *pdata, Eina_Accessor **accessor)
{
Eo *child;
Eina_Accessor *accessor = NULL;
unsigned i = 0;
EINA_SAFETY_ON_NULL_RETURN(pdata);
EINA_SAFETY_ON_NULL_RETURN(pdata->priv);
EINA_SAFETY_ON_NULL_RETURN(*accessor);
Elm_View_List_Data *priv = pdata->priv;
unsigned int i, total = 0;
efl_model_children_count_get(pdata->model, &total);
if (total == 0)
return;
efl_model_children_slice_get(pdata->model, 0, 0, (Eina_Accessor **)&accessor);
EINA_SAFETY_ON_NULL_RETURN(accessor);
EINA_ACCESSOR_FOREACH(accessor, i, child)
EINA_ACCESSOR_FOREACH(*accessor, i, child)
{
View_List_ItemData *idata = malloc(sizeof(View_List_ItemData));
memset(idata, 0, sizeof(View_List_ItemData));
View_List_ItemData *idata = calloc(1, sizeof(View_List_ItemData));
EINA_SAFETY_ON_NULL_RETURN(idata);
idata->priv = priv;
idata->parent = pdata;
idata->model = child;
eo_ref(child);
eo_event_callback_add(child, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, _efl_model_properties_change_cb, idata);
efl_model_properties_load(child);
idata->item = elm_genlist_item_append(priv->genlist, priv->itc, idata, pdata->item,
priv->itype, _item_sel_cb, idata);
}
if (pdata->item)
if (i > 0 && pdata->item)
elm_genlist_item_expanded_set(pdata->item, EINA_TRUE);
}
static void
_efl_model_load_children(View_List_ItemData *pdata)
{
Eina_Promise *promise;
efl_model_children_slice_get(pdata->model, 0, 0, &promise);
eina_promise_then(promise, (Eina_Promise_Cb)&_efl_model_load_children_then, NULL, pdata);
}
static Eina_Bool
_efl_model_children_count_change_cb(void *data, const Eo_Event *event EINA_UNUSED)
{
@ -281,27 +353,9 @@ _efl_model_children_count_change_cb(void *data, const Eo_Event *event EINA_UNUSE
return EINA_TRUE;
}
static Eina_Bool
_efl_model_load_status_change_cb(void *data, const Eo_Event *event)
{
View_List_ItemData *idata = data;
Efl_Model_Load *load = event->info;
if (load->status & EFL_MODEL_LOAD_STATUS_UNLOADED)
{
if (idata->item)
elm_genlist_item_expanded_set(idata->item, EINA_FALSE);
}
idata->status = load->status;
return EINA_TRUE;
}
static void
_priv_model_set(Elm_View_List_Data *priv, Eo *model)
{
Efl_Model_Load_Status load_st;
if (priv->model != NULL)
{
eo_event_callback_array_del(priv->model, model_callbacks(), priv->rootdata);
@ -318,11 +372,7 @@ _priv_model_set(Elm_View_List_Data *priv, Eo *model)
eo_ref(priv->model);
eo_event_callback_array_add(priv->model, model_callbacks(), priv->rootdata);
load_st = efl_model_load_status_get(priv->model);
if (load_st & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
{
_efl_model_load_children(priv->rootdata);
}
_efl_model_load_children(priv->rootdata);
}
/**
@ -370,11 +420,12 @@ _elm_view_list_eo_base_destructor(Eo *obj, Elm_View_List_Data *priv)
eina_hash_free(priv->prop_con);
free(priv->rootdata);
priv->rootdata = NULL;
if (priv->genlist) {
evas_object_event_callback_del(priv->genlist, EVAS_CALLBACK_DEL, _genlist_deleted);
eo_event_callback_array_del(priv->genlist, genlist_callbacks(), priv);
eo_unref(priv->genlist);
}
if (priv->genlist)
{
evas_object_event_callback_del(priv->genlist, EVAS_CALLBACK_DEL, _genlist_deleted);
eo_event_callback_array_del(priv->genlist, genlist_callbacks(), priv);
eo_unref(priv->genlist);
}
eo_unref(priv->model);

View File

@ -4,15 +4,14 @@
# include <config.h>
#endif
#include <stdio.h>
#include <Eo.h>
#include <Eio.h>
#include <Ecore.h>
#include <Efl.h>
#include <Eio.h>
#include <eio_model.h>
#include <stdio.h>
#include "eio_suite.h"
#include <check.h>
#define EFL_MODEL_TEST_FILENAME_PATH "/tmp"
#define EFL_MODEL_MAX_TEST_CHILDS 16
@ -58,157 +57,95 @@ static Eina_Bool
return ECORE_CALLBACK_CANCEL;
}
static Eina_Bool
_load_status_cb(void *data EINA_UNUSED, const Eo_Event *event)
static void
promise_then_count(Eo* obj EINA_UNUSED, int *total)
{
Efl_Model_Load *st = event->info;
printf("Load CHANGE\n");
if (st->status & EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN)
printf("Children is Loaded\n");
if (st->status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
{
fprintf(stderr, "Properties are Loaded\n"); fflush(stderr);
if(!reqs.properties_loaded)
ecore_main_loop_quit();
reqs.properties_loaded = 1;
}
if ((st->status & EFL_MODEL_LOAD_STATUS_LOADED) == EFL_MODEL_LOAD_STATUS_LOADED)
{
Eina_Accessor *accessor;
const Eina_Value *value_prop;
Efl_Model_Load_Status status;
unsigned int total;
char *str;
printf("Model is Loaded\n");
status = efl_model_property_get(event->obj, "filename", &value_prop);
str = eina_value_to_string(value_prop);
printf("efl_model_loaded filename %s, status=%d\n", str, status);
free(str);
status = efl_model_property_get(event->obj, "size", &value_prop);
str = eina_value_to_string(value_prop);
printf("efl_model_loaded size %s, status=%d\n", str, status);
free(str);
status = efl_model_property_get(event->obj, "mtime", &value_prop);
str = eina_value_to_string(value_prop);
printf("efl_model_loaded mtime %s, status=%d\n", str, status);
free(str);
efl_model_children_count_get(event->obj, &total);
printf("efl_model_test count %d\n", (int)total);
/**< get full list */
status = efl_model_children_slice_get(event->obj, 0, 0, (Eina_Accessor **)&accessor);
eina_accessor_free(accessor);
ecore_main_loop_quit();
}
return EINA_TRUE;
ck_assert_ptr_ne(total, NULL);
printf("efl_model_loaded count %d\n", *total); fflush(stdout);
ecore_main_loop_quit();
}
static Eina_Bool
_properties_change_cb(void *data EINA_UNUSED, const Eo_Event *event)
static void
promise_then_accessor(Eo* obj EINA_UNUSED, Eina_Accessor **accessor)
{
const Efl_Model_Property_Event *evt = (Efl_Model_Property_Event *)event->info;
const char *prop;
Eina_Array_Iterator it;
unsigned int i;
ck_assert_ptr_ne(accessor, NULL);
printf("efl_model_loaded accessor %p\n", *accessor); fflush(stdout);
EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
{
if (!strcmp(prop, "is_dir"))
reqs.changed_is_dir = 1;
else if (!strcmp(prop, "is_lnk"))
reqs.changed_is_lnk = 1;
else if (!strcmp(prop, "size"))
reqs.changed_size = 1;
else if (!strcmp(prop, "mtime"))
reqs.changed_mtime = 1;
}
Eo* child;
int i = 0;
EINA_ACCESSOR_FOREACH(*accessor, i, child)
{
printf("efl_model_loaded child: %d pointer %p\n", i, child);
}
reqs.properties = 1;
return EINA_TRUE;
ecore_main_loop_quit();
}
static Eina_Bool
_children_count_cb(void *data EINA_UNUSED, const Eo_Event *event)
static void
promise_then_value(void *user EINA_UNUSED, Eina_Value *value)
{
unsigned int *len = (unsigned int *)event->info;
unsigned int total;
ck_assert_ptr_ne(value, NULL);
char *str = eina_value_to_string(value);
fprintf(stdout, "Children count number=%d\n", *len);
reqs.children = *len;
ck_assert_ptr_ne(str, NULL);
printf("efl_model_loaded property: %s\n", str);
free(str);
efl_model_children_count_get(event->obj, &total);
fprintf(stdout, "New total children count number=%d\n", *len);
ecore_main_loop_quit();
}
return EINA_TRUE;
static void
error_promise_then(void* data, Eina_Error const* error)
{
ck_abort_msg(0, "Error Promise cb");
ecore_main_loop_quit();
}
START_TEST(eio_model_test_test_file)
{
Eo *filemodel = NULL;
const Eina_Value *value_prop;
Efl_Model_Load_Status status;
Eina_Array *properties_list = NULL;
Eina_Array_Iterator iterator;
char *str;
unsigned int i;
memset(&reqs, 0, sizeof(struct reqs_t));
fail_if(!eina_init(), "ERROR: Cannot init Eina!\n");
fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
fail_if(!eo_init(), "ERROR: Cannot init EO!\n");
fail_if(!eio_init(), "ERROR: Cannot init EIO!\n");
filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, EFL_MODEL_TEST_FILENAME_PATH));
fail_if(!filemodel, "ERROR: Cannot init model!\n");
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _load_status_cb, NULL);
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, _properties_change_cb, NULL);
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, _children_count_cb, NULL);
efl_model_load(filemodel);
handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
Eina_Promise *promise;
efl_model_property_get(filemodel, "filename", &promise);
eina_promise_then(promise, &promise_then_value, &error_promise_then, NULL);
ecore_main_loop_begin();
status = efl_model_property_get(filemodel, "filename", &value_prop);
str = eina_value_to_string(value_prop);
printf("efl_model_test filename %s, load status %d\n", str, status);
efl_model_property_get(filemodel, "size", &promise);
eina_promise_then(promise, &promise_then_value, &error_promise_then, NULL);
ecore_main_loop_begin();
free(str);
efl_model_property_get(filemodel, "mtime", &promise);
eina_promise_then(promise, &promise_then_value, &error_promise_then, NULL);
ecore_main_loop_begin();
i = 0;
efl_model_properties_get(filemodel, &properties_list);
EINA_ARRAY_ITER_NEXT(properties_list, i, str, iterator)
{
fprintf(stdout, "Returned property list %d: %s\n", i, str);
if(!strcmp(str, "filename"))
reqs.proplist_filename = 1;
else if(!strcmp(str, "path"))
reqs.proplist_path = 1;
else if(!strcmp(str, "mtime"))
reqs.proplist_mtime = 1;
else if(!strcmp(str, "is_dir"))
reqs.proplist_is_dir = 1;
else if(!strcmp(str, "is_lnk"))
reqs.proplist_is_lnk = 1;
else if(!strcmp(str, "size"))
reqs.proplist_size = 1;
}
efl_model_children_slice_get(filemodel, 0, 0, &promise);
eina_promise_then(promise, &promise_then_accessor, &error_promise_then, NULL);
ecore_main_loop_begin();
efl_model_children_count_get(filemodel, &promise);
eina_promise_then(promise, &promise_then_count, &error_promise_then, NULL);
ecore_main_loop_begin();
eo_unref(filemodel);
eio_shutdown();
ecore_shutdown();
eina_shutdown();
eio_shutdown();
}
END_TEST
@ -217,3 +154,4 @@ eio_model_test_file(TCase *tc)
{
tcase_add_test(tc, eio_model_test_test_file);
}

View File

@ -4,113 +4,74 @@
# include <config.h>
#endif
#include <stdio.h>
#include <Eo.h>
#include <Eio.h>
#include <Ecore.h>
#include <Efl.h>
#include <Eio.h>
#include <eio_model.h>
#include <stdio.h>
#include "eio_suite.h"
#include <check.h>
Eina_Bool children_added = EINA_FALSE;
Eina_Tmpstr* temp_filename = NULL;
const char* tmpdir = NULL;
Eina_Bool children_deleted = EINA_FALSE;
struct _pair
{
Eo *parent, *child;
};
static Eina_Bool
_load_monitor_status_cb(void *data, const Eo_Event *event)
_children_removed_cb(void *data EINA_UNUSED, const Eo_Event* event)
{
Efl_Model_Load* st = event->info;
Eo* parent = data;
const Eina_Value* value_prop = NULL;
const char* str = NULL;
if (!(st->status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES))
return EINA_TRUE;
efl_model_property_get(event->obj, "path", &value_prop);
fail_if(!value_prop, "ERROR: Cannot get property!\n");
str = eina_value_to_string(value_prop);
fail_if(!str, "ERROR: Cannot convert value to string!\n");
fprintf(stderr, "new children filename %s\n", str);
if(temp_filename && strcmp(str, temp_filename) == 0)
{
fprintf(stderr, "is child that we want\n");
eo_event_callback_del(event->obj, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _load_monitor_status_cb, data);
children_added = EINA_TRUE;
efl_model_child_del(parent, event->obj);
}
return EINA_FALSE;
}
static Eina_Bool
_children_removed_cb(void *data EINA_UNUSED, const Eo_Event *event)
{
if(children_added)
{
Efl_Model_Children_Event* evt = event->info;
Eina_Bool b;
b = efl_model_load_status_get(evt->child);
if(b)
{
const Eina_Value* value_prop = NULL;
const char* str = NULL;
efl_model_property_get(evt->child, "path", &value_prop);
fail_if(!value_prop, "ERROR: Cannot get property!\n");
str = eina_value_to_string(value_prop);
fail_if(!str, "ERROR: Cannot convert value to string!\n");
if(temp_filename && strcmp(str, temp_filename) == 0)
ecore_main_loop_quit();
}
}
return EINA_TRUE;
}
static Eina_Bool
_children_added_cb(void *data EINA_UNUSED, const Eo_Event *event)
{
Efl_Model_Children_Event* evt = event->info;
if (evt == NULL)
return EINA_TRUE;
eo_event_callback_add(evt->child, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _load_monitor_status_cb, event->obj);
efl_model_load(evt->child);
return EINA_TRUE;
}
static Eina_Bool
_children_count_cb(void *data EINA_UNUSED, const Eo_Event *event)
{
unsigned int *len = event->info;
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
Eo *child;
unsigned int i = 0;
int fd = 0;
fprintf(stderr, "Children count number=%d\n", *len);
/**< get full list */
status = efl_model_children_slice_get(event->obj, 0, 0, (Eina_Accessor **)&accessor);
if(accessor != NULL)
fprintf(stderr, __FILE__ ":%d %s\n", __LINE__, __func__);
if(children_deleted)
{
EINA_ACCESSOR_FOREACH(accessor, i, child) {}
fprintf(stdout, "Got %d childs from Accessor. status=%d\n", i, status);
}
Efl_Model_Children_Event* evt = event->info;
Eina_Promise* promise;
efl_model_property_get(evt->child, "path", &promise);
Eina_Value const* value = ecore_promise_value_get(promise);
char* filename = eina_value_to_string(value);
if(temp_filename && !strcmp(filename, temp_filename) == 0)
ecore_main_loop_quit();
free(filename);
}
return EINA_TRUE;
}
static Eina_Bool
_children_added_cb(void *data EINA_UNUSED, const Eo_Event* event)
{
fprintf(stderr, __FILE__ ":%d %s\n", __LINE__, __func__);
Efl_Model_Children_Event* evt = event->info;
Eina_Promise* promise;
efl_model_property_get(evt->child, "path", &promise);
Eina_Value const* value = ecore_promise_value_get(promise);
char* filename = eina_value_to_string(value);
if(temp_filename && !strcmp(temp_filename, filename))
{
children_deleted = EINA_TRUE;
efl_model_child_del(event->obj, evt->child);
}
free(filename);
return EINA_TRUE;
}
static void
_create_file(void *data EINA_UNUSED, void* value EINA_UNUSED)
{
int fd;
if((fd = eina_file_mkstemp("prefixXXXXXX.ext", &temp_filename)) > 0)
{
close(fd);
fprintf(stderr, __FILE__ ":%d %s\n", __LINE__, __func__);
close(fd);
}
return EINA_TRUE;
}
START_TEST(eio_model_test_test_monitor_add)
@ -121,6 +82,7 @@ START_TEST(eio_model_test_test_monitor_add)
fail_if(!eina_init(), "ERROR: Cannot init Eina!\n");
fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
fail_if(!eo_init(), "ERROR: Cannot init EO!\n");
fail_if(!eio_init(), "ERROR: Cannot init EIO!\n");
tmpdir = eina_environment_tmp_get();
@ -128,11 +90,13 @@ START_TEST(eio_model_test_test_monitor_add)
filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, tmpdir));
fail_if(!filemodel, "ERROR: Cannot init model!\n");
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_CHILD_ADDED, _children_added_cb, NULL);
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_CHILD_REMOVED, _children_removed_cb, NULL);
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, _children_count_cb, NULL);
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_CHILD_ADDED, &_children_added_cb, filemodel);
eo_event_callback_add(filemodel, EFL_MODEL_BASE_EVENT_CHILD_REMOVED, &_children_removed_cb, NULL);
efl_model_load(filemodel);
Eina_Promise* promise;
efl_model_children_slice_get(filemodel, 0, 0, &promise);
ecore_promise_then(promise, &_create_file, NULL);
ecore_main_loop_begin();
@ -142,7 +106,7 @@ START_TEST(eio_model_test_test_monitor_add)
ecore_shutdown();
eina_shutdown();
fail_if(!children_added);
fail_if(!children_deleted);
}
END_TEST
@ -151,3 +115,4 @@ eio_model_test_monitor_add(TCase *tc)
{
tcase_add_test(tc, eio_model_test_test_monitor_add);
}

View File

@ -6,13 +6,13 @@
#include "../efl_check.h"
static const Efl_Test_Case etc[] = {
{"Eio_Monitor", eio_test_monitor},
/* {"Eio_Monitor", eio_test_monitor}, */
{"Eio Model", eio_model_test_file},
{"Eio Model Monitor", eio_model_test_monitor_add},
{"Eio File", eio_test_file},
#ifdef XATTR_TEST_DIR
{"Eio_Xattr", eio_test_xattr},
#endif
/* {"Eio Model Monitor", eio_model_test_monitor_add}, */
/* {"Eio File", eio_test_file}, */
/* #ifdef XATTR_TEST_DIR */
/* {"Eio_Xattr", eio_test_xattr}, */
/* #endif */
{NULL, NULL}
};

View File

@ -127,7 +127,6 @@ _fakse_server_property_get(const Eldbus_Service_Interface *iface,
const Eldbus_Message *request_msg EINA_UNUSED,
Eldbus_Message **error EINA_UNUSED)
{
fprintf(stderr, "%s:%d _fake_server_property_get %s\n", __FILE__, __LINE__, propname); fflush(stderr);
Fake_Server_Data *data = eldbus_service_object_data_get(iface, FAKE_SERVER_DATA_KEY);
ck_assert_ptr_ne(NULL, data);

View File

@ -14,6 +14,45 @@
#include "eldbus_test_eldbus_model.h"
#include "eldbus_suite.h"
static void
_promise_then_quit_cb(void **data , void **value )
{
*data = *value;
ecore_main_loop_quit();
}
static void
_promise_then_cp(Eina_Value *data , void *value)
{
eina_value_copy(value, data);
ecore_main_loop_quit();
}
static void
_promise_check_err(void *data EINA_UNUSED, void *value EINA_UNUSED)
{
ck_assert_msg(0, "Promise Expected Error:\n");
ecore_main_loop_quit();
}
static void
_error_then_ok(void* data, Eina_Error const* error)
{
// fprintf(stderr, "Promise ERROR CB: %s\n", eina_error_msg_get(*error));
if (data != NULL)
ck_assert_ptr_ne(error, (Eina_Error*)data);
ecore_main_loop_quit();
}
static void
_error_then_cb(void* data EINA_UNUSED, Eina_Error const* error)
{
ck_assert_msg(0,"Promise ERROR: %s\n", eina_error_msg_get(*error));
ecore_main_loop_quit();
}
static Eina_Bool
_eo_event_quit_cb(void *data EINA_UNUSED, const Eo_Event *event EINA_UNUSED)
{
@ -21,6 +60,31 @@ _eo_event_quit_cb(void *data EINA_UNUSED, const Eo_Event *event EINA_UNUSED)
return EINA_FALSE;
}
void *
efl_model_promise_then(Eina_Promise *promise)
{
void *data = NULL;
eina_promise_then(promise, (Eina_Promise_Cb)&_promise_then_quit_cb, &_error_then_cb, &data);
ecore_main_loop_begin();
return data;
}
void
check_efl_model_promise_error(Eina_Promise *promise, Eina_Error *err)
{
eina_promise_then(promise, &_promise_check_err, &_error_then_ok, err);
ecore_main_loop_begin();
}
int
efl_model_promise_then_u(Eina_Promise *promise)
{
unsigned i = 0;
eina_promise_then(promise, (Eina_Promise_Cb)&_promise_then_quit_cb, &_error_then_cb, &i);
ecore_main_loop_begin();
return i;
}
void
efl_model_wait_for_event(Eo *obj, const Eo_Event_Description* event)
{
@ -29,46 +93,21 @@ efl_model_wait_for_event(Eo *obj, const Eo_Event_Description* event)
eo_event_callback_del(obj, event, _eo_event_quit_cb, NULL);
}
static Eina_Bool
_event_load_status_quit_cb(void *data, const Eo_Event *event)
{
printf("_event_load_status_quit_cb\n");
Efl_Model_Load_Status expected_status = (Efl_Model_Load_Status)data;
Efl_Model_Load *actual_load = (Efl_Model_Load*)event->info;
if (expected_status == actual_load->status)
{
ecore_main_loop_quit();
return EINA_FALSE;
}
return EINA_TRUE;
}
void
efl_model_wait_for_load_status(Efl_Model_Base *efl_model, Efl_Model_Load_Status expected_status)
{
Efl_Model_Load_Status actual_status;
actual_status = efl_model_load_status_get(efl_model);
if (expected_status == actual_status)
return;
eo_event_callback_add(efl_model, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_load_status_quit_cb, (void*)expected_status);
ecore_main_loop_begin();
eo_event_callback_del(efl_model, EFL_MODEL_BASE_EVENT_LOAD_STATUS, _event_load_status_quit_cb, (void*)expected_status);
}
Efl_Model_Base *
efl_model_nth_child_get(Efl_Model_Base *efl_model, unsigned int n)
{
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(efl_model, n, 1, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise;
efl_model_children_slice_get(efl_model, n, 1, &promise);
eina_promise_ref(promise);
ck_assert_ptr_ne(NULL, promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
Eo *child = NULL;
Eina_Bool ret = eina_accessor_data_get(accessor, 0, (void**)&child);
eina_accessor_free(accessor);
eina_promise_unref(promise);
ck_assert(ret);
ck_assert_ptr_ne(NULL, child);
return child;
@ -80,40 +119,31 @@ efl_model_first_child_get(Efl_Model_Base *efl_model)
return efl_model_nth_child_get(efl_model, 1);
}
void
efl_model_load_and_wait_for_load_status(Eo *obj, Efl_Model_Load_Status expected_status)
{
efl_model_load(obj);
efl_model_wait_for_load_status(obj, expected_status);
}
static int expected_ret = 0;
void
check_init(void)
{
ecore_init();
expected_ret = eldbus_init();
ck_assert_int_ge(expected_ret, 1);
int ret = eldbus_init();
ck_assert_int_ge(ret, 1);
}
void
check_shutdown(void)
{
int ret = eldbus_shutdown();
ck_assert_int_eq(ret, expected_ret - 1);
ecore_shutdown();
int ret = eldbus_shutdown();
ck_assert_int_eq(ret, 0);
}
void
check_property(Eo *object, const char *property_name, const char *expected_value)
{
Eina_Value const* property_value;
Efl_Model_Load_Status status;
status = efl_model_property_get(object, property_name, &property_value);
ck_assert_msg(EFL_MODEL_LOAD_STATUS_ERROR != status, "Nonexistent property: %s", property_name);
ck_assert_ptr_ne(NULL, property_value);
char *actual_value = eina_value_to_string(property_value);
Eina_Promise *promise;
efl_model_property_get(object, property_name, &promise);
ck_assert_ptr_ne(NULL, promise);
Eina_Value *value = efl_model_promise_then(promise);
char *actual_value;
eina_value_get(value, &actual_value);
if (!actual_value)
ck_assert_ptr_eq(expected_value, actual_value);
else
@ -132,14 +162,6 @@ create_connection(void)
return connection;
}
Eo *
create_and_load_connection(void)
{
Eo *connection = create_connection();
efl_model_load_and_wait_for_load_status(connection, EFL_MODEL_LOAD_STATUS_LOADED);
return connection;
}
Eo *
create_object(void)
{
@ -148,55 +170,40 @@ create_object(void)
return object;
}
Eo *
create_and_load_object(void)
{
Eo *object = create_object();
efl_model_load_and_wait_for_load_status(object, EFL_MODEL_LOAD_STATUS_LOADED);
return object;
}
void
check_efl_model_load_status_get(Efl_Model_Base *efl_model, Efl_Model_Load_Status expected_load_status)
{
Efl_Model_Load_Status actual_load_status;
actual_load_status = efl_model_load_status_get(efl_model);
ck_assert_int_eq(expected_load_status, actual_load_status);
}
void
check_efl_model_children_count_eq(Efl_Model_Base *efl_model, unsigned int expected_children_count)
{
unsigned int actual_children_count = 0;
efl_model_children_count_get(efl_model, &actual_children_count);
unsigned int actual_children_count;
Eina_Promise *promise;
efl_model_children_count_get(efl_model, &promise);
actual_children_count = efl_model_promise_then_u(promise);
ck_assert_int_eq(expected_children_count, actual_children_count);
}
void
check_efl_model_children_count_ge(Efl_Model_Base *efl_model, unsigned int minimum_children_count)
{
unsigned int actual_children_count = 0;
Efl_Model_Load_Status status;
status = efl_model_children_count_get(efl_model, &actual_children_count);
// A minimum count only exists if model have EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN
ck_assert((EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN & status) == EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
unsigned int actual_children_count;
Eina_Promise *promise;
efl_model_children_count_get(efl_model, &promise);
actual_children_count = efl_model_promise_then_u(promise);
ck_assert_int_ge(actual_children_count, minimum_children_count);
}
void
check_efl_model_children_slice_get(Efl_Model_Base *efl_model)
{
unsigned int count = 0;
Efl_Model_Load_Status status;
status = efl_model_children_count_get(efl_model, &count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
unsigned count;
Eina_Promise *promise;
Eina_Accessor *accessor;
efl_model_children_count_get(efl_model, &promise);
count = efl_model_promise_then_u(promise);
ck_assert_msg(count, "There must be at least 1 child to test");
// Test slice all
Eina_Accessor *accessor;
status = efl_model_children_slice_get(efl_model, 0, 0, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_slice_get(efl_model, 0, 0, &promise);
eina_promise_ref(promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
// Get first child
Eo *first_child = NULL;
@ -213,12 +220,13 @@ check_efl_model_children_slice_get(Efl_Model_Base *efl_model)
ret = eina_accessor_data_get(accessor, count, (void**)&nonexistent_child);
ck_assert(!ret);
ck_assert_ptr_eq(NULL, nonexistent_child);
eina_accessor_free(accessor);
eina_promise_unref(promise);
// Test slice first child
Eo *child = NULL;
status = efl_model_children_slice_get(efl_model, 1, 1, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_slice_get(efl_model, 1, 1, &promise);
eina_promise_ref(promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
ret = eina_accessor_data_get(accessor, 0, (void**)&child);
ck_assert(ret);
@ -226,11 +234,12 @@ check_efl_model_children_slice_get(Efl_Model_Base *efl_model)
ret = eina_accessor_data_get(accessor, 1, (void**)&child);
ck_assert(!ret);
ck_assert_ptr_eq(first_child, child);
eina_accessor_free(accessor);
eina_promise_unref(promise);
// Test slice last child
status = efl_model_children_slice_get(efl_model, count, 1, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_slice_get(efl_model, count, 1, &promise);
eina_promise_ref(promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
ret = eina_accessor_data_get(accessor, 0, (void**)&child);
ck_assert(ret);
@ -238,19 +247,22 @@ check_efl_model_children_slice_get(Efl_Model_Base *efl_model)
ret = eina_accessor_data_get(accessor, 1, (void**)&child);
ck_assert(!ret);
ck_assert_ptr_eq(last_child, child);
eina_accessor_free(accessor);
eina_promise_unref(promise);
// Test slice nonexistent element
status = efl_model_children_slice_get(efl_model, count + 1, 1, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_slice_get(efl_model, count + 1, 1, &promise);
eina_promise_ref(promise);
ck_assert_ptr_ne(NULL, promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_eq(NULL, accessor);
eina_promise_unref(promise);
}
START_TEST(smoke)
{
check_init();
Eo *connection = create_and_load_connection();
Eo *connection = create_connection();
eo_unref(connection);
check_shutdown();
@ -263,8 +275,6 @@ START_TEST(object)
Eo *root = create_object();
efl_model_load_and_wait_for_load_status(root, EFL_MODEL_LOAD_STATUS_LOADED);
eo_unref(root);
check_shutdown();
@ -277,19 +287,23 @@ START_TEST(proxy)
Eo *root = create_object();
efl_model_load_and_wait_for_load_status(root, EFL_MODEL_LOAD_STATUS_LOADED);
Eina_Accessor *accessor = NULL;
efl_model_children_slice_get(root, 0, 0, &accessor);
Eina_Promise *promise = NULL;
efl_model_children_slice_get(root, 0, 0, &promise);
eina_promise_ref(promise);
ck_assert_ptr_ne(NULL, promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
unsigned int i;
Eo *proxy;
EINA_ACCESSOR_FOREACH(accessor, i, proxy)
{
efl_model_load_and_wait_for_load_status(proxy, EFL_MODEL_LOAD_STATUS_LOADED);
ck_assert_ptr_ne(NULL, proxy);
//efl_model_load_and_wait_for_load_status(proxy, EFL_MODEL_LOAD_STATUS_LOADED);
}
eina_accessor_free(accessor);
eina_promise_unref(promise);
eo_unref(root);
@ -309,9 +323,11 @@ Eldbus_Model_Proxy *
eldbus_model_proxy_from_object_get(Eldbus_Model_Object *object, const char *interface_name)
{
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(object, 0, 0, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise = NULL;
efl_model_children_slice_get(object, 0, 0, &promise);
ck_assert_ptr_ne(NULL, promise);
eina_promise_ref(promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
Eo *proxy = NULL;
@ -327,7 +343,7 @@ eldbus_model_proxy_from_object_get(Eldbus_Model_Object *object, const char *inte
proxy = NULL;
end:
eina_accessor_free(accessor);
eina_promise_unref(promise);
return proxy;
}
@ -335,9 +351,11 @@ static Eldbus_Model_Arguments *
_eldbus_model_arguments_from_proxy_get(Eldbus_Model_Proxy *proxy, const char *method_name, const Eo_Class *klass)
{
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(proxy, 0, 0, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise = NULL;
efl_model_children_slice_get(proxy, 0, 0, &promise);
ck_assert_ptr_ne(NULL, promise);
eina_promise_ref(promise);
accessor = efl_model_promise_then(promise);
ck_assert_ptr_ne(NULL, accessor);
Eo *child = NULL;
@ -356,7 +374,7 @@ _eldbus_model_arguments_from_proxy_get(Eldbus_Model_Proxy *proxy, const char *me
child = NULL;
end:
eina_accessor_free(accessor);
eina_promise_unref(promise);
return child;
}
@ -375,29 +393,42 @@ eldbus_model_signal_from_proxy_get(Eldbus_Model_Proxy *proxy, const char *signal
void
check_efl_model_property_int_eq(Efl_Model_Base *efl_model, const char *property, int expected_value)
{
Eina_Value const* property_value;
Efl_Model_Load_Status status;
status = efl_model_property_get(efl_model, property, &property_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
ck_assert_ptr_ne(NULL, property_value);
Eina_Value property_value;
Eina_Promise *promise;
efl_model_property_get(efl_model, property, &promise);
ck_assert_ptr_ne(NULL, promise);
const Eina_Value_Type *property_type = eina_value_type_get(property_value);
eina_promise_then(promise, (Eina_Promise_Cb)&_promise_then_cp, &_error_then_cb, &property_value);
ecore_main_loop_begin();
const Eina_Value_Type *property_type = eina_value_type_get(&property_value);
ck_assert_ptr_eq(EINA_VALUE_TYPE_INT, property_type);
int actual_value = 0;
eina_value_get(property_value, &actual_value);
eina_value_get(&property_value, &actual_value);
ck_assert_int_eq(expected_value, actual_value);
eina_value_flush(&property_value);
}
void
check_efl_model_property_int_set(Efl_Model_Base *efl_model, const char *property, int value)
{
Eina_Value eina_value;
Eina_Value eina_value, value_ret;
Eina_Promise *promise;
eina_value_setup(&eina_value, EINA_VALUE_TYPE_INT);
eina_value_set(&eina_value, value);
Efl_Model_Load_Status status;
status = efl_model_property_set(efl_model, property, &eina_value);
efl_model_property_set(efl_model, property, &eina_value, &promise);
eina_promise_then(promise, (Eina_Promise_Cb)&_promise_then_cp, &_error_then_cb, &value_ret);
ecore_main_loop_begin();
const Eina_Value_Type *property_type = eina_value_type_get(&value_ret);
ck_assert_ptr_eq(EINA_VALUE_TYPE_INT, property_type);
int actual_value;
eina_value_get(&value_ret, &actual_value);
ck_assert_int_eq(value, actual_value);
eina_value_flush(&eina_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
}

View File

@ -8,22 +8,22 @@
void check_init(void);
void check_shutdown(void);
Eo *create_connection(void);
Eo *create_and_load_connection(void);
Eo *create_object(void);
Eo *create_and_load_object(void);
void efl_model_wait_for_event(Eo *obj, const Eo_Event_Description *event);
void efl_model_wait_for_load_status(Eo *obj, Efl_Model_Load_Status expected_status);
void efl_model_load_and_wait_for_load_status(Eo *obj, Efl_Model_Load_Status expected_status);
Efl_Model_Base *efl_model_nth_child_get(Efl_Model_Base *obj, unsigned int n);
Efl_Model_Base *efl_model_first_child_get(Efl_Model_Base *efl_model);
void check_efl_model_load_status_get(Efl_Model_Base *obj, Efl_Model_Load_Status expected_load_status);
void check_efl_model_children_count_eq(Efl_Model_Base *obj, unsigned int expected_children_count);
void check_efl_model_children_count_ge(Efl_Model_Base *obj, unsigned int minimum_children_count);
void check_efl_model_children_slice_get(Efl_Model_Base *efl_model);
void check_efl_model_property_int_eq(Efl_Model_Base *obj, const char *property, int expected_value);
void check_efl_model_property_int_set(Efl_Model_Base *obj, const char *property, int value);
void check_efl_model_promise_error(Eina_Promise *promise, Eina_Error *err);
void *efl_model_promise_then(Eina_Promise *promise);
int efl_model_promise_then_u(Eina_Promise *promise);
Eldbus_Model_Proxy *eldbus_model_proxy_from_object_get(Eldbus_Model_Object *object, const char *interface_name);
Eldbus_Model_Method *eldbus_model_method_from_proxy_get(Eldbus_Model_Proxy *proxy, const char *method_name);

View File

@ -12,7 +12,6 @@
#include "eldbus_suite.h"
static Eo *connection = NULL;
static Eo *unloaded_connection = NULL;
#define UNIQUE_NAME_PROPERTY "unique_name"
@ -20,83 +19,58 @@ static void
_setup(void)
{
check_init();
connection = create_and_load_connection();
unloaded_connection = create_connection();
connection = create_connection();
}
static void
_teardown(void)
{
eo_unref(unloaded_connection);
eo_unref(connection);
check_shutdown();
}
START_TEST(load_status_get)
{
check_efl_model_load_status_get(connection, EFL_MODEL_LOAD_STATUS_LOADED);
check_efl_model_load_status_get(unloaded_connection, EFL_MODEL_LOAD_STATUS_UNLOADED);
}
END_TEST
START_TEST(properties_get)
{
Eina_Array *properties = NULL;
Efl_Model_Load_Status status;
status = efl_model_properties_get(connection, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
const Eina_Array *properties = NULL;
properties = efl_model_properties_get(connection);
ck_assert_ptr_ne(NULL, properties);
const unsigned int expected_properties_count = 1;
unsigned int actual_properties_count = eina_array_count(properties);
ck_assert_int_eq(expected_properties_count, actual_properties_count);
// Unloaded connection populates its properties
status = efl_model_properties_get(unloaded_connection, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_UNLOADED, status);
ck_assert_ptr_ne(NULL, properties);
actual_properties_count = eina_array_count(properties);
ck_assert_int_eq(expected_properties_count, actual_properties_count);
}
END_TEST
START_TEST(property_get)
{
Eina_Value const* property_value;
Efl_Model_Load_Status status;
status = efl_model_property_get(connection, UNIQUE_NAME_PROPERTY, &property_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
ck_assert_ptr_ne(NULL, property_value);
Eina_Promise *promise;
efl_model_property_get(connection, UNIQUE_NAME_PROPERTY, &promise);
efl_model_promise_then(promise);
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
status = efl_model_property_get(connection, "nonexistent", &property_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
// Nonexistent property must raise ERROR
promise = NULL;
efl_model_property_get(connection, "nonexistent", &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
}
END_TEST
START_TEST(property_set)
{
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
Eina_Value value;
Eina_Promise *promise;
// Nonexistent property must raise ERROR
eina_value_setup(&value, EINA_VALUE_TYPE_INT);
eina_value_set(&value, 1);
Efl_Model_Load_Status status;
status = efl_model_property_set(connection, "nonexistent", &value);
eina_value_flush(&value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_property_set(connection, "nonexistent", &value, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
// UNIQUE_NAME_PROPERTY is read-only
status = efl_model_property_set(connection, UNIQUE_NAME_PROPERTY, &value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
promise = NULL;
efl_model_property_set(connection, UNIQUE_NAME_PROPERTY, &value, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_READ_ONLY);
// The model must be loaded to be able to set its properties
const char *expected_value = "unloaded";
eina_value_setup(&value, EINA_VALUE_TYPE_STRING);
eina_value_set(&value, expected_value);
status = efl_model_property_set(unloaded_connection, UNIQUE_NAME_PROPERTY, &value);
eina_value_flush(&value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
}
END_TEST
@ -116,44 +90,6 @@ END_TEST
START_TEST(children_slice_get)
{
check_efl_model_children_slice_get(connection);
// Unloaded connection must return EFL_MODEL_LOAD_STATUS_UNLOADED
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(unloaded_connection, 0, 0, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_UNLOADED, status);
ck_assert_ptr_eq(NULL, accessor);
}
END_TEST
START_TEST(unload)
{
check_efl_model_load_status_get(connection, EFL_MODEL_LOAD_STATUS_LOADED);
efl_model_unload(connection);
check_efl_model_load_status_get(connection, EFL_MODEL_LOAD_STATUS_UNLOADED);
check_efl_model_children_count_eq(connection, 0);
}
END_TEST
START_TEST(properties_load)
{
efl_model_properties_load(unloaded_connection);
check_efl_model_load_status_get(unloaded_connection, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
END_TEST
START_TEST(children_load)
{
efl_model_children_load(unloaded_connection);
check_efl_model_load_status_get(unloaded_connection, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
efl_model_wait_for_load_status(unloaded_connection, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
check_efl_model_load_status_get(unloaded_connection, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
_test_children_count(unloaded_connection);
}
END_TEST
@ -168,17 +104,17 @@ END_TEST
START_TEST(child_del)
{
unsigned int expected_children_count = 0;
Efl_Model_Load_Status status;
status = efl_model_children_count_get(connection, &expected_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise;
efl_model_children_count_get(connection, &promise);
ck_assert_ptr_ne(NULL, promise);
expected_children_count = efl_model_promise_then_u(promise);
Eo *child = efl_model_first_child_get(connection);
status = efl_model_child_del(connection, child);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_child_del(connection, child);
unsigned int actual_children_count = 0;
status = efl_model_children_count_get(connection, &actual_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_count_get(connection, &promise);
actual_children_count = efl_model_promise_then_u(promise);
ck_assert_int_le(expected_children_count, actual_children_count);
}
@ -187,15 +123,11 @@ END_TEST
void eldbus_test_eldbus_model_connection(TCase *tc)
{
tcase_add_checked_fixture(tc, _setup, _teardown);
tcase_add_test(tc, load_status_get);
tcase_add_test(tc, properties_get);
tcase_add_test(tc, property_get);
tcase_add_test(tc, property_set);
tcase_add_test(tc, children_count);
tcase_add_test(tc, children_slice_get);
tcase_add_test(tc, unload);
tcase_add_test(tc, properties_load);
tcase_add_test(tc, children_load);
tcase_add_test(tc, child_add);
tcase_add_test(tc, child_del);
}

View File

@ -32,17 +32,11 @@ _setup(void)
fake_server_object = eo_add(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(eo_self, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, FAKE_SERVER_BUS, FAKE_SERVER_PATH));
ck_assert_ptr_ne(NULL, fake_server_object);
efl_model_load_and_wait_for_load_status(fake_server_object, EFL_MODEL_LOAD_STATUS_LOADED);
fake_server_proxy = eldbus_model_proxy_from_object_get(fake_server_object, FAKE_SERVER_INTERFACE);
ck_assert_ptr_ne(NULL, fake_server_proxy);
efl_model_load_and_wait_for_load_status(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
method = eldbus_model_method_from_proxy_get(fake_server_proxy, FAKE_SERVER_SUM_METHOD_NAME);
ck_assert_ptr_ne(NULL, method);
efl_model_load_and_wait_for_load_status(method, EFL_MODEL_LOAD_STATUS_LOADED);
}
static void
@ -55,18 +49,10 @@ _teardown(void)
check_shutdown();
}
START_TEST(load_status_get)
{
check_efl_model_load_status_get(method, EFL_MODEL_LOAD_STATUS_LOADED);
}
END_TEST
START_TEST(properties_get)
{
Eina_Array *properties = NULL;
Efl_Model_Load_Status status;
status = efl_model_properties_get(method, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
const Eina_Array *properties = NULL;
properties = efl_model_properties_get(method);
ck_assert_ptr_ne(NULL, properties);
const unsigned int expected_properties_count = 3; // a, b and result arguments of 'sum' method
@ -78,27 +64,26 @@ END_TEST
START_TEST(property_get)
{
// Input only property returns error
Eina_Value const* dummy;
Efl_Model_Load_Status status;
status = efl_model_property_get(method, ARGUMENT_A, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
Eina_Promise *promise;
efl_model_property_get(method, ARGUMENT_A, &promise);
check_efl_model_promise_error(promise, NULL);
status = efl_model_property_get(method, ARGUMENT_RESULT, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_property_get(method, ARGUMENT_RESULT, &promise);
efl_model_promise_then(promise);
// Nonexistent property returns error
status = efl_model_property_get(method, "nonexistent", &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_property_get(method, "nonexistent", &promise);
check_efl_model_promise_error(promise, NULL);
}
END_TEST
START_TEST(property_set)
{
// Output argument returns error
Eina_Promise *promise;
Eina_Value dummy = {0};
Efl_Model_Load_Status status;
status = efl_model_property_set(method, ARGUMENT_RESULT, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_property_set(method, ARGUMENT_RESULT, &dummy, &promise);
check_efl_model_promise_error(promise, NULL);
}
END_TEST
@ -116,51 +101,9 @@ END_TEST
START_TEST(children_slice_get)
{
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(method, 1, 1, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
ck_assert_ptr_eq(NULL, accessor);
}
END_TEST
static void
_check_unload(void)
{
check_efl_model_load_status_get(method, EFL_MODEL_LOAD_STATUS_LOADED);
efl_model_unload(method);
check_efl_model_load_status_get(method, EFL_MODEL_LOAD_STATUS_UNLOADED);
check_efl_model_children_count_eq(method, 0);
}
START_TEST(unload)
{
_check_unload();
}
END_TEST
START_TEST(properties_load)
{
_check_unload();
efl_model_properties_load(method);
efl_model_wait_for_load_status(method, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
check_efl_model_load_status_get(method, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
END_TEST
START_TEST(children_load)
{
_check_unload();
efl_model_children_load(method);
efl_model_wait_for_load_status(method, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
check_efl_model_load_status_get(method, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
_test_method_children_count(method);
Eina_Promise *promise;
efl_model_children_slice_get(method, 1, 1, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_SUPPORTED);
}
END_TEST
@ -176,9 +119,8 @@ START_TEST(child_del)
{
// efl_model_child_del always returns ERROR
Eo *child = NULL;
Efl_Model_Load_Status status;
status = efl_model_child_del(method, child);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_child_del(method, child);
//ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
}
END_TEST
@ -187,12 +129,9 @@ START_TEST(call)
check_efl_model_property_int_set(method, ARGUMENT_A, 12345678);
check_efl_model_property_int_set(method, ARGUMENT_B, 87654321);
Efl_Model_Load_Status status;
status = eldbus_model_method_call(method);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
eldbus_model_method_call(method);
efl_model_wait_for_event(method, ELDBUS_MODEL_METHOD_EVENT_SUCCESSFUL_CALL);
check_efl_model_property_int_eq(method, ARGUMENT_RESULT, 99999999);
}
END_TEST
@ -200,15 +139,11 @@ END_TEST
void eldbus_test_eldbus_model_method(TCase *tc)
{
tcase_add_checked_fixture(tc, _setup, _teardown);
tcase_add_test(tc, load_status_get);
tcase_add_test(tc, properties_get);
tcase_add_test(tc, property_get);
tcase_add_test(tc, property_set);
tcase_add_test(tc, children_count);
tcase_add_test(tc, children_slice_get);
tcase_add_test(tc, unload);
tcase_add_test(tc, properties_load);
tcase_add_test(tc, children_load);
tcase_add_test(tc, child_add);
tcase_add_test(tc, child_del);
tcase_add_test(tc, call);

View File

@ -12,7 +12,6 @@
#include "eldbus_suite.h"
static Eo *object = NULL;
static Eo *unloaded_object = NULL;
#define UNIQUE_NAME_PROPERTY "unique_name"
@ -20,82 +19,58 @@ static void
_setup(void)
{
check_init();
object = create_and_load_object();
unloaded_object = create_object();
object = create_object();
}
static void
_teardown(void)
{
eo_unref(unloaded_object);
eo_unref(object);
check_shutdown();
}
START_TEST(load_status_get)
{
check_efl_model_load_status_get(object, EFL_MODEL_LOAD_STATUS_LOADED);
check_efl_model_load_status_get(unloaded_object, EFL_MODEL_LOAD_STATUS_UNLOADED);
}
END_TEST
START_TEST(properties_get)
{
Eina_Array *properties = NULL;
Efl_Model_Load_Status status;
status = efl_model_properties_get(object, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
const Eina_Array *properties = NULL;
properties = efl_model_properties_get(object);
ck_assert_ptr_ne(NULL, properties);
const unsigned int expected_properties_count = 1;
unsigned int actual_properties_count = eina_array_count(properties);
ck_assert_int_eq(expected_properties_count, actual_properties_count);
// Unloaded object populates its properties
status = efl_model_properties_get(unloaded_object, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_UNLOADED, status);
ck_assert_ptr_ne(NULL, properties);
actual_properties_count = eina_array_count(properties);
ck_assert_int_eq(expected_properties_count, actual_properties_count);
}
END_TEST
START_TEST(property_get)
{
const Eina_Value* property_value;
Efl_Model_Load_Status status;
status = efl_model_property_get(object, UNIQUE_NAME_PROPERTY, &property_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise;
efl_model_property_get(object, UNIQUE_NAME_PROPERTY, &promise);
efl_model_promise_then(promise);
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
status = efl_model_property_get(object, "nonexistent", &property_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
// Nonexistent property must raise ERROR
promise = NULL;
efl_model_property_get(object, "nonexistent", &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
}
END_TEST
START_TEST(property_set)
{
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
Eina_Value value;
Eina_Promise *promise;
// Nonexistent property must raise ERROR
eina_value_setup(&value, EINA_VALUE_TYPE_INT);
eina_value_set(&value, 1);
Efl_Model_Load_Status status;
status = efl_model_property_set(object, "nonexistent", &value);
eina_value_flush(&value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_property_set(object, "nonexistent", &value, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
// UNIQUE_NAME_PROPERTY is read-only
status = efl_model_property_set(object, UNIQUE_NAME_PROPERTY, &value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
promise = NULL;
efl_model_property_set(object, UNIQUE_NAME_PROPERTY, &value, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_READ_ONLY);
// The model must be loaded to be able to set its properties
const char *expected_value = "unloaded";
eina_value_setup(&value, EINA_VALUE_TYPE_STRING);
eina_value_set(&value, expected_value);
status = efl_model_property_set(unloaded_object, UNIQUE_NAME_PROPERTY, &value);
eina_value_flush(&value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
}
END_TEST
@ -115,44 +90,6 @@ END_TEST
START_TEST(children_slice_get)
{
check_efl_model_children_slice_get(object);
// Unloaded object must return EFL_MODEL_LOAD_STATUS_UNLOADED
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(unloaded_object, 0, 0, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_UNLOADED, status);
ck_assert_ptr_eq(NULL, accessor);
}
END_TEST
START_TEST(unload)
{
check_efl_model_load_status_get(object, EFL_MODEL_LOAD_STATUS_LOADED);
efl_model_unload(object);
check_efl_model_load_status_get(object, EFL_MODEL_LOAD_STATUS_UNLOADED);
check_efl_model_children_count_eq(object, 0);
}
END_TEST
START_TEST(properties_load)
{
efl_model_properties_load(unloaded_object);
check_efl_model_load_status_get(unloaded_object, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
END_TEST
START_TEST(children_load)
{
efl_model_children_load(unloaded_object);
check_efl_model_load_status_get(unloaded_object, EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN);
efl_model_wait_for_load_status(unloaded_object, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
check_efl_model_load_status_get(unloaded_object, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
_test_children_count(unloaded_object);
}
END_TEST
@ -167,18 +104,20 @@ END_TEST
START_TEST(child_del)
{
unsigned int expected_children_count = 0;
Efl_Model_Load_Status status;
status = efl_model_children_count_get(object, &expected_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise;
efl_model_children_count_get(object, &promise);
ck_assert_ptr_ne(NULL, promise);
expected_children_count = efl_model_promise_then_u(promise);
ck_assert_msg(expected_children_count, "There must be at least 1 child to test");
Eo *child = efl_model_first_child_get(object);
status = efl_model_child_del(object, child);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_child_del(object, child);
promise = NULL;
unsigned int actual_children_count = 0;
status = efl_model_children_count_get(object, &actual_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_count_get(object, &promise);
ck_assert_ptr_ne(NULL, promise);
actual_children_count = efl_model_promise_then_u(promise);
ck_assert_int_le(expected_children_count, actual_children_count);
}
END_TEST
@ -186,15 +125,11 @@ END_TEST
void eldbus_test_eldbus_model_object(TCase *tc)
{
tcase_add_checked_fixture(tc, _setup, _teardown);
tcase_add_test(tc, load_status_get);
tcase_add_test(tc, properties_get);
tcase_add_test(tc, property_get);
tcase_add_test(tc, property_set);
tcase_add_test(tc, children_count);
tcase_add_test(tc, children_slice_get);
tcase_add_test(tc, unload);
tcase_add_test(tc, properties_load);
tcase_add_test(tc, children_load);
tcase_add_test(tc, child_add);
tcase_add_test(tc, child_del);
}

View File

@ -12,76 +12,55 @@
#include "eldbus_suite.h"
static Eo *dbus_object1 = NULL;
static Eo *dbus_object2 = NULL;
static Eo *dbus_proxy = NULL;
static Eo *unloaded_dbus_proxy = NULL;
static void
_setup(void)
{
check_init();
dbus_object1 = create_and_load_object();
dbus_object2 = create_and_load_object();
dbus_object1 = create_object();
dbus_proxy = eldbus_model_proxy_from_object_get(dbus_object1, ELDBUS_FDO_INTERFACE);
ck_assert_ptr_ne(NULL, dbus_proxy);
efl_model_load_and_wait_for_load_status(dbus_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
unloaded_dbus_proxy = eldbus_model_proxy_from_object_get(dbus_object2, ELDBUS_FDO_INTERFACE);
ck_assert_ptr_ne(NULL, dbus_proxy);
}
static void
_teardown(void)
{
eo_unref(dbus_object2);
eo_unref(dbus_object1);
check_shutdown();
}
START_TEST(load_status_get)
{
check_efl_model_load_status_get(dbus_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
check_efl_model_load_status_get(unloaded_dbus_proxy, EFL_MODEL_LOAD_STATUS_UNLOADED);
}
END_TEST
START_TEST(properties_get)
{
const Eina_Array *properties = NULL;
// ELDBUS_FDO_INTERFACE have no properties
Eina_Array *properties = NULL;
Efl_Model_Load_Status status;
status = efl_model_properties_get(dbus_proxy, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
properties = efl_model_properties_get(dbus_proxy);
ck_assert_ptr_ne(NULL, properties);
ck_assert_int_eq(0, eina_array_count(properties));
// Must be loaded to get the properties
status = efl_model_properties_get(unloaded_dbus_proxy, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
}
END_TEST
START_TEST(property_get)
{
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
const Eina_Value* property_value;
Efl_Model_Load_Status status;
status = efl_model_property_get(dbus_proxy, "nonexistent", &property_value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
// Nonexistent property must return ERROR
Eina_Promise *promise;
efl_model_property_get(dbus_proxy, "nonexistent", &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
}
END_TEST
START_TEST(property_set)
{
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
Eina_Value value;
Eina_Promise *promise;
// Nonexistent property must return ERROR
eina_value_setup(&value, EINA_VALUE_TYPE_INT);
eina_value_set(&value, 1);
Efl_Model_Load_Status status;
status = efl_model_property_set(dbus_proxy, "nonexistent", &value);
efl_model_property_set(dbus_proxy, "nonexistent", &value, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
eina_value_flush(&value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
}
END_TEST
@ -101,42 +80,6 @@ END_TEST
START_TEST(children_slice_get)
{
check_efl_model_children_slice_get(dbus_proxy);
// Unloaded dbus_proxy must return EFL_MODEL_LOAD_STATUS_UNLOADED
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(unloaded_dbus_proxy, 0, 0, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_UNLOADED, status);
ck_assert_ptr_eq(NULL, accessor);
}
END_TEST
START_TEST(unload)
{
check_efl_model_load_status_get(dbus_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
efl_model_unload(dbus_proxy);
check_efl_model_load_status_get(dbus_proxy, EFL_MODEL_LOAD_STATUS_UNLOADED);
check_efl_model_children_count_eq(dbus_proxy, 0);
}
END_TEST
START_TEST(properties_load)
{
efl_model_properties_load(unloaded_dbus_proxy);
check_efl_model_load_status_get(unloaded_dbus_proxy, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
END_TEST
START_TEST(children_load)
{
efl_model_children_load(unloaded_dbus_proxy);
efl_model_wait_for_load_status(unloaded_dbus_proxy, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
check_efl_model_load_status_get(unloaded_dbus_proxy, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
_test_dbus_proxy_children_count(unloaded_dbus_proxy);
}
END_TEST
@ -151,17 +94,17 @@ END_TEST
START_TEST(child_del)
{
unsigned int expected_children_count = 0;
Efl_Model_Load_Status status;
status = efl_model_children_count_get(dbus_proxy, &expected_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
Eina_Promise *promise;
efl_model_children_count_get(dbus_proxy, &promise);
ck_assert_ptr_ne(NULL, promise);
expected_children_count = efl_model_promise_then_u(promise);
Eo *child = efl_model_first_child_get(dbus_proxy);
status = efl_model_child_del(dbus_proxy, child);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_child_del(dbus_proxy, child);
unsigned int actual_children_count = 0;
status = efl_model_children_count_get(dbus_proxy, &actual_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_count_get(dbus_proxy, &promise);
actual_children_count = efl_model_promise_then_u(promise);
ck_assert_int_le(expected_children_count, actual_children_count);
}
@ -170,15 +113,11 @@ END_TEST
void eldbus_test_eldbus_model_proxy(TCase *tc)
{
tcase_add_checked_fixture(tc, _setup, _teardown);
tcase_add_test(tc, load_status_get);
tcase_add_test(tc, properties_get);
tcase_add_test(tc, property_get);
tcase_add_test(tc, property_set);
tcase_add_test(tc, children_count);
tcase_add_test(tc, children_slice_get);
tcase_add_test(tc, unload);
tcase_add_test(tc, properties_load);
tcase_add_test(tc, children_load);
tcase_add_test(tc, child_add);
tcase_add_test(tc, child_del);
}

View File

@ -30,17 +30,11 @@ _setup(void)
fake_server_object = eo_add(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(eo_self, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, FAKE_SERVER_BUS, FAKE_SERVER_PATH));
ck_assert_ptr_ne(NULL, fake_server_object);
efl_model_load_and_wait_for_load_status(fake_server_object, EFL_MODEL_LOAD_STATUS_LOADED);
fake_server_proxy = eldbus_model_proxy_from_object_get(fake_server_object, FAKE_SERVER_INTERFACE);
ck_assert_ptr_ne(NULL, fake_server_proxy);
efl_model_load_and_wait_for_load_status(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
pong_signal = eldbus_model_signal_from_proxy_get(fake_server_proxy, FAKE_SERVER_PONG_SIGNAL_NAME);
ck_assert_ptr_ne(NULL, pong_signal);
efl_model_load_and_wait_for_load_status(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED);
}
static void
@ -53,18 +47,10 @@ _teardown(void)
check_shutdown();
}
START_TEST(load_status_get)
{
check_efl_model_load_status_get(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED);
}
END_TEST
START_TEST(properties_get)
{
Eina_Array *properties = NULL;
Efl_Model_Load_Status status;
status = efl_model_properties_get(pong_signal, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
const Eina_Array *properties = NULL;
properties = efl_model_properties_get(pong_signal);
ck_assert_ptr_ne(NULL, properties);
const unsigned int expected_properties_count = 1; // 'response' only
@ -76,25 +62,23 @@ END_TEST
START_TEST(property_get)
{
// Signal properties always have output direction
Eina_Value const* dummy;
Efl_Model_Load_Status status;
status = efl_model_property_get(pong_signal, ARGUMENT_A, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
ck_assert_ptr_ne(NULL, dummy);
Eina_Promise *promise;
efl_model_property_get(pong_signal, ARGUMENT_A, &promise);
efl_model_promise_then(promise);
// Nonexistent property must return EFL_MODEL_LOAD_STATUS_ERROR
status = efl_model_property_get(pong_signal, "nonexistent", &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
// Nonexistent property must return ERROR
efl_model_property_get(pong_signal, "nonexistent", &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_FOUND);
}
END_TEST
START_TEST(property_set)
{
// Signals have output arguments only. All returns error
Eina_Promise *promise;
Eina_Value dummy = {0};
Efl_Model_Load_Status status;
status = efl_model_property_set(pong_signal, ARGUMENT_A, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_property_set(pong_signal, ARGUMENT_A, &dummy, &promise);
check_efl_model_promise_error(promise, NULL);
}
END_TEST
@ -112,51 +96,9 @@ END_TEST
START_TEST(children_slice_get)
{
Eina_Accessor *accessor;
Efl_Model_Load_Status status;
status = efl_model_children_slice_get(pong_signal, 1, 1, &accessor);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
ck_assert_ptr_eq(NULL, accessor);
}
END_TEST
static void
_check_unload(void)
{
check_efl_model_load_status_get(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED);
efl_model_unload(pong_signal);
check_efl_model_load_status_get(pong_signal, EFL_MODEL_LOAD_STATUS_UNLOADED);
check_efl_model_children_count_eq(pong_signal, 0);
}
START_TEST(unload)
{
_check_unload();
}
END_TEST
START_TEST(properties_load)
{
_check_unload();
efl_model_properties_load(pong_signal);
efl_model_wait_for_load_status(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
check_efl_model_load_status_get(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
}
END_TEST
START_TEST(children_load)
{
_check_unload();
efl_model_children_load(pong_signal);
efl_model_wait_for_load_status(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
check_efl_model_load_status_get(pong_signal, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
_test_signal_children_count(pong_signal);
Eina_Promise *promise;
efl_model_children_slice_get(pong_signal, 1, 1, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_NOT_SUPPORTED);
}
END_TEST
@ -170,11 +112,9 @@ END_TEST
START_TEST(child_del)
{
// efl_model_child_del always returns ERROR
// efl_model_child_del always returns ERROR FIXME catch error
Eo *child = NULL;
Efl_Model_Load_Status status;
status = efl_model_child_del(pong_signal, child);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_child_del(pong_signal, child);
}
END_TEST
@ -183,13 +123,9 @@ START_TEST(signals)
Eldbus_Model_Method *ping_method = eldbus_model_method_from_proxy_get(fake_server_proxy, FAKE_SERVER_PING_METHOD_NAME);
ck_assert_ptr_ne(NULL, ping_method);
efl_model_load_and_wait_for_load_status(ping_method, EFL_MODEL_LOAD_STATUS_LOADED);
check_efl_model_property_int_set(ping_method, ARGUMENT_A, 99);
Efl_Model_Load_Status status;
status = eldbus_model_method_call(ping_method);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
eldbus_model_method_call(ping_method);
efl_model_wait_for_event(pong_signal, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED);
@ -200,15 +136,11 @@ END_TEST
void eldbus_test_eldbus_model_signal(TCase *tc)
{
tcase_add_checked_fixture(tc, _setup, _teardown);
tcase_add_test(tc, load_status_get);
tcase_add_test(tc, properties_get);
tcase_add_test(tc, property_get);
tcase_add_test(tc, property_set);
tcase_add_test(tc, children_count);
tcase_add_test(tc, children_slice_get);
tcase_add_test(tc, unload);
tcase_add_test(tc, properties_load);
tcase_add_test(tc, children_load);
tcase_add_test(tc, child_add);
tcase_add_test(tc, child_del);
tcase_add_test(tc, signals);

View File

@ -36,11 +36,7 @@ _setup(void)
fake_server_object = eo_add(ELDBUS_MODEL_OBJECT_CLASS, NULL, eldbus_model_object_constructor(eo_self, ELDBUS_CONNECTION_TYPE_SESSION, NULL, EINA_FALSE, FAKE_SERVER_BUS, FAKE_SERVER_PATH));
ck_assert_ptr_ne(NULL, fake_server_object);
efl_model_load_and_wait_for_load_status(fake_server_object, EFL_MODEL_LOAD_STATUS_LOADED);
fake_server_proxy = eldbus_model_proxy_from_object_get(fake_server_object, FAKE_SERVER_INTERFACE);
efl_model_load_and_wait_for_load_status(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
}
static void
@ -53,20 +49,9 @@ _teardown(void)
check_shutdown();
}
START_TEST(load_status_get)
{
check_efl_model_load_status_get(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
_teardown();
}
END_TEST
START_TEST(properties_get)
{
Eina_Array *properties = NULL;
Efl_Model_Load_Status status;
status = efl_model_properties_get(fake_server_proxy, &properties);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
const Eina_Array *properties = efl_model_properties_get(fake_server_proxy);
ck_assert_ptr_ne(NULL, properties);
const unsigned int expected_properties_count = 3; // FAKE_SERVER_READONLY_PROPERTY, FAKE_SERVER_WRITEONLY_PROPERTY and FAKE_SERVER_READWRITE_PROPERTY properties
@ -83,10 +68,9 @@ START_TEST(property_get)
check_efl_model_property_int_eq(fake_server_proxy, FAKE_SERVER_READWRITE_PROPERTY, FAKE_SERVER_READWRITE_PROPERTY_VALUE);
// Write-only property returns error
const Eina_Value *dummy;
Efl_Model_Load_Status status;
status = efl_model_property_get(fake_server_proxy, FAKE_SERVER_WRITEONLY_PROPERTY, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
Eina_Promise *promise;
efl_model_property_get(fake_server_proxy, FAKE_SERVER_WRITEONLY_PROPERTY, &promise);
//ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
_teardown();
}
@ -98,10 +82,8 @@ _check_property_set(const char *property_name, int expected_property_value, int
Eina_Value value;
eina_value_setup(&value, EINA_VALUE_TYPE_INT);
eina_value_set(&value, expected_property_value);
Efl_Model_Load_Status status;
status = efl_model_property_set(fake_server_proxy, property_name, &value);
efl_model_property_set(fake_server_proxy, property_name, &value, NULL);
eina_value_flush(&value);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_wait_for_event(fake_server_proxy, EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED);
@ -114,10 +96,10 @@ START_TEST(property_set)
_check_property_set(FAKE_SERVER_READWRITE_PROPERTY, 0x76543210, &fake_server_data.readwrite_property);
// Read-only property returns error
Eina_Promise *promise;
Eina_Value dummy = {0};
Efl_Model_Load_Status status;
status = efl_model_property_set(fake_server_proxy, FAKE_SERVER_READONLY_PROPERTY, &dummy);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_property_set(fake_server_proxy, FAKE_SERVER_READONLY_PROPERTY, &dummy, &promise);
check_efl_model_promise_error(promise, &EFL_MODEL_ERROR_READ_ONLY);
_teardown();
}
@ -164,52 +146,6 @@ START_TEST(children_slice_get)
}
END_TEST
static void
_check_unload(void)
{
check_efl_model_load_status_get(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED);
efl_model_unload(fake_server_proxy);
check_efl_model_load_status_get(fake_server_proxy, EFL_MODEL_LOAD_STATUS_UNLOADED);
check_efl_model_children_count_eq(fake_server_proxy, 0);
}
START_TEST(unload)
{
_check_unload();
_teardown();
}
END_TEST
START_TEST(properties_load)
{
_check_unload();
efl_model_properties_load(fake_server_proxy);
efl_model_wait_for_load_status(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
check_efl_model_load_status_get(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES);
_teardown();
}
END_TEST
START_TEST(children_load)
{
_check_unload();
efl_model_children_load(fake_server_proxy);
efl_model_wait_for_load_status(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
check_efl_model_load_status_get(fake_server_proxy, EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN);
_test_fake_server_proxy_children_count(fake_server_proxy);
_teardown();
}
END_TEST
START_TEST(child_add)
{
Eo *child = efl_model_child_add(fake_server_proxy);
@ -222,19 +158,19 @@ END_TEST
START_TEST(child_del)
{
// Tests that it is not possible to delete children
Eina_Promise *promise;
unsigned int expected_children_count = 0;
Efl_Model_Load_Status status;
status = efl_model_children_count_get(fake_server_proxy, &expected_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_count_get(fake_server_proxy, &promise);
expected_children_count = efl_model_promise_then_u(promise);
ck_assert_msg(expected_children_count, "There must be at least 1 child to test");
// efl_model_child_del always returns ERROR
Eo *child = efl_model_first_child_get(fake_server_proxy);
status = efl_model_child_del(fake_server_proxy, child);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_ERROR, status);
efl_model_child_del(fake_server_proxy, child);
unsigned int actual_children_count = 0;
status = efl_model_children_count_get(fake_server_proxy, &actual_children_count);
ck_assert_int_eq(EFL_MODEL_LOAD_STATUS_LOADED, status);
efl_model_children_count_get(fake_server_proxy, &promise);
actual_children_count = efl_model_promise_then_u(promise);
ck_assert_int_le(expected_children_count, actual_children_count);
@ -245,15 +181,11 @@ END_TEST
void eldbus_test_fake_server_eldbus_model_proxy(TCase *tc)
{
tcase_add_checked_fixture(tc, _setup, NULL);
tcase_add_test(tc, load_status_get);
tcase_add_test(tc, properties_get);
tcase_add_test(tc, property_get);
tcase_add_test(tc, property_set);
tcase_add_test(tc, children_count);
tcase_add_test(tc, children_slice_get);
tcase_add_test(tc, unload);
tcase_add_test(tc, properties_load);
tcase_add_test(tc, children_load);
tcase_add_test(tc, child_add);
tcase_add_test(tc, child_del);
}