Eobj: eobj_generic_data_*->EOBJ_BASE_DATA_*.

And also split the base class away from eobj.c

SVN revision: 70267
This commit is contained in:
Tom Hacohen 2012-04-17 12:49:53 +00:00
parent bad7533b67
commit 2764023655
10 changed files with 316 additions and 226 deletions

View File

@ -30,7 +30,7 @@ _constructor(Eobj *obj, void *class_data __UNUSED__)
fail_if(eobj_composite_is(obj));
fail_if(!eobj_composite_is(simple));
eobj_generic_data_set(obj, "simple-obj", simple);
eobj_do(obj, EOBJ_BASE_DATA_SET("simple-obj", simple, NULL));
eobj_unref(simple);
}

View File

@ -37,7 +37,8 @@ main(int argc, char *argv[])
fail_if(a != 1);
/* disable the callback forwarder, and fail if it's still called. */
Eobj *simple = eobj_generic_data_get(obj, "simple-obj");
Eobj *simple;
eobj_do(obj, EOBJ_BASE_DATA_GET("simple-obj", (void **) &simple));
eobj_ref(simple);
eobj_event_callback_forwarder_del(simple, SIG_A_CHANGED, obj);

View File

@ -32,14 +32,16 @@ const Eobj_Class *evas_object_class_get(void) EINA_CONST;
static inline Evas_Object *
eobj_evas_object_get(Eobj *obj)
{
return eobj_generic_data_get(obj, EVAS_OBJ_STR);
void *data;
eobj_do(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data));
return data;
}
/* FIXME: Hack in the meanwhile. */
static inline void
eobj_evas_object_set(Eobj *obj, Evas_Object *evas_obj)
{
eobj_generic_data_set(obj, EVAS_OBJ_STR, evas_obj);
eobj_do(obj, EOBJ_BASE_DATA_SET(EVAS_OBJ_STR, evas_obj, NULL));
}
#endif

View File

@ -70,7 +70,7 @@ _constructor(Eobj *obj, void *class_data __UNUSED__)
eobj_event_callback_add(obj, EOBJ_EV_CALLBACK_ADD, _cb_added, NULL);
eobj_event_callback_add(obj, EOBJ_EV_CALLBACK_DEL, _cb_deled, NULL);
eobj_generic_data_set(obj, "cb_count", (intptr_t) 0);
eobj_do(obj, EOBJ_BASE_DATA_SET("cb_count", (intptr_t) 0, NULL));
}
static void

View File

