2008-08-11 09:30:16 -07:00
|
|
|
/* EINA - EFL data type library
|
|
|
|
* Copyright (C) 2008 Cedric Bail
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef EINA_ACCESSOR_H__
|
|
|
|
#define EINA_ACCESSOR_H__
|
|
|
|
|
2008-12-08 02:51:51 -08:00
|
|
|
#include "eina_config.h"
|
|
|
|
|
2008-08-11 09:30:16 -07:00
|
|
|
#include "eina_types.h"
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
#include "eina_magic.h"
|
2008-08-11 09:30:16 -07:00
|
|
|
|
2011-04-07 03:38:25 -07:00
|
|
|
/**
|
|
|
|
* @addtogroup Eina_Accessor_Group Accessor Functions
|
|
|
|
*
|
|
|
|
* @brief These functions manage accessor on containers.
|
|
|
|
*
|
|
|
|
* These functions allow to access elements of a container in a
|
|
|
|
* generic way, without knowing which container is used (a bit like
|
|
|
|
* iterators in the C++ STL). Accessors allows random access (that is, any
|
|
|
|
* element in the container). For sequential access, see
|
|
|
|
* @ref Eina_Iterator_Group.
|
|
|
|
*
|
|
|
|
* An accessor is created from container data types, so no creation
|
|
|
|
* function is available here. An accessor is deleted with
|
|
|
|
* eina_accessor_free(). To get the data of an element at a given
|
|
|
|
* position, use eina_accessor_data_get(). To call a function on
|
|
|
|
* chosen elements of a container, use eina_accessor_over().
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2009-06-22 13:03:58 -07:00
|
|
|
/**
|
|
|
|
* @addtogroup Eina_Content_Access_Group Content Access
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2008-09-07 00:19:19 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Eina_Accessor_Group Accessor Functions
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef Eina_Accessor
|
2010-11-06 05:34:55 -07:00
|
|
|
* Abstract type for accessors.
|
2008-09-07 00:19:19 -07:00
|
|
|
*/
|
2008-08-11 09:30:16 -07:00
|
|
|
typedef struct _Eina_Accessor Eina_Accessor;
|
|
|
|
|
2010-11-06 05:34:55 -07:00
|
|
|
/**
|
|
|
|
* @typedef Eina_Accessor_Get_At_Callback
|
|
|
|
* Type for a callback that returns the data of a container as the given index.
|
|
|
|
*/
|
|
|
|
typedef Eina_Bool (*Eina_Accessor_Get_At_Callback)(Eina_Accessor *it,
|
|
|
|
unsigned int index,
|
|
|
|
void **data);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef Eina_Accessor_Get_Container_Callback
|
|
|
|
* Type for a callback that returns the container.
|
|
|
|
*/
|
|
|
|
typedef void *(*Eina_Accessor_Get_Container_Callback)(Eina_Accessor *it);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef Eina_Accessor_Free_Callback
|
|
|
|
* Type for a callback that frees the container.
|
|
|
|
*/
|
|
|
|
typedef void (*Eina_Accessor_Free_Callback)(Eina_Accessor *it);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef Eina_Accessor_Lock_Callback
|
|
|
|
* Type for a callback that lock the container.
|
|
|
|
*/
|
2010-08-11 07:32:30 -07:00
|
|
|
typedef Eina_Bool (*Eina_Accessor_Lock_Callback)(Eina_Accessor *it);
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
|
|
|
|
struct _Eina_Accessor
|
|
|
|
{
|
2010-08-19 05:02:28 -07:00
|
|
|
#define EINA_ACCESSOR_VERSION 1
|
2010-11-06 05:34:55 -07:00
|
|
|
int version; /**< Version of the Accessor API. */
|
2010-08-19 05:02:28 -07:00
|
|
|
|
2010-11-06 05:34:55 -07:00
|
|
|
Eina_Accessor_Get_At_Callback get_at EINA_ARG_NONNULL(1, 3) EINA_WARN_UNUSED_RESULT; /**< Callback called when a data element is requested. */
|
|
|
|
Eina_Accessor_Get_Container_Callback get_container EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; /**< Callback called when the container is requested. */
|
|
|
|
Eina_Accessor_Free_Callback free EINA_ARG_NONNULL(1); /**< Callback called when the container is freed. */
|
2008-12-05 22:53:14 -08:00
|
|
|
|
2010-11-06 05:34:55 -07:00
|
|
|
Eina_Accessor_Lock_Callback lock EINA_WARN_UNUSED_RESULT; /**< Callback called when the container is locked. */
|
|
|
|
Eina_Accessor_Lock_Callback unlock EINA_WARN_UNUSED_RESULT; /**< Callback called when the container is unlocked. */
|
2010-08-11 07:32:30 -07:00
|
|
|
|
2008-12-05 22:53:14 -08:00
|
|
|
#define EINA_MAGIC_ACCESSOR 0x98761232
|
* eina/src/include/eina_array.h,
* eina/src/include/eina_f16p16.h,
* eina/src/include/eina_accessor.h,
* eina/src/include/eina_list.h,
* eina/src/include/eina_iterator.h,
* eina/src/lib/eina_rectangle.c,
* eina/src/lib/eina_list.c,
* eina/src/lib/eina_array.c,
* eina/src/lib/eina_hash.c,
* eina/src/lib/eina_module.c,
* eina/src/lib/eina_stringshare.c,
* eina/src/lib/eina_benchmark.c: Fix for windows compilation.
SVN revision: 38663
2009-01-20 07:56:48 -08:00
|
|
|
EINA_MAGIC
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
};
|
|
|
|
|
2010-11-06 05:34:55 -07:00
|
|
|
/**
|
|
|
|
* @def FUNC_ACCESSOR_GET_AT(Function)
|
|
|
|
* Helper macro to cast @p Function to a Eina_Accessor_Get_At_Callback.
|
|
|
|
*/
|
2010-10-22 23:41:45 -07:00
|
|
|
#define FUNC_ACCESSOR_GET_AT(Function) ((Eina_Accessor_Get_At_Callback)Function)
|
2010-11-06 05:34:55 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @def FUNC_ACCESSOR_GET_CONTAINER(Function)
|
|
|
|
* Helper macro to cast @p Function to a Eina_Accessor_Get_Container_Callback.
|
|
|
|
*/
|
2010-08-12 23:36:33 -07:00
|
|
|
#define FUNC_ACCESSOR_GET_CONTAINER(Function) ((Eina_Accessor_Get_Container_Callback)Function)
|
2010-11-06 05:34:55 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @def FUNC_ACCESSOR_FREE(Function)
|
|
|
|
* Helper macro to cast @p Function to a Eina_Accessor_Free_Callback.
|
|
|
|
*/
|
2010-10-22 23:41:45 -07:00
|
|
|
#define FUNC_ACCESSOR_FREE(Function) ((Eina_Accessor_Free_Callback)Function)
|
2010-11-06 05:34:55 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @def FUNC_ACCESSOR_LOCK(Function)
|
|
|
|
* Helper macro to cast @p Function to a Eina_Iterator_Lock_Callback.
|
|
|
|
*/
|
2010-10-22 23:41:45 -07:00
|
|
|
#define FUNC_ACCESSOR_LOCK(Function) ((Eina_Accessor_Lock_Callback)Function)
|
Make it possible to create iterators outside Eina.
Many places in EFL we just create walk something, create a list with
walked data, return, then the user walks it again and then deletes
(which will walk again). For such cases it's way better to define
iterators or accessors.
I'm not moving any EFL code to it now, but if people are interested,
things like evas_render_method_list(), evas_font_available_list(),
evas_objects_at_xy_get(), evas_objects_in_rectangle_get(),
evas_object_smart_members_get() are good candidates. If the subject is
already using Eina list, then you can just use
eina_list_iterator_new() and return it, otherwise you can define your
own iterator, which is very easy.
SVN revision: 37956
2008-12-05 19:41:03 -08:00
|
|
|
|
2011-04-07 03:38:25 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Free an accessor.
|
|
|
|
*
|
|
|
|
* @param accessor The accessor to free.
|
|
|
|
*
|
|
|
|
* This function frees @p accessor if it is not @c NULL;
|
|
|
|
*/
|
2010-08-12 23:36:33 -07:00
|
|
|
EAPI void eina_accessor_free(Eina_Accessor *accessor) EINA_ARG_NONNULL(1);
|
2010-08-16 08:02:37 -07:00
|
|
|
EAPI Eina_Bool eina_accessor_data_get(Eina_Accessor *accessor,
|
2010-10-22 23:41:45 -07:00
|
|
|
unsigned int position,
|
|
|
|
void **data) EINA_ARG_NONNULL(1);
|
|
|
|
EAPI void *eina_accessor_container_get(Eina_Accessor *accessor) EINA_ARG_NONNULL(1) EINA_PURE;
|
|
|
|
EAPI void eina_accessor_over(Eina_Accessor *accessor,
|
|
|
|
Eina_Each_Cb cb,
|
|
|
|
unsigned int start,
|
|
|
|
unsigned int end,
|
|
|
|
const void *fdata) EINA_ARG_NONNULL(1, 2);
|
2010-08-11 07:32:30 -07:00
|
|
|
EAPI Eina_Bool eina_accessor_lock(Eina_Accessor *accessor) EINA_ARG_NONNULL(1);
|
|
|
|
EAPI Eina_Bool eina_accessor_unlock(Eina_Accessor *accessor) EINA_ARG_NONNULL(1);
|
|
|
|
|
2009-02-27 08:32:22 -08:00
|
|
|
/**
|
|
|
|
* @def EINA_ACCESSOR_FOREACH
|
|
|
|
* @brief Macro to iterate over all elements easily.
|
|
|
|
*
|
|
|
|
* @param accessor The accessor to use.
|
2009-06-22 13:03:58 -07:00
|
|
|
* @param counter A counter used by eina_accessor_data_get() when
|
|
|
|
* iterating over the container.
|
2009-02-27 08:32:22 -08:00
|
|
|
* @param data Where to store * data, must be a pointer support getting
|
2009-06-22 13:03:58 -07:00
|
|
|
* its address since * eina_accessor_data_get() requires a pointer to
|
|
|
|
* pointer!
|
2009-02-27 08:32:22 -08:00
|
|
|
*
|
2009-06-22 13:03:58 -07:00
|
|
|
* This macro allows a convenient way to loop over all elements in an
|
2009-02-27 08:32:22 -08:00
|
|
|
* accessor, very similar to EINA_LIST_FOREACH().
|
|
|
|
*
|
|
|
|
* This macro can be used for freeing the data of a list, like in the
|
|
|
|
* following example. It has the same goal as the one documented in
|
|
|
|
* EINA_LIST_FOREACH(), but using accessors:
|
|
|
|
*
|
|
|
|
* @code
|
|
|
|
* Eina_List *list;
|
|
|
|
* Eina_Accessor *accessor;
|
|
|
|
* unsigned int i;
|
|
|
|
* char *data;
|
|
|
|
*
|
|
|
|
* // list is already filled,
|
|
|
|
* // its elements are just duplicated strings
|
|
|
|
*
|
|
|
|
* accessor = eina_list_accessor_new(list);
|
|
|
|
* EINA_ACCESSOR_FOREACH(accessor, i, data)
|
|
|
|
* free(data);
|
|
|
|
* eina_accessor_free(accessor);
|
|
|
|
* eina_list_free(list);
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* @note if the datatype provides both iterators and accessors prefer
|
|
|
|
* to use iterators to iterate over, as they're likely to be more
|
|
|
|
* optimized for such task.
|
|
|
|
*
|
|
|
|
* @note this example is not optimal algorithm to release a list since
|
|
|
|
* it will walk the list twice, but it serves as an example. For
|
|
|
|
* optimized version use EINA_LIST_FREE()
|
|
|
|
*
|
|
|
|
* @warning unless explicitly stated in functions returning accessors,
|
|
|
|
* do not modify the accessed object while you walk it, in this
|
|
|
|
* example using lists, do not remove list nodes or you might
|
|
|
|
* crash! This is not a limitiation of accessors themselves,
|
|
|
|
* rather in the accessors implementations to keep them as simple
|
|
|
|
* and fast as possible.
|
|
|
|
*/
|
2010-10-22 23:41:45 -07:00
|
|
|
#define EINA_ACCESSOR_FOREACH(accessor, counter, data) \
|
|
|
|
for ((counter) = 0; \
|
2010-12-15 03:56:50 -08:00
|
|
|
eina_accessor_data_get((accessor), (counter), (void **)(void *)&(data)); \
|
2010-08-16 08:02:37 -07:00
|
|
|
(counter)++)
|
2009-02-27 08:32:22 -08:00
|
|
|
|
2009-06-22 13:03:58 -07:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2008-09-07 00:19:19 -07:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2008-08-11 09:30:16 -07:00
|
|
|
#endif
|