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
This commit is contained in:
Gustavo Sverzut Barbieri 2008-12-06 03:41:03 +00:00
parent 2f8f874b20
commit a00eaac6a6
6 changed files with 90 additions and 39 deletions

View File

@ -20,6 +20,7 @@
#define EINA_ACCESSOR_H__
#include "eina_types.h"
#include "eina_magic.h"
/**
* @defgroup Eina_Accessor_Group Accessor Functions
@ -33,6 +34,25 @@
*/
typedef struct _Eina_Accessor Eina_Accessor;
typedef Eina_Bool (*Eina_Accessor_Get_At_Callback)(Eina_Accessor *it, unsigned int index, void **data);
typedef void *(*Eina_Accessor_Get_Container_Callback)(Eina_Accessor *it);
typedef void (*Eina_Accessor_Free_Callback)(Eina_Accessor *it);
struct _Eina_Accessor
{
#define EINA_MAGIC_ACCESSOR 0x98761232
EINA_MAGIC;
Eina_Accessor_Get_At_Callback get_at;
Eina_Accessor_Get_Container_Callback get_container;
Eina_Accessor_Free_Callback free;
};
#define FUNC_ACCESSOR_GET_AT(Function) ((Eina_Accessor_Get_At_Callback)Function)
#define FUNC_ACCESSOR_GET_CONTAINER(Function) ((Eina_Accessor_Get_Container_Callback)Function)
#define FUNC_ACCESSOR_FREE(Function) ((Eina_Accessor_Free_Callback)Function)
EAPI void eina_accessor_free (Eina_Accessor *accessor);
EAPI Eina_Bool eina_accessor_data_get (Eina_Accessor *accessor, unsigned int position, void **data);

View File

@ -20,6 +20,7 @@
#define EINA_ITERATOR_H__
#include "eina_types.h"
#include "eina_magic.h"
/**
* @defgroup Eina_Iterator_Group Iterator Functions
@ -33,6 +34,25 @@
*/
typedef struct _Eina_Iterator Eina_Iterator;
typedef Eina_Bool (*Eina_Iterator_Next_Callback)(Eina_Iterator *it, void **data);
typedef void *(*Eina_Iterator_Get_Container_Callback)(Eina_Iterator *it);
typedef void (*Eina_Iterator_Free_Callback)(Eina_Iterator *it);
struct _Eina_Iterator
{
#define EINA_MAGIC_ITERATOR 0x98761233
EINA_MAGIC;
Eina_Iterator_Next_Callback next;
Eina_Iterator_Get_Container_Callback get_container;
Eina_Iterator_Free_Callback free;
};
#define FUNC_ITERATOR_NEXT(Function) ((Eina_Iterator_Next_Callback)Function)
#define FUNC_ITERATOR_GET_CONTAINER(Function) ((Eina_Iterator_Get_Container_Callback)Function)
#define FUNC_ITERATOR_FREE(Function) ((Eina_Iterator_Free_Callback)Function)
EAPI void eina_iterator_free (Eina_Iterator *iterator);
EAPI void *eina_iterator_container_get (Eina_Iterator *iterator);

View File

