forked from enlightenment/efl
Merge branch 'devs/felipealmeida/emodel'
Efl.Model is an attempt to provide a data model as in the M of MVC to efl core. A first implementation and example is provided as a Eio.Model. This together with some patch in Elementary should provide a fully asynchronous and fast modern MVC system for EFL. The API has been in review since last summer, but will still only be accessible with EFL BETA API and EO for now. More data model should come in the future.
This commit is contained in:
commit
ec6b88257d
|
@ -162,7 +162,8 @@ pc/ecore-cxx.pc \
|
|||
pc/eolian-cxx.pc \
|
||||
pc/edje-cxx.pc \
|
||||
pc/eet-cxx.pc \
|
||||
pc/eo-cxx.pc
|
||||
pc/eo-cxx.pc \
|
||||
pc/eio-cxx.pc
|
||||
endif
|
||||
|
||||
if HAVE_ELUA
|
||||
|
|
|
@ -4573,6 +4573,7 @@ pc/ecore-avahi.pc
|
|||
pc/ector.pc
|
||||
pc/embryo.pc
|
||||
pc/eio.pc
|
||||
pc/eio-cxx.pc
|
||||
pc/eldbus.pc
|
||||
pc/efreet.pc
|
||||
pc/efreet-mime.pc
|
||||
|
|
|
@ -28,9 +28,12 @@
|
|||
/eina-cxx.pc
|
||||
/eet-cxx.pc
|
||||
/eio.pc
|
||||
/eio-cxx.pc
|
||||
/eldbus.pc
|
||||
/elocation.pc
|
||||
/embryo.pc
|
||||
/emodel.pc
|
||||
/emodel-cxx.pc
|
||||
/emotion.pc
|
||||
/eo.pc
|
||||
/ephysics.pc
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: eio C++ API
|
||||
Description: Enlightenned Asynchronous Input Output library C++ API.
|
||||
Requires.private: @requirements_pc_eio@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -leio
|
||||
Libs.private: @requirements_libs_eio@
|
||||
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eio-@VMAJ@ -I${includedir}/eio-cxx-@VMAJ@
|
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: emodel C++ API
|
||||
Description: MVC Library C++ API.
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires.private: @requirements_pc_emodel@
|
||||
Libs: -L${libdir} -lemodel
|
||||
Libs.private: @requirements_libs_emodel@
|
||||
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/emodel-@VMAJ@ -I${includedir}/emodel-cxx-@VMAJ@
|
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: emodel
|
||||
Description: MVC Library
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires.private: @requirements_pc_emodel@
|
||||
Libs: -L${libdir} -lemodel
|
||||
Libs.private: @requirements_libs_emodel@
|
||||
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/emodel-@VMAJ@
|
|
@ -60,7 +60,7 @@ build() {
|
|||
package_efl() {
|
||||
provides+=("ecore=$pkgver" "eldbus=$pkgver" "edje=$pkgver"
|
||||
"eet=$pkgver" "eeze=$pkgver" "efreet=$pkgver"
|
||||
"eina=$pkgver" "eio=$pkgver" "embryo=$pkgver" "emotion=$pkgver"
|
||||
"eina=$pkgver" "eio=$pkgver" "embryo=$pkgver" "emotion=$pkgver" "emodel=$pkgver"
|
||||
"ephysics=$pkgver" "ethumb=$pkgver" "evas=$pkgver")
|
||||
conflicts+=('ecore' 'edje' 'eet' 'eeze' 'efreet' 'eina' 'eio' 'embryo' 'emotion'
|
||||
'ethumb' 'evas')
|
||||
|
|
|
@ -10,7 +10,8 @@ EOLIAN_FLAGS = -I$(srcdir)\
|
|||
-I$(srcdir)/lib/efl/interfaces \
|
||||
-I$(srcdir)/lib/ecore_audio \
|
||||
-I$(srcdir)/lib/ecore \
|
||||
-I$(srcdir)/lib/ecore_con
|
||||
-I$(srcdir)/lib/ecore_con \
|
||||
-I$(srcdir)/lib/eio
|
||||
|
||||
DIST_SUBDIRS =
|
||||
SUBDIRS =
|
||||
|
@ -77,6 +78,7 @@ include Makefile_Eo_Cxx.am
|
|||
include Makefile_Efl_Cxx.am
|
||||
include Makefile_Edje_Cxx.am
|
||||
include Makefile_Evas_Cxx.am
|
||||
include Makefile_Eio_Cxx.am
|
||||
|
||||
include Makefile_Elua.am
|
||||
include Makefile_Elocation.am
|
||||
|
|
|
@ -12,7 +12,8 @@ efl_eolian_files = \
|
|||
lib/efl/interfaces/efl_gfx_shape.eo \
|
||||
lib/efl/interfaces/efl_gfx_gradient_base.eo \
|
||||
lib/efl/interfaces/efl_gfx_gradient_linear.eo \
|
||||
lib/efl/interfaces/efl_gfx_gradient_radial.eo
|
||||
lib/efl/interfaces/efl_gfx_gradient_radial.eo \
|
||||
lib/efl/interfaces/efl_model_base.eo
|
||||
|
||||
efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h)
|
||||
efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c)
|
||||
|
@ -28,6 +29,7 @@ CLEANFILES += \
|
|||
EXTRA_DIST += \
|
||||
lib/efl/Efl_Config.h \
|
||||
lib/efl/Efl.h \
|
||||
lib/efl/Efl_Model_Common.h \
|
||||
$(efl_eolian_files)
|
||||
|
||||
efleolianfilesdir = $(datadir)/eolian/include/efl-@VMAJ@
|
||||
|
|
|
@ -19,7 +19,7 @@ generated_efl_cxx_bindings = \
|
|||
lib/efl/interfaces/efl_gfx_gradient_radial.eo.hh
|
||||
|
||||
lib/efl/Efl.hh: $(generated_efl_cxx_bindings)
|
||||
@echo @ECHO_E@ "#ifndef EFL_CXX_EDJE_HH\n#define EFL_CXX_EDJE_HH\n" > $(top_builddir)/src/lib/efl/Efl.hh
|
||||
@echo @ECHO_E@ "#ifndef EFL_CXX_HH\n#define EFL_CXX_HH\n" > $(top_builddir)/src/lib/efl/Efl.hh
|
||||
@echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/efl/Efl.hh
|
||||
@for i in $(generated_efl_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/efl/Efl.hh; done
|
||||
@echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/efl/Efl.hh
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
|
||||
### Library
|
||||
|
||||
EIO_EOS = \
|
||||
lib/eio/eio_model.eo
|
||||
|
||||
EIO_EOS_H = $(EIO_EOS:%.eo=%.eo.h)
|
||||
EIO_EOS_C = $(EIO_EOS:%.eo=%.eo.c)
|
||||
|
||||
BUILT_SOURCES += $(EIO_EOS_C) $(EIO_EOS_H)
|
||||
|
||||
eioeolianfilesdir = $(datadir)/eolian/include/eio-@VMAJ@
|
||||
eioeolianfiles_DATA = $(EIO_EOS)
|
||||
|
||||
lib_LTLIBRARIES += lib/eio/libeio.la
|
||||
EXTRA_DIST += $(eioeolianfiles_DATA)
|
||||
|
||||
installed_eiomainheadersdir = $(includedir)/eio-@VMAJ@
|
||||
|
||||
dist_installed_eiomainheaders_DATA = lib/eio/Eio.h lib/eio/eio_inline_helper.x
|
||||
nodist_installed_eiomainheaders_DATA = $(EIO_EOS_H)
|
||||
|
||||
lib_eio_libeio_la_SOURCES = \
|
||||
lib/eio/eio_dir.c \
|
||||
|
@ -16,6 +30,8 @@ lib/eio/eio_monitor.c \
|
|||
lib/eio/eio_monitor_poll.c \
|
||||
lib/eio/eio_single.c \
|
||||
lib/eio/eio_xattr.c \
|
||||
lib/eio/eio_model.c \
|
||||
lib/eio/eio_model_private.h \
|
||||
lib/eio/eio_private.h
|
||||
|
||||
if HAVE_INOTIFY
|
||||
|
@ -30,9 +46,9 @@ endif
|
|||
endif
|
||||
endif
|
||||
|
||||
lib_eio_libeio_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EIO_CFLAGS@
|
||||
lib_eio_libeio_la_LIBADD = @EIO_LIBS@
|
||||
lib_eio_libeio_la_DEPENDENCIES = @EIO_INTERNAL_LIBS@
|
||||
lib_eio_libeio_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EIO_CFLAGS@ @EFL_CFLAGS@
|
||||
lib_eio_libeio_la_LIBADD = @EIO_LIBS@ @EFL_LIBS@
|
||||
lib_eio_libeio_la_DEPENDENCIES = @EIO_INTERNAL_LIBS@ @EFL_INTERNAL_LIBS@
|
||||
lib_eio_libeio_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
|
||||
if HAVE_NOTIFY_COCOA
|
||||
lib_eio_libeio_la_LDFLAGS += -framework CoreServices
|
||||
|
@ -45,6 +61,8 @@ TESTS += tests/eio/eio_suite
|
|||
|
||||
tests_eio_eio_suite_SOURCES = \
|
||||
tests/eio/eio_suite.c \
|
||||
tests/eio/eio_model_test_file.c \
|
||||
tests/eio/eio_model_test_monitor_add.c \
|
||||
tests/eio/eio_test_monitor.c
|
||||
|
||||
tests_eio_eio_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
|
@ -52,16 +70,20 @@ tests_eio_eio_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
|||
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eio\" \
|
||||
@CHECK_CFLAGS@ \
|
||||
@ECORE_FILE_CFLAGS@ \
|
||||
@EIO_CFLAGS@
|
||||
@EIO_CFLAGS@ @EFL_CFLAGS@
|
||||
|
||||
tests_eio_eio_suite_LDADD = \
|
||||
@CHECK_LIBS@ \
|
||||
@USE_ECORE_FILE_LIBS@ \
|
||||
@USE_EIO_LIBS@
|
||||
@USE_EFL_LIBS@
|
||||
|
||||
tests_eio_eio_suite_DEPENDENCIES = \
|
||||
@USE_EIO_INTERNAL_LIBS@
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST += tests/eio/eio_suite.h
|
||||
EXTRA_DIST += \
|
||||
tests/eio/eio_suite.h \
|
||||
lib/eio/eio_model.h
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
if HAVE_CXX11
|
||||
|
||||
### Generated headers
|
||||
|
||||
generated_eio_cxx_bindings = lib/eio/eio_model.eo.hh
|
||||
|
||||
lib/eio/Eio.hh: $(generated_eio_cxx_bindings)
|
||||
@echo @ECHO_E@ "#ifndef EFL_CXX_EIO_HH\n#define EFL_CXX_EIO_HH\n" > $(top_builddir)/src/lib/eio/Eio.hh
|
||||
@echo @ECHO_E@ "#ifdef EFL_BETA_API_SUPPORT" >> $(top_builddir)/src/lib/eio/Eio.hh
|
||||
@for i in $(generated_eio_cxx_bindings); do echo "#include <$$(basename $$i)>" >> $(top_builddir)/src/lib/eio/Eio.hh; done
|
||||
@echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/eio/Eio.hh
|
||||
|
||||
generated_eio_cxx_all = \
|
||||
$(generated_eio_cxx_bindings) \
|
||||
lib/eio/Eio.hh
|
||||
|
||||
CLEANFILES += $(generated_eio_cxx_all)
|
||||
|
||||
installed_eiocxxmainheadersdir = $(includedir)/eio-cxx-@VMAJ@/
|
||||
nodist_installed_eiocxxmainheaders_DATA = $(generated_eio_cxx_all)
|
||||
|
||||
endif
|
|
@ -22,6 +22,7 @@ eio_file_copy
|
|||
eio_file_ls_SOURCES = eio_file_ls.c
|
||||
eio_file_ls_LDADD = \
|
||||
$(top_builddir)/src/lib/eio/libeio.la \
|
||||
$(top_builddir)/src/lib/emodel/libemodel.la \
|
||||
$(top_builddir)/src/lib/eo/libeo.la \
|
||||
$(top_builddir)/src/lib/ecore/libecore.la \
|
||||
$(top_builddir)/src/lib/eet/libeet.la \
|
||||
|
@ -32,6 +33,7 @@ $(top_builddir)/src/lib/eina/libeina.la \
|
|||
eio_file_copy_SOURCES = eio_file_copy.c
|
||||
eio_file_copy_LDADD = \
|
||||
$(top_builddir)/src/lib/eio/libeio.la \
|
||||
$(top_builddir)/src/lib/emodel/libemodel.la \
|
||||
$(top_builddir)/src/lib/eo/libeo.la \
|
||||
$(top_builddir)/src/lib/ecore/libecore.la \
|
||||
$(top_builddir)/src/lib/eet/libeet.la \
|
||||
|
|
|
@ -139,6 +139,8 @@ typedef enum _Efl_Gfx_Fill_Spread
|
|||
|
||||
#ifdef EFL_BETA_API_SUPPORT
|
||||
|
||||
#include <Efl_Model_Common.h>
|
||||
|
||||
/* Interfaces */
|
||||
#include "interfaces/efl_control.eo.h"
|
||||
#include "interfaces/efl_file.eo.h"
|
||||
|
@ -146,6 +148,7 @@ typedef enum _Efl_Gfx_Fill_Spread
|
|||
#include "interfaces/efl_player.eo.h"
|
||||
#include "interfaces/efl_text.eo.h"
|
||||
#include "interfaces/efl_text_properties.eo.h"
|
||||
#include "interfaces/efl_model_base.eo.h"
|
||||
|
||||
EAPI extern const Eo_Event_Description _EFL_GFX_CHANGED;
|
||||
EAPI extern const Eo_Event_Description _EFL_GFX_PATH_CHANGED;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#ifndef _EFL_MODEL_COMMON_H
|
||||
#define _EFL_MODEL_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @enum _Efl_Model_Load_Status
|
||||
* XXX/TODO/FIXME: Remove this enum (and possibly other data) from here
|
||||
* as soon as eolian translates these data types in .eo's.
|
||||
*/
|
||||
enum _Efl_Model_Load_Status
|
||||
{
|
||||
EFL_MODEL_LOAD_STATUS_ERROR = 0,
|
||||
EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES = (1 << 0),
|
||||
EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN = (1 << 1),
|
||||
EFL_MODEL_LOAD_STATUS_LOADING = (1 << 0) | (1 << 1),
|
||||
|
||||
EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES = (1 << 2),
|
||||
EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN = (1 << 3),
|
||||
EFL_MODEL_LOAD_STATUS_LOADED = (1 << 2) | (1 << 3),
|
||||
|
||||
EFL_MODEL_LOAD_STATUS_UNLOADING = (1 << 4),
|
||||
EFL_MODEL_LOAD_STATUS_UNLOADED = (1 << 5)
|
||||
};
|
||||
/**
|
||||
* @typedef Efl_Model_Load_Status
|
||||
*/
|
||||
typedef enum _Efl_Model_Load_Status Efl_Model_Load_Status;
|
||||
|
||||
/**
|
||||
* @struct _Efl_Model_Load
|
||||
* Structure to hold Efl_Model_Load_Status enum
|
||||
* (and possible other data) to avoid ABI break.
|
||||
*/
|
||||
struct _Efl_Model_Load
|
||||
{
|
||||
Efl_Model_Load_Status status;
|
||||
/* add more data below here if necessary */
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef Efl_Model_Load
|
||||
*/
|
||||
typedef struct _Efl_Model_Load Efl_Model_Load;
|
||||
|
||||
/**
|
||||
* @struct _Efl_Model_Property_Event
|
||||
*/
|
||||
struct _Efl_Model_Property_Event
|
||||
{
|
||||
const Eina_Array *changed_properties; /**< array of property name */
|
||||
const Eina_Array *invalidated_properties; /**< array of property name */
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef Efl_Model_Property_Event
|
||||
*/
|
||||
typedef struct _Efl_Model_Property_Event Efl_Model_Property_Event;
|
||||
|
||||
/**
|
||||
* @struct _Efl_Model_Children_Event
|
||||
* Every time a child id added the event
|
||||
* EFL_MODEL_EVENT_CHILD_ADDED is dispatched
|
||||
* passing along this structure.
|
||||
*/
|
||||
struct _Efl_Model_Children_Event
|
||||
{
|
||||
Eo *child; /**< child, for child_add */
|
||||
/**
|
||||
* index is a hint and is intended
|
||||
* to provide a way for applications
|
||||
* to control/know children relative
|
||||
* positions through listings.
|
||||
*
|
||||
* NOTE: If listing is performed asynchronously
|
||||
* exact order may not be guaranteed.
|
||||
*/
|
||||
unsigned int index;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct Efl_Model_Children_Event
|
||||
*/
|
||||
typedef struct _Efl_Model_Children_Event Efl_Model_Children_Event;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -25,3 +25,5 @@ EAPI const Eo_Event_Description _EFL_GFX_CHANGED =
|
|||
|
||||
EAPI const Eo_Event_Description _EFL_GFX_PATH_CHANGED =
|
||||
EO_EVENT_DESCRIPTION("Graphics path changed", "The path of a shape object changed");
|
||||
|
||||
#include "interfaces/efl_model_base.eo.c"
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* type Efl_Model_Load_Status: enum _Efl_Model_Load_Status
|
||||
* {
|
||||
* EFL_MODEL_LOAD_STATUS_ERROR = 0, /*@ Error in Load Model *
|
||||
* EFL_MODEL_LOAD_STATUS_LOADING_PROPERTIES = (1 << 0), /*@ properties load in progress *
|
||||
* EFL_MODEL_LOAD_STATUS_LOADING_CHILDREN = (1 << 1), /*@ children load in progress *
|
||||
* EFL_MODEL_LOAD_STATUS_LOADING = (1 << 0) | (1 << 1), /*@ children and properties load in progress *
|
||||
*
|
||||
* EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES = (1 << 2), /*@ Model as ready to fetch properties *
|
||||
* EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN = (1 << 3), /*@ Model as ready to fetch children *
|
||||
* EFL_MODEL_LOAD_STATUS_LOADED = (1 << 2) | (1 << 3), /*@ Model as ready to fetch properties and children *
|
||||
*
|
||||
* EFL_MODEL_LOAD_STATUS_UNLOADING = (1 << 4), /*@ Model Unload in progress *
|
||||
* EFL_MODEL_LOAD_STATUS_UNLOADED = (1 << 5) /*@ Model Unloaded *
|
||||
* }
|
||||
*
|
||||
*
|
||||
* type Efl_Model_Property_Event: struct _Efl_Model_Property_Event
|
||||
* {
|
||||
* changed_properties: Eina_Array* <const(char)*>; /*@ List of changed properties *
|
||||
* invalidated_properties: Eina_Array* <const(char)*>; /*@ Removed properties identified by name *
|
||||
* }
|
||||
*/
|
||||
|
||||
interface Efl.Model.Base ()
|
||||
{
|
||||
legacy_prefix: null;
|
||||
eo_prefix: efl_model;
|
||||
properties {
|
||||
load_status {
|
||||
get {
|
||||
/*@
|
||||
Get a load emodel current status.
|
||||
|
||||
@return: @c Efl_Model_Load_Status
|
||||
|
||||
By convention this means get the current model status.
|
||||
Possible values are defined Efl_Model_Load_Status enumerator.
|
||||
|
||||
@see Efl_Model_Load_Status
|
||||
@see efl_model_load
|
||||
|
||||
@since 1.14 */
|
||||
return: Efl_Model_Load_Status;
|
||||
}
|
||||
}
|
||||
properties {
|
||||
get {
|
||||
/*@
|
||||
Get properties from model.
|
||||
|
||||
@return: @c Efl_Model_Load_Status
|
||||
|
||||
properties_get is due to provide callers a way the fetch the current
|
||||
properties implemented/used by the model.
|
||||
The event EFL_MODEL_EVENT_PROPERTIES_CHANGE will be raised to notify listeners
|
||||
of any modifications in the properties.
|
||||
|
||||
@see EFL_MODEL_EVENT_PROPERTIES_CHANGE
|
||||
@since 1.14 */
|
||||
|
||||
return: Efl_Model_Load_Status;
|
||||
}
|
||||
values {
|
||||
const(array<const(char*)>*) properties; /*@ array of current properties */
|
||||
}
|
||||
}
|
||||
property {
|
||||
set {
|
||||
/*@
|
||||
Set a property value of a given property name.
|
||||
|
||||
@return: @c EINA_TRUE, on success, @c EINA_FALSE in readonly property or error
|
||||
|
||||
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
|
||||
|
||||
@see efl_model_property_get
|
||||
@see EFL_MODEL_EVENT_PROPERTIES_CHANGE
|
||||
@since 1.14 */
|
||||
|
||||
return: Efl_Model_Load_Status;
|
||||
}
|
||||
get {
|
||||
/*@
|
||||
Retrieve the value of a given property name.
|
||||
|
||||
@return: @c Load Status, on success, @c EFL_MODEL_LOAD_STATUS_ERROR otherwise
|
||||
|
||||
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.
|
||||
|
||||
@see efl_model_properties_get
|
||||
@see EFL_MODEL_EVENT_PROPERTIES_CHANGE
|
||||
|
||||
@since 1.14 */
|
||||
return: Efl_Model_Load_Status;
|
||||
}
|
||||
keys {
|
||||
const(char)* property; /*@ Property name */
|
||||
}
|
||||
values {
|
||||
const(Eina_Value)* value; /*@ New value */
|
||||
}
|
||||
}
|
||||
children_slice {
|
||||
get {
|
||||
/*@
|
||||
Get children slice OR full range.
|
||||
|
||||
@return: @c Efl_Model_Load_Status. See below for more info.
|
||||
|
||||
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 @c EFL_MODEL_LOAD_STATUS_LOADED_CHILDREN.
|
||||
When children accessor is return:ed 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 @c start AND @c 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:
|
||||
child 0 [no]
|
||||
child 1 [no]
|
||||
child 2 [yes]
|
||||
child 3 [yes]
|
||||
child 4 [yes]
|
||||
child 5 [yes]
|
||||
child 6 [no]
|
||||
child 7 [no]
|
||||
|
||||
Optionally the user can call children_count_get to know
|
||||
the number of children so a valid range can be known in advance.
|
||||
|
||||
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
|
||||
|
||||
@see efl_model_children_get
|
||||
@see efl_model_children_count_get
|
||||
@see efl_model_load
|
||||
@see efl_model_load_status_get
|
||||
@since 1.14 */
|
||||
|
||||
return: Efl_Model_Load_Status;
|
||||
}
|
||||
keys {
|
||||
unsigned start; /*@ Range begin - start from here. If start and count are 0 slice is ignored.*/
|
||||
unsigned count; /*@ Range size. If count and start are 0 slice is ignored.*/
|
||||
}
|
||||
values {
|
||||
accessor<list*>* children_accessor;
|
||||
}
|
||||
}
|
||||
children_count {
|
||||
get {
|
||||
/*@
|
||||
Get children count.
|
||||
|
||||
@return: @c EINA_TRUE, on success, @c EINA_FALSE otherwise
|
||||
|
||||
When efl_model_load is completed efl_model_coildren_count_get can be use
|
||||
to get the number of children. children_count_get can also be used
|
||||
before calling children_slice_get so a valid range is known.
|
||||
Event EFL_MODEL_CHILDREN_COUNT_CHANGED is emitted when count is finished.
|
||||
|
||||
@see efl_model_children_get
|
||||
@see efl_model_children_slice_get
|
||||
@see efl_model_load
|
||||
@see efl_model_load_status_get
|
||||
@since 1.14 */
|
||||
|
||||
return: Efl_Model_Load_Status;
|
||||
}
|
||||
values {
|
||||
unsigned children_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
methods {
|
||||
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
|
||||
@warning 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 Efl_Model_Load_Status
|
||||
@see efl_model_properties_load
|
||||
@see efl_model_children_load
|
||||
@see efl_model_unload
|
||||
@see efl_model_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
|
||||
@warning This convention should be followed, but no guarantees of behaviour
|
||||
by user defined types can be given.
|
||||
|
||||
@see Efl_Model_Load_Status
|
||||
@see efl_model_load
|
||||
@see efl_model_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 efl_model_load, meaning that
|
||||
it won't load children, it is a hint.
|
||||
For loadind both properties and children use efl_model_load
|
||||
instead.
|
||||
|
||||
@see efl_model_load
|
||||
|
||||
@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 efl_model_load, meaning that
|
||||
it won't load properties. For loadind both properties and children use efl_model_load
|
||||
instead.
|
||||
|
||||
@see efl_model_load
|
||||
|
||||
@since 1.14 */
|
||||
}
|
||||
child_add {
|
||||
/*@
|
||||
Add a new child.
|
||||
|
||||
@return: @c Emodel* on success, @c NULL otherwise
|
||||
|
||||
Add a new child, possibly dummy, depending on the implementation,
|
||||
of a internal keeping. When the child is effectively
|
||||
added the event EFL_MODEL_EVENT_CHILD_ADD is then raised and the new child
|
||||
is kept along with other children.
|
||||
|
||||
@see EFL_MODEL_EVENT_CHILD_ADD
|
||||
@see load_status_get
|
||||
|
||||
@since 1.14 */
|
||||
|
||||
return: Eo *;
|
||||
}
|
||||
child_del {
|
||||
/*@
|
||||
Remove a child.
|
||||
|
||||
@return: @c Efl_Model_Load_Status on success, @c EFL_MODEL_LOAD_STATUS_ERROR otherwise.
|
||||
|
||||
Remove a child of a internal keeping. When the child is effectively
|
||||
removed the event EFL_MODEL_EVENT_CHILD_REMOVED is then raised to give a
|
||||
chance for listeners to perform any cleanup and/or update references.
|
||||
|
||||
@see EFL_MODEL_EVENT_CHILD_REMOVED
|
||||
@since 1.14 */
|
||||
|
||||
return: Efl_Model_Load_Status;
|
||||
|
||||
params {
|
||||
@in Eo* child; /*@ Child to be removed */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events {
|
||||
load,status: Efl_Model_Load_Status; /*@ Event dispatch when load status changes */
|
||||
properties,changed: Efl_Model_Properties_Evt; /*@ Event dispatched when properties list is available. */
|
||||
child,added; /*@ Event dispatched when new child is added. */
|
||||
child,removed; /*@ Event dispatched when child is removed. */
|
||||
children,count,changed; /*@ Event dispatched when children count is finished. */
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,683 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <Efl.h>
|
||||
#include <Eina.h>
|
||||
#include <eio_model.h>
|
||||
#include <Eio.h>
|
||||
#include <Ecore.h>
|
||||
#include <Eo.h>
|
||||
|
||||
#include "eio_private.h"
|
||||
#include "eio_model_private.h"
|
||||
|
||||
#define MY_CLASS EIO_MODEL_CLASS
|
||||
#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
|
||||
_load_set(Eio_Model_Data *priv, Efl_Model_Load_Status status)
|
||||
{
|
||||
Efl_Model_Load load;
|
||||
|
||||
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_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_LOAD_STATUS, &load));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks
|
||||
* Property
|
||||
*/
|
||||
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));
|
||||
|
||||
priv->is_dir = eio_file_is_dir(stat);
|
||||
memset(&evt, 0, sizeof(Efl_Model_Property_Event));
|
||||
|
||||
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_do(priv->obj, eo_event_callback_call(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);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_progress_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, const Eio_Progress *info EINA_UNUSED)
|
||||
{
|
||||
//TODO: implement
|
||||
}
|
||||
|
||||
static void
|
||||
_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_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;
|
||||
|
||||
eo_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, &evt));
|
||||
eina_array_free(properties);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error)
|
||||
{
|
||||
if (error != 0)
|
||||
{
|
||||
ERR("%d: %s.", error, strerror(error));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_prop_set_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error)
|
||||
{
|
||||
if (error != 0)
|
||||
{
|
||||
ERR("%d: %s.", error, strerror(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks
|
||||
* Ecore Events
|
||||
*/
|
||||
static Eina_Bool
|
||||
_efl_model_evt_added_ecore_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||
{
|
||||
Eio_Monitor_Event *evt = (Eio_Monitor_Event*)event;
|
||||
Eio_Model_Data *priv = data;
|
||||
Efl_Model_Children_Event cevt;
|
||||
Eina_Value path;
|
||||
|
||||
if (priv->children_list)
|
||||
{
|
||||
cevt.child = eo_add_ref(EIO_MODEL_CLASS, priv->obj, eio_model_path_set(evt->filename));
|
||||
priv->children_list = eina_list_append(priv->children_list, cevt.child);
|
||||
cevt.index = eina_list_count(priv->children_list);
|
||||
|
||||
eina_value_setup(&path, EINA_VALUE_TYPE_STRING);
|
||||
eina_value_set(&path, evt->filename);
|
||||
eo_do(cevt.child, eio_model_children_filter_set(priv->filter_cb, priv->filter_userdata));
|
||||
eina_value_flush(&path);
|
||||
|
||||
eo_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILD_ADDED, &cevt));
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_efl_model_evt_deleted_ecore_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||
{
|
||||
Eio_Monitor_Event *evt = (Eio_Monitor_Event*)event;
|
||||
Eio_Model_Data *priv = data;
|
||||
|
||||
if (priv->children_list)
|
||||
{
|
||||
Eina_List* cur = priv->children_list;
|
||||
int i;
|
||||
|
||||
for (i = 0; cur; ++i, cur = cur->next)
|
||||
{
|
||||
Eio_Model_Data *cur_priv = eo_data_scope_get(cur->data, MY_CLASS);
|
||||
if(strcmp(cur_priv->path, evt->filename) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cur)
|
||||
{
|
||||
Efl_Model_Children_Event cevt;
|
||||
cevt.index = i;
|
||||
cevt.child = cur->data;
|
||||
|
||||
eo_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILD_REMOVED, &cevt));
|
||||
|
||||
priv->children_list = eina_list_remove_list(priv->children_list, cur);
|
||||
eo_unref(cevt.child);
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_monitors_list_load(Eio_Model_Data *priv)
|
||||
{
|
||||
priv->mon.mon_event_child_add[0] = EIO_MONITOR_DIRECTORY_CREATED;
|
||||
priv->mon.mon_event_child_add[1] = EIO_MONITOR_FILE_CREATED;
|
||||
priv->mon.mon_event_child_add[2] = EIO_MONITOR_ERROR;
|
||||
priv->mon.mon_event_child_del[0] = EIO_MONITOR_DIRECTORY_DELETED;
|
||||
priv->mon.mon_event_child_del[1] = EIO_MONITOR_FILE_DELETED;
|
||||
priv->mon.mon_event_child_del[2] = EIO_MONITOR_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks
|
||||
* Child Del
|
||||
*/
|
||||
static Eina_Bool
|
||||
_eio_filter_child_del_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, const Eina_File_Direct_Info *info EINA_UNUSED)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_progress_child_del_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, const Eio_Progress *info EINA_UNUSED)
|
||||
{}
|
||||
|
||||
static void
|
||||
_eio_done_unlink_cb(void *data, Eio_File *handler EINA_UNUSED)
|
||||
{
|
||||
Eio_Model_Data *priv = data;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(priv);
|
||||
EINA_SAFETY_ON_NULL_RETURN(priv->obj);
|
||||
|
||||
eo_unref(priv->obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_error_unlink_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error)
|
||||
{
|
||||
Eio_Model_Data *priv = data;
|
||||
|
||||
ERR("%d: %s.", error, strerror(error));
|
||||
|
||||
eo_unref(priv->obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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_Array **)properties = priv->properties_name;
|
||||
|
||||
return priv->load.status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
|
||||
*value = NULL;
|
||||
if (priv->load.status & EFL_MODEL_LOAD_STATUS_LOADED_PROPERTIES)
|
||||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
return priv->load.status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
char *dest;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(property, EINA_FALSE);
|
||||
|
||||
if (strcmp(property, "path") != 0)
|
||||
return EINA_FALSE;
|
||||
|
||||
dest = eina_value_to_string(value);
|
||||
if (priv->path == NULL)
|
||||
{
|
||||
priv->path = dest;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_model_efl_model_base_monitor_add(Eio_Model_Data *priv)
|
||||
{
|
||||
if (!priv->monitor)
|
||||
{
|
||||
priv->monitor = eio_monitor_add(priv->path);
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; priv->mon.mon_event_child_add[i] != EIO_MONITOR_ERROR ; ++i)
|
||||
priv->mon.ecore_child_add_handler[i] =
|
||||
ecore_event_handler_add(priv->mon.mon_event_child_add[i], _efl_model_evt_added_ecore_cb, priv);
|
||||
|
||||
for (i = 0; priv->mon.mon_event_child_del[i] != EIO_MONITOR_ERROR ; ++i)
|
||||
priv->mon.ecore_child_add_handler[i] =
|
||||
ecore_event_handler_add(priv->mon.mon_event_child_del[i], _efl_model_evt_deleted_ecore_cb, priv);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Callbacks
|
||||
* Children Load
|
||||
*/
|
||||
static Eina_Bool
|
||||
_eio_filter_children_load_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info)
|
||||
{
|
||||
Eio_Model_Data *priv = data;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
|
||||
|
||||
if (priv->filter_cb)
|
||||
{
|
||||
return priv->filter_cb(priv->filter_userdata, handler, info);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_main_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_File_Direct_Info *info)
|
||||
{
|
||||
Eo *child;
|
||||
Eio_Model_Data *priv = data;
|
||||
EINA_SAFETY_ON_NULL_RETURN(priv);
|
||||
|
||||
child = eo_add(MY_CLASS, NULL, eio_model_path_set(info->path));
|
||||
if (priv->filter_cb)
|
||||
eo_do(child, eio_model_children_filter_set(priv->filter_cb, priv->filter_userdata));
|
||||
|
||||
priv->children_list = eina_list_append(priv->children_list, child);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
eo_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, &count));
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_error_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, int error)
|
||||
{
|
||||
Eio_Model_Data *priv = data;
|
||||
Eo *child;
|
||||
|
||||
ERR("%d: %s.", error, strerror(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
|
||||
_eio_model_children_filter_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eio_Filter_Direct_Cb filter_cb, void *data)
|
||||
{
|
||||
priv->filter_cb = filter_cb;
|
||||
priv->filter_userdata = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Child Add
|
||||
*/
|
||||
static Eo *
|
||||
_eio_model_efl_model_base_child_add(Eo *obj EINA_UNUSED, Eio_Model_Data *priv EINA_UNUSED)
|
||||
{
|
||||
return eo_add(EIO_MODEL_CLASS, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_model_efl_model_base_child_del_stat(void* data, Eio_File* handler EINA_UNUSED, const Eina_Stat* stat)
|
||||
{
|
||||
Eo* child = data;
|
||||
Eio_Model_Data *child_priv = eo_data_scope_get(child, MY_CLASS);
|
||||
|
||||
if(eio_file_is_dir(stat))
|
||||
eio_dir_unlink(child_priv->path,
|
||||
_eio_filter_child_del_cb,
|
||||
_eio_progress_child_del_cb,
|
||||
_eio_done_unlink_cb,
|
||||
_eio_error_unlink_cb,
|
||||
child_priv);
|
||||
else
|
||||
eio_file_unlink(child_priv->path, _eio_done_unlink_cb, _eio_error_unlink_cb, child_priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Child Remove
|
||||
*/
|
||||
static Efl_Model_Load_Status
|
||||
_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);
|
||||
|
||||
if (priv->children_list != NULL)
|
||||
{
|
||||
priv->children_list = eina_list_remove(priv->children_list, child);
|
||||
}
|
||||
|
||||
child_priv = eo_data_scope_get(child, MY_CLASS);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(child_priv, EFL_MODEL_LOAD_STATUS_ERROR);
|
||||
|
||||
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
|
||||
_eio_model_efl_model_base_children_slice_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv,
|
||||
unsigned start, unsigned count, Eina_Accessor **children_accessor)
|
||||
{
|
||||
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))
|
||||
{
|
||||
/**
|
||||
* Status should be in either unloaded state or unitialized
|
||||
* so we simply return without much alarm.
|
||||
*/
|
||||
*children_accessor = NULL;
|
||||
return priv->load.status;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class definitions
|
||||
*/
|
||||
static void
|
||||
_eio_model_eo_base_constructor(Eo *obj, Eio_Model_Data *priv)
|
||||
{
|
||||
eo_do_super(obj, MY_CLASS, eo_constructor());
|
||||
unsigned int i;
|
||||
priv->obj = obj;
|
||||
|
||||
priv->properties_name = eina_array_new(EIO_MODEL_PROP_LAST);
|
||||
EINA_SAFETY_ON_NULL_RETURN(priv->properties_name);
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
_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);
|
||||
}
|
||||
|
||||
static void
|
||||
_eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv)
|
||||
{
|
||||
Eo *child;
|
||||
unsigned int i;
|
||||
|
||||
if (priv->monitor)
|
||||
eio_monitor_del(priv->monitor);
|
||||
|
||||
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);
|
||||
|
||||
free(priv->path);
|
||||
eo_do_super(obj, MY_CLASS, eo_destructor());
|
||||
}
|
||||
|
||||
#include "eio_model.eo.c"
|
|
@ -0,0 +1,49 @@
|
|||
class Eio.Model (Eo.Base, Efl.Model.Base)
|
||||
{
|
||||
legacy_prefix: null;
|
||||
methods {
|
||||
children_filter_set {
|
||||
/*@ Set children filter callback.
|
||||
This function sets, along with user's private data userdata,
|
||||
the Eio's Eio_Filter_Direct_Cb which is a mid-step
|
||||
before receiving the real data. Once in filter
|
||||
callback we can decide, by returning either EINA_FALSE, to abort
|
||||
the notification or EINA_TRUE to keep it.
|
||||
@see Eio.h
|
||||
@see emodel_children_slice_fetch
|
||||
@def emodel_children_filter_set
|
||||
@since 1.11
|
||||
@in filter_cb
|
||||
@in userdata */
|
||||
params {
|
||||
Eio_Filter_Direct_Cb filter_cb; /*@ Filter callback */
|
||||
void *userdata; /*@ User's private data */
|
||||
}
|
||||
}
|
||||
path_set {
|
||||
/*@ Custom Eio_Model constructor.
|
||||
@def eio_model_constructor
|
||||
@since 1.11
|
||||
@in path */
|
||||
params {
|
||||
@in const(char)* path; /*@ Root path provided by caller */
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
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.child_add;
|
||||
Efl.Model.Base.child_del;
|
||||
Efl.Model.Base.children_slice.get;
|
||||
Efl.Model.Base.children_count.get;
|
||||
Efl.Model.Base.children_load;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @page emodel_eio_main Emodel_Eio
|
||||
*
|
||||
* @date 2014 (created)
|
||||
*
|
||||
* @brief Emodel_Eio Library Public API Calls
|
||||
*
|
||||
* @section toc Table of Contents
|
||||
*
|
||||
* @li @ref emodel_eio_main_intro
|
||||
*
|
||||
* @section eo_main_intro Introduction
|
||||
*
|
||||
* This module targets file operations using Emodel.
|
||||
|
||||
*
|
||||
* Recommended reading:
|
||||
*
|
||||
* @li @ref Emodel
|
||||
* @li @ref Eo
|
||||
* @li @ref Eina
|
||||
*
|
||||
* @defgroup Emodel_Eio EIO implementation wrapper for Emodel
|
||||
*
|
||||
* @addtogroup Emodel_Eio
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _EMODEL_EIO_H
|
||||
#define _EMODEL_EIO_H
|
||||
|
||||
#include <Eo.h>
|
||||
#include <Efl.h>
|
||||
#include <Eio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <eio_model.eo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //_EMODEL_EIO_H
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef _EIO_MODEL_PRIVATE_H
|
||||
#define _EIO_MODEL_PRIVATE_H
|
||||
|
||||
#define PROP_LIST_SIZE 7
|
||||
|
||||
typedef struct _Eio_Model_Data Eio_Model_Data;
|
||||
typedef struct _Eio_Model_Monitor_Data Eio_Model_Monitor_Data;
|
||||
|
||||
struct _Eio_Model_Monitor_Data
|
||||
{
|
||||
Ecore_Event_Handler *ecore_child_add_handler[3];
|
||||
Ecore_Event_Handler *ecore_child_del_handler[3];
|
||||
int mon_event_child_add[3]; /**< plus EIO_MONITOR_ERROR */
|
||||
int mon_event_child_del[3]; /**< plus EIO_MONITOR_ERROR */
|
||||
};
|
||||
|
||||
enum {
|
||||
EIO_MODEL_PROP_FILENAME = 0,
|
||||
EIO_MODEL_PROP_PATH,
|
||||
EIO_MODEL_PROP_MTIME,
|
||||
EIO_MODEL_PROP_IS_DIR,
|
||||
EIO_MODEL_PROP_IS_LNK,
|
||||
EIO_MODEL_PROP_SIZE,
|
||||
EIO_MODEL_PROP_LAST
|
||||
};
|
||||
|
||||
static const char* _eio_model_prop_names[] =
|
||||
{
|
||||
[EIO_MODEL_PROP_FILENAME] = "filename",
|
||||
[EIO_MODEL_PROP_PATH] = "path",
|
||||
[EIO_MODEL_PROP_MTIME] = "mtime",
|
||||
[EIO_MODEL_PROP_IS_DIR] = "is_dir",
|
||||
[EIO_MODEL_PROP_IS_LNK] = "is_lnk",
|
||||
[EIO_MODEL_PROP_SIZE] = "size"
|
||||
};
|
||||
|
||||
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_List *children_list;
|
||||
/**< EIO data */
|
||||
Eio_File *file;
|
||||
Eina_Bool is_dir;
|
||||
Eio_Monitor *monitor;
|
||||
Eio_Model_Monitor_Data mon;
|
||||
int cb_count_child_add; /**< monitor reference counter for child add event */
|
||||
int cb_count_child_del; /**< monitor reference counter for child del event*/
|
||||
Eio_Filter_Direct_Cb filter_cb;
|
||||
void *filter_userdata;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,232 @@
|
|||
//Compile with:
|
||||
// gcc -o emodel_test_file emodel_test_file.c `pkg-config --cflags --libs emodel`
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eo.h>
|
||||
#include <Eio.h>
|
||||
#include <Ecore.h>
|
||||
#include <Efl.h>
|
||||
#include <eio_model.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
#define EFL_MODEL_TEST_FILENAME_PATH "/tmp"
|
||||
#define EFL_MODEL_MAX_TEST_CHILDS 16
|
||||
|
||||
/**
|
||||
* The following test works however
|
||||
* it is going to rename (move) the original directory to
|
||||
* new one so '/tmp' as root dir doesn't work , you'll need to use
|
||||
* '/tmp/some_other_dir' as root instead.
|
||||
*/
|
||||
//#define _RUN_LOCAL_TEST
|
||||
|
||||
struct reqs_t {
|
||||
/* property change */
|
||||
int changed_is_dir;
|
||||
int changed_is_lnk;
|
||||
int changed_size;
|
||||
int changed_mtime;
|
||||
|
||||
/* properties list */
|
||||
int proplist_filename;
|
||||
int proplist_path;
|
||||
int proplist_mtime;
|
||||
int proplist_is_dir;
|
||||
int proplist_is_lnk;
|
||||
int proplist_size;
|
||||
|
||||
/* misc tests for data or propeties */
|
||||
int properties;
|
||||
int children;
|
||||
int child_add;
|
||||
int child_del;
|
||||
};
|
||||
|
||||
static struct reqs_t reqs;
|
||||
static Ecore_Event_Handler *handler;
|
||||
|
||||
static Eina_Bool
|
||||
exit_func(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
|
||||
{
|
||||
Ecore_Event_Signal_Exit *e;
|
||||
|
||||
e = (Ecore_Event_Signal_Exit *)ev;
|
||||
if (e->interrupt) fprintf(stdout, "Exit: interrupt\n");
|
||||
else if (e->quit) fprintf(stdout, "Exit: quit\n");
|
||||
else if (e->terminate) fprintf(stdout, "Exit: terminate\n");
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_load_status_cb(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
|
||||
{
|
||||
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)
|
||||
printf("Properties is Loaded\n");
|
||||
|
||||
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");
|
||||
eo_do(obj, status = efl_model_property_get("filename", &value_prop));
|
||||
str = eina_value_to_string(value_prop);
|
||||
printf("efl_model_loaded filename %s, status=%d\n", str, status);
|
||||
free(str);
|
||||
|
||||
eo_do(obj, status = efl_model_property_get("size", &value_prop));
|
||||
str = eina_value_to_string(value_prop);
|
||||
printf("efl_model_loaded size %s, status=%d\n", str, status);
|
||||
free(str);
|
||||
|
||||
eo_do(obj, status = efl_model_property_get("mtime", &value_prop));
|
||||
str = eina_value_to_string(value_prop);
|
||||
printf("efl_model_loaded mtime %s, status=%d\n", str, status);
|
||||
free(str);
|
||||
|
||||
eo_do(obj, efl_model_children_count_get(&total));
|
||||
printf("efl_model_test count %d\n", (int)total);
|
||||
|
||||
/**< get full list */
|
||||
eo_do(obj, status = efl_model_children_slice_get(0 ,0 ,(Eina_Accessor **)&accessor));
|
||||
eina_accessor_free(accessor);
|
||||
eo_do(obj, status = efl_model_children_slice_get(5 ,5 ,(Eina_Accessor **)&accessor));
|
||||
eina_accessor_free(accessor);
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_properties_change_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
|
||||
{
|
||||
const Efl_Model_Property_Event *evt = (Efl_Model_Property_Event *)event_info;
|
||||
const char *prop;
|
||||
Eina_Array_Iterator it;
|
||||
unsigned int i;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
reqs.properties = 1;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_children_count_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
|
||||
{
|
||||
unsigned int *len = (unsigned int *)event_info;
|
||||
unsigned int total;
|
||||
|
||||
fprintf(stdout, "Children count number=%d\n", *len);
|
||||
reqs.children = *len;
|
||||
|
||||
eo_do(obj, efl_model_children_count_get(&total));
|
||||
fprintf(stdout, "New total children count number=%d\n", *len);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
START_TEST(eio_model_test_test_file)
|
||||
{
|
||||
Eo *filemodel = NULL;
|
||||
const Eina_Value *value_prop;
|
||||
Efl_Model_Load_Status status;
|
||||
#ifdef _RUN_LOCAL_TEST
|
||||
Eina_Value nameset_value;
|
||||
#endif
|
||||
Eina_Array *properties_list;
|
||||
Eina_Array_Iterator iterator;
|
||||
char *str;
|
||||
unsigned int i;
|
||||
|
||||
memset(&reqs, -1, sizeof(struct reqs_t));
|
||||
|
||||
fail_if(!eina_init(), "ERROR: Cannot init Eina!\n");
|
||||
fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
|
||||
fail_if(!eio_init(), "ERROR: Cannot init EIO!\n");
|
||||
|
||||
filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(EFL_MODEL_TEST_FILENAME_PATH));
|
||||
fail_if(!filemodel, "ERROR: Cannot init model!\n");
|
||||
|
||||
eo_do(filemodel, eo_event_callback_add(EFL_MODEL_BASE_EVENT_LOAD_STATUS, _load_status_cb, NULL));
|
||||
eo_do(filemodel, eo_event_callback_add(EFL_MODEL_BASE_EVENT_PROPERTIES_CHANGED, _properties_change_cb, NULL));
|
||||
eo_do(filemodel, eo_event_callback_add(EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, _children_count_cb, NULL));
|
||||
|
||||
eo_do(filemodel, efl_model_load());
|
||||
|
||||
handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
|
||||
|
||||
eo_do(filemodel, status = efl_model_property_get("filename", &value_prop));
|
||||
str = eina_value_to_string(value_prop);
|
||||
printf("efl_model_test filename %s, load status %d\n", str, status);
|
||||
|
||||
free(str);
|
||||
|
||||
i = 0;
|
||||
eo_do(filemodel, efl_model_properties_get(&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;
|
||||
}
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
#ifdef _RUN_LOCAL_TEST
|
||||
eina_value_setup(&nameset_value, EINA_VALUE_TYPE_STRING);
|
||||
eina_value_setup(&value_prop, EINA_VALUE_TYPE_STRING);
|
||||
eina_value_set(&nameset_value, "/tmp/efl_model_test");
|
||||
eo_do(filemodel, efl_model_property_set("path", &nameset_value));
|
||||
eina_value_flush(&nameset_value);
|
||||
eo_do(filemodel, status = efl_model_property_get("path", &value_prop));
|
||||
#endif
|
||||
|
||||
sleep(1); /**< EIO is asynchrounous so I must give some time for deletions to execute */
|
||||
eo_unref(filemodel);
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
eio_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eio_model_test_file(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, eio_model_test_test_file);
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
//Compile with:
|
||||
// gcc -o emodel_test_file emodel_test_file.c `pkg-config --cflags --libs emodel`
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eo.h>
|
||||
#include <Eio.h>
|
||||
#include <Ecore.h>
|
||||
#include <Efl.h>
|
||||
#include <eio_model.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
#define EFL_MODEL_TEST_FILENAME_PATH "/tmp"
|
||||
|
||||
Eina_Bool children_added = EINA_FALSE;
|
||||
|
||||
static Eina_Bool
|
||||
_load_monitor_status_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
|
||||
{
|
||||
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;
|
||||
|
||||
eo_do(obj, efl_model_property_get("filename", &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(strcmp(str, "test_file_monitor_add") == 0)
|
||||
{
|
||||
fprintf(stderr, "is child that we want\n");
|
||||
eo_do(obj, eo_event_callback_del(EFL_MODEL_BASE_EVENT_LOAD_STATUS, _load_monitor_status_cb, data));
|
||||
children_added = EINA_TRUE;
|
||||
eo_do(parent, efl_model_child_del(obj));
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_children_added_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
|
||||
{
|
||||
Efl_Model_Children_Event* evt = event_info;
|
||||
if (evt == NULL)
|
||||
return EINA_TRUE;
|
||||
|
||||
eo_do(evt->child, eo_event_callback_add(EFL_MODEL_BASE_EVENT_LOAD_STATUS, _load_monitor_status_cb, obj));
|
||||
eo_do(evt->child, efl_model_load());
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_children_count_cb(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
|
||||
{
|
||||
unsigned int *len = event_info;
|
||||
Eina_Accessor *accessor;
|
||||
Efl_Model_Load_Status status;
|
||||
Eo *child;
|
||||
unsigned int i = 0;
|
||||
|
||||
fprintf(stderr, "Children count number=%d\n", *len);
|
||||
|
||||
/**< get full list */
|
||||
eo_do(obj, status = efl_model_children_slice_get(0 ,0 ,(Eina_Accessor **)&accessor));
|
||||
if(accessor != NULL)
|
||||
{
|
||||
EINA_ACCESSOR_FOREACH(accessor, i, child) {}
|
||||
fprintf(stdout, "Got %d childs from Accessor. status=%d\n", i, status);
|
||||
}
|
||||
|
||||
fclose(fopen(EFL_MODEL_TEST_FILENAME_PATH "/test_file_monitor_add", "w+"));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
START_TEST(eio_model_test_test_monitor_add)
|
||||
{
|
||||
Eo *filemodel = NULL;
|
||||
|
||||
fprintf(stderr, "efl_model_test_test_monitor_add\n");
|
||||
|
||||
fail_if(!eina_init(), "ERROR: Cannot init Eina!\n");
|
||||
fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
|
||||
fail_if(!eio_init(), "ERROR: Cannot init EIO!\n");
|
||||
|
||||
filemodel = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(EFL_MODEL_TEST_FILENAME_PATH));
|
||||
fail_if(!filemodel, "ERROR: Cannot init model!\n");
|
||||
|
||||
eo_do(filemodel, eo_event_callback_add(EFL_MODEL_BASE_EVENT_CHILD_ADDED, _children_added_cb, NULL));
|
||||
eo_do(filemodel, eo_event_callback_add(EFL_MODEL_BASE_EVENT_CHILDREN_COUNT_CHANGED, _children_count_cb, NULL));
|
||||
|
||||
eo_do(filemodel, efl_model_load());
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
sleep(1); /**< EIO is asynchrounous so I must give some time for deletions to execute */
|
||||
|
||||
ecore_main_loop_iterate(); /**< Give time to unlink file */
|
||||
|
||||
eo_unref(filemodel);
|
||||
|
||||
eio_shutdown();
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
|
||||
fail_if(!children_added);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eio_model_test_monitor_add(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, eio_model_test_test_monitor_add);
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ struct _Eio_Test_Case
|
|||
|
||||
static const Eio_Test_Case etc[] = {
|
||||
{"Eio_Monitor", eio_test_monitor},
|
||||
{"Eio Model", eio_model_test_file},
|
||||
{"Eio Model Monitor", eio_model_test_monitor_add},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,5 +4,7 @@
|
|||
#include <check.h>
|
||||
|
||||
void eio_test_monitor(TCase *tc);
|
||||
void eio_model_test_file(TCase *tc);
|
||||
void eio_model_test_monitor_add(TCase *tc);
|
||||
|
||||
#endif /* _EIO_SUITE_H */
|
||||
|
|
Loading…
Reference in New Issue