@ -1,5 +1,6 @@
LIST(APPEND EOBJ_CC_SOURCES
eobj.c
eobj_base_class.c
)
include_directories(

View File

@ -407,40 +407,6 @@ EAPI int eobj_ref_get(const Eobj *obj);
*/
EAPI void eobj_del(Eobj *obj);
/**
* @brief Set generic data to object.
* @param obj the object to work on.
* @param key the key associated with the data
* @param data the data to set.
* @return the previous data associated with the key.
*
* @see eobj_generic_data_get()
* @see eobj_generic_data_del()
*/
EAPI void *eobj_generic_data_set(Eobj *obj, const char *key, const void *data);
/**
* @brief Get generic data from object.
* @param obj the object to work on.
* @param key the key associated with the data
* @return the data associated with the key.
*
* @see eobj_generic_data_set()
* @see eobj_generic_data_del()
*/
EAPI void *eobj_generic_data_get(const Eobj *obj, const char *key);
/**
* @brief Del generic data from object.
* @param obj the object to work on.
* @param key the key associated with the data
* @return the data previously associated with the key.
*
* @see eobj_generic_data_set()
* @see eobj_generic_data_get()
*/
EAPI void *eobj_generic_data_del(Eobj *obj, const char *key);
/**
* @var _EOBJ_EV_FREE
* see #EOBJ_EV_FREE
@ -682,6 +648,65 @@ EAPI extern const Eobj_Event_Description _EOBJ_EV_CALLBACK_DEL;
* */
EAPI const Eobj_Class *eobj_base_class_get(void) EINA_CONST;
/**
* @typedef eobj_base_data_free_func
* Data free func prototype.
*/
typedef void (*eobj_base_data_free_func)(void *);
/**
* @var EOBJ_BASE_BASE_ID
* #EOBJ_BASE_CLASS 's base id.
*/
extern EAPI Eobj_Op EOBJ_BASE_BASE_ID;
enum {
EOBJ_BASE_SUB_ID_DATA_SET,
EOBJ_BASE_SUB_ID_DATA_GET,
EOBJ_BASE_SUB_ID_DATA_DEL,
EOBJ_BASE_SUB_ID_LAST
};
/**
* @def EOBJ_BASE_ID(sub_id)
* Helper macro to get the full Op ID out of the sub_id for EOBJ_BASE.
* @param sub_id the sub id inside EOBJ_BASE.
*/
#define EOBJ_BASE_ID(sub_id) (EOBJ_BASE_BASE_ID + sub_id)
/**
* @def EOBJ_BASE_DATA_SET(key, data, free_func)
* Set generic data to object.
* @param key the key associated with the data
* @param data the data to set.
* @param free_func the func to free data with (NULL means "do nothing").
*
* @see #EOBJ_BASE_DATA_GET
* @see #EOBJ_BASE_DATA_DEL
*/
#define EOBJ_BASE_DATA_SET(key, data, free_func) EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_SET), EOBJ_TYPECHECK(const char *, key), EOBJ_TYPECHECK(const void *, data), EOBJ_TYPECHECK(eobj_base_data_free_func, free_func)
/**
* @def EOBJ_BASE_DATA_GET(key, data)
* Get generic data from object.
* @param key the key associated with the data
* @param data the data for the key
*
* @see #EOBJ_BASE_DATA_SET
* @see #EOBJ_BASE_DATA_DEL
*/
#define EOBJ_BASE_DATA_GET(key, data) EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), EOBJ_TYPECHECK(const char *, key), EOBJ_TYPECHECK(void **, data)
/**
* @def EOBJ_BASE_DATA_DEL(key)
* Get generic data from object.
* @param key the key associated with the data
*
* @see #EOBJ_BASE_DATA_SET
* @see #EOBJ_BASE_DATA_DEL
*/
#define EOBJ_BASE_DATA_DEL(key) EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_DEL), EOBJ_TYPECHECK(const char *, key)
/**
* @}
*/

View File

@ -1,48 +1,23 @@
#include <Eina.h>
#include "Eobj.h"
#include "eobj_private.h"
#include "config.h"
typedef int Eobj_Class_Id;
static int _eobj_log_dom = -1;
int _eobj_log_dom = -1;
static Eobj_Class **_eobj_classes;
static Eobj_Class_Id _eobj_classes_last_id;
static Eina_Bool _eobj_init_count = 0;
static void _eobj_callback_remove_all(Eobj *obj);
static void _eobj_generic_data_del_all(Eobj *obj);
static void eobj_class_constructor(Eobj *obj, const Eobj_Class *klass);
static void eobj_class_destructor(Eobj *obj, const Eobj_Class *klass);
static void eobj_constructor_error_unset(Eobj *obj);
#ifdef CRITICAL
#undef CRITICAL
#endif
#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eobj_log_dom, __VA_ARGS__)
#ifdef ERR
#undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_eobj_log_dom, __VA_ARGS__)
#ifdef WRN
#undef WRN
#endif
#define WRN(...) EINA_LOG_DOM_WARN(_eobj_log_dom, __VA_ARGS__)
#ifdef INF
#undef INF
#endif
#define INF(...) EINA_LOG_DOM_INFO(_eobj_log_dom, __VA_ARGS__)
#ifdef DBG
#undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_eobj_log_dom, __VA_ARGS__)
typedef struct _Eobj_Callback_Description Eobj_Callback_Description;
struct _Eobj {
@ -56,8 +31,6 @@ struct _Eobj {
Eina_Inlist *callbacks;
int walking_list;
Eina_Inlist *generic_data;
Eina_Inlist *kls_itr;
Eina_Bool delete:1;
@ -846,8 +819,6 @@ eobj_unref(Eobj *obj)
if (obj->data_blob)
free(obj->data_blob);
_eobj_generic_data_del_all(obj);
free(obj);
}
}
@ -952,97 +923,6 @@ eobj_data_get(Eobj *obj, const Eobj_Class *klass)
return NULL;
}
typedef struct
{
EINA_INLIST;
Eina_Stringshare *key;
void *data;
} Eobj_Generic_Data_Node;
static void
_eobj_generic_data_node_free(Eobj_Generic_Data_Node *node)
{
eina_stringshare_del(node->key);
free(node);
}
static void
_eobj_generic_data_del_all(Eobj *obj)
{
Eina_Inlist *nnode;
Eobj_Generic_Data_Node *node;
EINA_INLIST_FOREACH_SAFE(obj->generic_data, nnode, node)
{
obj->generic_data = eina_inlist_remove(obj->generic_data,
EINA_INLIST_GET(node));
_eobj_generic_data_node_free(node);
}
}
EAPI void *
eobj_generic_data_set(Eobj *obj, const char *key, const void *data)
{
void *prev_data;
Eobj_Generic_Data_Node *node;
if (!key) return NULL;
if (!data) return NULL;
prev_data = eobj_generic_data_del(obj, key);
node = malloc(sizeof(Eobj_Generic_Data_Node));
node->key = eina_stringshare_add(key);
node->data = (void *) data;
obj->generic_data = eina_inlist_prepend(obj->generic_data,
EINA_INLIST_GET(node));
return prev_data;
}
EAPI void *
eobj_generic_data_get(const Eobj *obj, const char *key)
{
Eobj_Generic_Data_Node *node;
if (!key) return NULL;
EINA_INLIST_FOREACH(obj->generic_data, node)
{
if (!strcmp(node->key, key))
{
((Eobj *) obj)->generic_data =
eina_inlist_promote(obj->generic_data, EINA_INLIST_GET(node));
return node->data;
}
}
return NULL;
}
EAPI void *
eobj_generic_data_del(Eobj *obj, const char *key)
{
Eobj_Generic_Data_Node *node;
if (!key) return NULL;
EINA_INLIST_FOREACH(obj->generic_data, node)
{
if (!strcmp(node->key, key))
{
void *data;
data = node->data;
obj->generic_data = eina_inlist_remove(obj->generic_data,
EINA_INLIST_GET(node));
_eobj_generic_data_node_free(node);
return data;
}
}
return NULL;
}
EAPI Eina_Bool
eobj_init(void)
{
@ -1312,56 +1192,3 @@ eobj_event_callback_forwarder_del(Eobj *obj, const Eobj_Event_Description *desc,
return EINA_TRUE;
}
/* EOBJ_CLASS_BASE stuff */
static const Eobj_Class *_my_class = NULL;
/* FIXME: Set proper type descriptions. */
EAPI const Eobj_Event_Description _EOBJ_EV_CALLBACK_ADD =
EOBJ_EVENT_DESCRIPTION("callback,add", "?", "A callback was added.");
EAPI const Eobj_Event_Description _EOBJ_EV_CALLBACK_DEL =
EOBJ_EVENT_DESCRIPTION("callback,del", "?", "A callback was deleted.");
EAPI const Eobj_Event_Description _EOBJ_EV_FREE =
EOBJ_EVENT_DESCRIPTION("free", "", "Obj is being freed.");
EAPI const Eobj_Event_Description _EOBJ_EV_DEL =
EOBJ_EVENT_DESCRIPTION("del", "", "Obj is being deleted.");
static void
_constructor(Eobj *obj, void *class_data __UNUSED__)
{
DBG("%p - %s.", obj, _my_class->desc->name);
}
static void
_destructor(Eobj *obj, void *class_data __UNUSED__)
{
DBG("%p - %s.", obj, _my_class->desc->name);
}
EAPI const Eobj_Class *
eobj_base_class_get(void)
{
if (_my_class) return _my_class;
static const Eobj_Event_Description *event_desc[] = {
EOBJ_EV_CALLBACK_ADD,
EOBJ_EV_CALLBACK_DEL,
EOBJ_EV_FREE,
EOBJ_EV_DEL,
NULL
};
static const Eobj_Class_Description class_desc = {
"Eobj Base",
EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT,
EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
event_desc,
0,
_constructor,
_destructor,
NULL,
NULL
};
return _my_class = eobj_class_new(&class_desc, NULL, NULL);
}

View File

@ -0,0 +1,190 @@
#include <Eina.h>
#include "Eobj.h"
#include "eobj_private.h"
#include "config.h"
EAPI Eobj_Op EOBJ_BASE_BASE_ID = EOBJ_NOOP;
typedef struct
{
Eina_Inlist *generic_data;
} Private_Data;
typedef struct
{
EINA_INLIST;
Eina_Stringshare *key;
void *data;
eobj_base_data_free_func free_func;
} Eobj_Generic_Data_Node;
static void
_eobj_generic_data_node_free(Eobj_Generic_Data_Node *node)
{
eina_stringshare_del(node->key);
if (node->free_func)
node->free_func(node->data);
free(node);
}
static void
_eobj_generic_data_del_all(Private_Data *pd)
{
Eina_Inlist *nnode;
Eobj_Generic_Data_Node *node;
EINA_INLIST_FOREACH_SAFE(pd->generic_data, nnode, node)
{
pd->generic_data = eina_inlist_remove(pd->generic_data,
EINA_INLIST_GET(node));
_eobj_generic_data_node_free(node);
}
}
static void
_data_set(Eobj *obj, void *class_data, va_list *list)
{
Private_Data *pd = class_data;
const char *key = va_arg(*list, const char *);
const void *data = va_arg(*list, const void *);
eobj_base_data_free_func free_func = va_arg(*list, eobj_base_data_free_func);
Eobj_Generic_Data_Node *node;
if (!key) return;
eobj_do(obj, EOBJ_BASE_DATA_DEL(key));
node = malloc(sizeof(Eobj_Generic_Data_Node));
node->key = eina_stringshare_add(key);
node->data = (void *) data;
node->free_func = free_func;
pd->generic_data = eina_inlist_prepend(pd->generic_data,
EINA_INLIST_GET(node));
}
static void
_data_get(Eobj *obj __UNUSED__, void *class_data, va_list *list)
{
Private_Data *pd = class_data;
const char *key = va_arg(*list, const char *);
void **data = va_arg(*list, void **);
Eobj_Generic_Data_Node *node;
if (!data) return;
*data = NULL;
if (!key) return;
EINA_INLIST_FOREACH(pd->generic_data, node)
{
if (!strcmp(node->key, key))
{
pd->generic_data =
eina_inlist_promote(pd->generic_data, EINA_INLIST_GET(node));
*data = node->data;
return;
}
}
}
static void
_data_del(Eobj *obj __UNUSED__, void *class_data, va_list *list)
{
Private_Data *pd = class_data;
const char *key = va_arg(*list, const char *);
Eobj_Generic_Data_Node *node;
if (!key) return;
EINA_INLIST_FOREACH(pd->generic_data, node)
{
if (!strcmp(node->key, key))
{
pd->generic_data = eina_inlist_remove(pd->generic_data,
EINA_INLIST_GET(node));
_eobj_generic_data_node_free(node);
return;
}
}
}
/* EOBJ_CLASS_BASE stuff */
static const Eobj_Class *_my_class = NULL;
/* FIXME: Set proper type descriptions. */
EAPI const Eobj_Event_Description _EOBJ_EV_CALLBACK_ADD =
EOBJ_EVENT_DESCRIPTION("callback,add", "?", "A callback was added.");
EAPI const Eobj_Event_Description _EOBJ_EV_CALLBACK_DEL =
EOBJ_EVENT_DESCRIPTION("callback,del", "?", "A callback was deleted.");
EAPI const Eobj_Event_Description _EOBJ_EV_FREE =
EOBJ_EVENT_DESCRIPTION("free", "", "Obj is being freed.");
EAPI const Eobj_Event_Description _EOBJ_EV_DEL =
EOBJ_EVENT_DESCRIPTION("del", "", "Obj is being deleted.");
static void
_constructor(Eobj *obj, void *class_data __UNUSED__)
{
DBG("%p - %s.", obj, eobj_class_name_get(_my_class));
}
static void
_destructor(Eobj *obj, void *class_data)
{
DBG("%p - %s.", obj, eobj_class_name_get(_my_class));
_eobj_generic_data_del_all(class_data);
}
static void
_class_constructor(Eobj_Class *klass)
{
const Eobj_Op_Func_Description func_desc[] = {
EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_SET), _data_set),
EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get),
EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_DEL), _data_del),
EOBJ_OP_FUNC_SENTINEL
};
eobj_class_funcs_set(klass, func_desc);
}
EAPI const Eobj_Class *
eobj_base_class_get(void)
{
if (_my_class) return _my_class;
static const Eobj_Op_Description op_desc[] = {
EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_SET, "?", "Set data for key."),
EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."),
EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_DEL, "?", "Del key."),
EOBJ_OP_DESCRIPTION_SENTINEL
};
static const Eobj_Event_Description *event_desc[] = {
EOBJ_EV_CALLBACK_ADD,
EOBJ_EV_CALLBACK_DEL,
EOBJ_EV_FREE,
EOBJ_EV_DEL,
NULL
};
static const Eobj_Class_Description class_desc = {
"Eobj Base",
EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT,
EOBJ_CLASS_DESCRIPTION_OPS(&EOBJ_BASE_BASE_ID, op_desc, EOBJ_BASE_SUB_ID_LAST),
event_desc,
sizeof(Private_Data),
_constructor,
_destructor,
_class_constructor,
NULL
};
return _my_class = eobj_class_new(&class_desc, NULL, NULL);
}