@ -52,8 +52,8 @@ EAPI void eina_magic_fail(void *d, Eina_Magic m, Eina_Magic req_m,
#define eina_magic_string_get(Magic) (NULL)
#define eina_magic_string_set(Magic, Magic_Name) ((void) 0)
#define eina_magic_fail(d, m, req_m, file, fnx, line) ((void) 0)
#define eina_magic_string_init() (1)
#define eina_magic_string_shutdown() (0)
#define eina_magic_string_init() do {} while(0)
#define eina_magic_string_shutdown() do {} while(0)
#endif

View File

@ -50,9 +50,6 @@
#define READBUFSIZ 65536
/* eina magic types */
#define EINA_MAGIC_ITERATOR 0x98761233
#define EINA_MAGIC_ACCESSOR 0x98761232
#define EINA_MAGIC_STRINGSHARE 0x98761234
#define EINA_MAGIC_STRINGSHARE_NODE 0x98761235
#define EINA_MAGIC_STRINGSHARE_HEAD 0x98761236
@ -98,40 +95,6 @@
FREE(ptr); \
} while(0);
/* Iterator/accessor private type */
typedef Eina_Bool (*Eina_Iterator_Next_Callback)(Eina_Iterator *it, void **data);
typedef void *(*Eina_Iterator_Get_Container_Callback)(Eina_Iterator *it);
typedef void (*Eina_Iterator_Free_Callback)(Eina_Iterator *it);
#define FUNC_ITERATOR_NEXT(Function) ((Eina_Iterator_Next_Callback)Function)
#define FUNC_ITERATOR_GET_CONTAINER(Function) ((Eina_Iterator_Get_Container_Callback)Function)
#define FUNC_ITERATOR_FREE(Function) ((Eina_Iterator_Free_Callback)Function)
typedef Eina_Bool (*Eina_Accessor_Get_At_Callback)(Eina_Accessor *it, unsigned int index, void **data);
typedef void *(*Eina_Accessor_Get_Container_Callback)(Eina_Accessor *it);
typedef void (*Eina_Accessor_Free_Callback)(Eina_Accessor *it);
#define FUNC_ACCESSOR_GET_AT(Function) ((Eina_Accessor_Get_At_Callback)Function)
#define FUNC_ACCESSOR_GET_CONTAINER(Function) ((Eina_Accessor_Get_Container_Callback)Function)
#define FUNC_ACCESSOR_FREE(Function) ((Eina_Accessor_Free_Callback)Function)
struct _Eina_Iterator
{
EINA_MAGIC;
Eina_Iterator_Next_Callback next;
Eina_Iterator_Get_Container_Callback get_container;
Eina_Iterator_Free_Callback free;
};
struct _Eina_Accessor
{
EINA_MAGIC;
Eina_Accessor_Get_At_Callback get_at;
Eina_Accessor_Get_Container_Callback get_container;
Eina_Accessor_Free_Callback free;
};
#endif /* EINA_PRIVATE_H_ */

View File

@ -28,6 +28,25 @@
#include "eina_accessor.h"
#include "eina_private.h"
/*============================================================================*
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
#define EINA_MAGIC_CHECK_ACCESSOR(d) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ACCESSOR)) \
EINA_MAGIC_FAIL(d, EINA_MAGIC_ACCESSOR); \
} while(0);
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
@ -72,6 +91,7 @@
EAPI void
eina_accessor_free(Eina_Accessor *accessor)
{
EINA_MAGIC_CHECK_ACCESSOR(accessor);
if (accessor) accessor->free(accessor);
}
@ -87,6 +107,7 @@ eina_accessor_free(Eina_Accessor *accessor)
EAPI void *
eina_accessor_container_get(Eina_Accessor *accessor)
{
EINA_MAGIC_CHECK_ACCESSOR(accessor);
if (!accessor) return NULL;
return accessor->get_container(accessor);
}
@ -107,6 +128,7 @@ eina_accessor_container_get(Eina_Accessor *accessor)
EAPI Eina_Bool
eina_accessor_data_get(Eina_Accessor *accessor, unsigned int position, void **data)
{
EINA_MAGIC_CHECK_ACCESSOR(accessor);
if (!accessor) return EINA_FALSE;
return accessor->get_at(accessor, position, data);
}
@ -138,6 +160,8 @@ eina_accessor_over(Eina_Accessor *accessor,
void *data;
unsigned int i = start;
EINA_MAGIC_CHECK_ACCESSOR(accessor);
if (!accessor) return ;
if (!(start < end)) return ;

View File

@ -28,6 +28,25 @@
#include "eina_iterator.h"
#include "eina_private.h"
/*============================================================================*
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
#define EINA_MAGIC_CHECK_ITERATOR(d) \
do { \
if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ITERATOR)) \
EINA_MAGIC_FAIL(d, EINA_MAGIC_ITERATOR); \
} while(0);
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
@ -72,6 +91,7 @@
EAPI void
eina_iterator_free(Eina_Iterator *iterator)
{
EINA_MAGIC_CHECK_ITERATOR(iterator);
if (iterator) iterator->free(iterator);
}
@ -87,6 +107,7 @@ eina_iterator_free(Eina_Iterator *iterator)
EAPI void *
eina_iterator_container_get(Eina_Iterator *iterator)
{
EINA_MAGIC_CHECK_ITERATOR(iterator);
if (!iterator) return NULL;
return iterator->get_container(iterator);
}
@ -106,6 +127,7 @@ eina_iterator_container_get(Eina_Iterator *iterator)
EAPI Eina_Bool
eina_iterator_next(Eina_Iterator *iterator, void **data)
{
EINA_MAGIC_CHECK_ITERATOR(iterator);
if (!iterator) return EINA_FALSE;
return iterator->next(iterator, data);
}
@ -130,6 +152,8 @@ eina_iterator_foreach(Eina_Iterator *iterator,
void *container;
void *data;
EINA_MAGIC_CHECK_ITERATOR(iterator);
if (!iterator) return ;
container = iterator->get_container(iterator);