View File

@ -0,0 +1,32 @@
#ifndef _EOBJ_PRIVATE_H
#define _EOBJ_PRIVATE_H
extern int _eobj_log_dom;
#ifdef CRITICAL
#undef CRITICAL
#endif
#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eobj_log_dom, __VA_ARGS__)
#ifdef ERR
#undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_eobj_log_dom, __VA_ARGS__)
#ifdef WRN
#undef WRN
#endif
#define WRN(...) EINA_LOG_DOM_WARN(_eobj_log_dom, __VA_ARGS__)
#ifdef INF
#undef INF
#endif
#define INF(...) EINA_LOG_DOM_INFO(_eobj_log_dom, __VA_ARGS__)
#ifdef DBG
#undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_eobj_log_dom, __VA_ARGS__)
#endif

View File

@ -53,21 +53,33 @@ START_TEST(eobj_generic_data)
{
eobj_init();
Eobj *obj = eobj_add(SIMPLE_CLASS, NULL);
void *data;
eobj_generic_data_set(obj, "test1", (void *) 1);
fail_if(1 != (int) eobj_generic_data_get(obj, "test1"));
fail_if(1 != (int) eobj_generic_data_del(obj, "test1"));
fail_if(eobj_generic_data_del(obj, "test1"));
eobj_do(obj, EOBJ_BASE_DATA_SET("test1", (void *) 1, NULL));
eobj_do(obj, EOBJ_BASE_DATA_GET("test1", &data));
fail_if(1 != (int) data);
eobj_do(obj, EOBJ_BASE_DATA_DEL("test1"));
eobj_do(obj, EOBJ_BASE_DATA_GET("test1", &data));
fail_if(data);
eobj_generic_data_set(obj, "test1", (void *) 1);
eobj_generic_data_set(obj, "test2", (void *) 2);
fail_if(2 != (int) eobj_generic_data_get(obj, "test2"));
fail_if(2 != (int) eobj_generic_data_del(obj, "test2"));
fail_if(eobj_generic_data_del(obj, "test2"));
eobj_do(obj, EOBJ_BASE_DATA_SET("test1", (void *) 1, NULL));
eobj_do(obj, EOBJ_BASE_DATA_SET("test2", (void *) 2, NULL));
eobj_do(obj, EOBJ_BASE_DATA_GET("test1", &data));
fail_if(1 != (int) data);
eobj_do(obj, EOBJ_BASE_DATA_GET("test2", &data));
fail_if(2 != (int) data);
fail_if(1 != (int) eobj_generic_data_get(obj, "test1"));
fail_if(1 != (int) eobj_generic_data_del(obj, "test1"));
fail_if(eobj_generic_data_del(obj, "test1"));
eobj_do(obj, EOBJ_BASE_DATA_GET("test2", &data));
fail_if(2 != (int) data);
eobj_do(obj, EOBJ_BASE_DATA_DEL("test2"));
eobj_do(obj, EOBJ_BASE_DATA_GET("test2", &data));
fail_if(data);
eobj_do(obj, EOBJ_BASE_DATA_GET("test1", &data));
fail_if(1 != (int) data);
eobj_do(obj, EOBJ_BASE_DATA_DEL("test1"));
eobj_do(obj, EOBJ_BASE_DATA_GET("test1", &data));
fail_if(data);
eobj_unref(obj);
eobj_shutdown();