2013-12-25 06:13:41 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <Eina.h>
|
|
|
|
|
2013-12-25 06:19:07 -08:00
|
|
|
#include "Eo.h"
|
2013-12-25 06:13:41 -08:00
|
|
|
#include "eo_ptr_indirection.h"
|
|
|
|
#include "eo_private.h"
|
|
|
|
|
|
|
|
static int event_freeze_count = 0;
|
|
|
|
|
|
|
|
typedef struct _Eo_Callback_Description Eo_Callback_Description;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2013-12-26 12:11:48 -08:00
|
|
|
Eina_List *children;
|
|
|
|
Eo *parent;
|
2014-07-06 04:15:21 -07:00
|
|
|
Eina_List *parent_list;
|
2013-12-26 12:11:48 -08:00
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
Eina_Inlist *generic_data;
|
|
|
|
Eo ***wrefs;
|
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
Eina_Inarray *callbacks;
|
2013-12-25 06:13:41 -08:00
|
|
|
unsigned short walking_list;
|
|
|
|
unsigned short event_freeze_count;
|
|
|
|
Eina_Bool deletions_waiting : 1;
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2015-03-30 07:46:44 -07:00
|
|
|
//clock_t call_updated;
|
|
|
|
|
2015-03-25 09:44:45 -07:00
|
|
|
//for benchmark start
|
|
|
|
unsigned int called_counter;
|
|
|
|
unsigned int callbacks_counter;
|
|
|
|
unsigned int called_loop_counter;
|
|
|
|
unsigned int called_inner_loop_counter;
|
|
|
|
unsigned int arrays_counter;
|
|
|
|
clock_t called_sum_clocks ;
|
|
|
|
|
|
|
|
unsigned int events_counter;
|
|
|
|
unsigned long long int have_events;
|
|
|
|
|
|
|
|
//for benchmar endk
|
|
|
|
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
} Eo_Base_Data;
|
2015-03-25 09:44:45 -07:00
|
|
|
//for benchmark start
|
|
|
|
|
|
|
|
static unsigned int called_counter=0;
|
|
|
|
static unsigned int callbacks_counter=0;
|
|
|
|
static unsigned int called_loop_counter=0;
|
|
|
|
static unsigned int called_inner_loop_counter=0;
|
|
|
|
|
|
|
|
static unsigned int arrays_counter=0;
|
|
|
|
static unsigned int objects_counter=0;
|
|
|
|
|
|
|
|
static clock_t called_sum_clocks =0;
|
|
|
|
static clock_t start_clock =0;
|
2015-03-26 02:41:36 -07:00
|
|
|
|
|
|
|
static unsigned int events_counter=0;
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
|
2015-03-30 07:46:44 -07:00
|
|
|
static unsigned legacy_events_inserted=0;
|
|
|
|
static unsigned regular_events_inserted=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//for benchmark end
|
|
|
|
//static clock_t call_updated=0;
|
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
typedef struct {
|
2015-03-24 23:59:24 -07:00
|
|
|
const Eo_Event_Description *event;
|
2015-03-30 07:46:44 -07:00
|
|
|
Eina_Stringshare *event_name;
|
2015-03-25 06:42:34 -07:00
|
|
|
Eo_Callback_Description *callbacks;
|
2015-03-18 02:53:54 -07:00
|
|
|
}Eo_Event_Callbacks;
|
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
|
|
|
Eina_Stringshare *key;
|
|
|
|
void *data;
|
2014-04-02 03:42:00 -07:00
|
|
|
eo_key_data_free_func free_func;
|
2013-12-25 06:13:41 -08:00
|
|
|
} Eo_Generic_Data_Node;
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eo_generic_data_node_free(Eo_Generic_Data_Node *node)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(node->key);
|
|
|
|
if (node->free_func)
|
|
|
|
node->free_func(node->data);
|
|
|
|
free(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_generic_data_del_all(Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eina_Inlist *nnode;
|
|
|
|
Eo_Generic_Data_Node *node = NULL;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH_SAFE(pd->generic_data, nnode, node)
|
|
|
|
{
|
|
|
|
pd->generic_data = eina_inlist_remove(pd->generic_data,
|
|
|
|
EINA_INLIST_GET(node));
|
|
|
|
|
|
|
|
_eo_generic_data_node_free(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_key_data_set(Eo *obj, Eo_Base_Data *pd,
|
2014-04-02 03:42:00 -07:00
|
|
|
const char *key, const void *data, eo_key_data_free_func free_func)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo_Generic_Data_Node *node;
|
|
|
|
|
|
|
|
if (!key) return;
|
|
|
|
|
2014-04-02 03:42:00 -07:00
|
|
|
eo_do(obj, eo_key_data_del(key); );
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
node = malloc(sizeof(Eo_Generic_Data_Node));
|
2013-12-26 11:56:59 -08:00
|
|
|
if (!node) return;
|
2013-12-25 06:13:41 -08:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void *
|
|
|
|
_eo_base_key_data_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
/* We don't really change it... */
|
|
|
|
Eo_Generic_Data_Node *node;
|
|
|
|
if (!key) return NULL;
|
|
|
|
|
|
|
|
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));
|
|
|
|
return node->data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id)
|
2013-12-26 12:11:48 -08:00
|
|
|
{
|
Eo: Remove GCCism and make it more portable.
This affects eo_do() and eo_add() that used to use the ({}) GCCism.
Following a discussion with Peter de Ridder after my talk at FOSDEM,
we've decided to reopen the GCCism (works with other gcc compatible
compilers like clang and intelc) discussion, and after a bit of back and
forth it was decided to make things more portable, at the cost of ease
of use.
For example:
if (eo_do(obj, visible_get()))
is no longer allowed, the portable alternative
Eina_Bool tmp;
if (eo_do_ret(obj, tmp, visible_get()))
is to be used instead.
However:
eo_do(obj, a = a_get(), b = b_get(), bool_set(!bool_get))
are still allowed and OK.
eo_do(obj, if (a_get()) return;);
is no longer allowed, but:
eo_do(obj, if (a_get()) something());
is still allowed.
For clarity, this commit only incorporates the Eo changes, and not the
EFL changes to make the efl conform with this change.
Thanks again to Peter de Ridder for triggering this important discussion
which led to this change.
2015-02-23 08:06:40 -08:00
|
|
|
Eina_Bool tmp;
|
2013-12-26 12:11:48 -08:00
|
|
|
if (pd->parent == parent_id)
|
|
|
|
return;
|
|
|
|
|
Eo: Remove GCCism and make it more portable.
This affects eo_do() and eo_add() that used to use the ({}) GCCism.
Following a discussion with Peter de Ridder after my talk at FOSDEM,
we've decided to reopen the GCCism (works with other gcc compatible
compilers like clang and intelc) discussion, and after a bit of back and
forth it was decided to make things more portable, at the cost of ease
of use.
For example:
if (eo_do(obj, visible_get()))
is no longer allowed, the portable alternative
Eina_Bool tmp;
if (eo_do_ret(obj, tmp, visible_get()))
is to be used instead.
However:
eo_do(obj, a = a_get(), b = b_get(), bool_set(!bool_get))
are still allowed and OK.
eo_do(obj, if (a_get()) return;);
is no longer allowed, but:
eo_do(obj, if (a_get()) something());
is still allowed.
For clarity, this commit only incorporates the Eo changes, and not the
EFL changes to make the efl conform with this change.
Thanks again to Peter de Ridder for triggering this important discussion
which led to this change.
2015-02-23 08:06:40 -08:00
|
|
|
if (eo_do_ret(obj, tmp, eo_composite_part_is()) && pd->parent)
|
2013-12-26 12:11:48 -08:00
|
|
|
{
|
2014-10-21 04:37:00 -07:00
|
|
|
eo_do(pd->parent, eo_composite_detach(obj));
|
2013-12-26 12:11:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pd->parent)
|
|
|
|
{
|
2014-06-03 03:23:53 -07:00
|
|
|
Eo_Base_Data *old_parent_pd;
|
2013-12-26 12:11:48 -08:00
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
old_parent_pd = eo_data_scope_get(pd->parent, EO_BASE_CLASS);
|
2013-12-26 12:11:48 -08:00
|
|
|
if (old_parent_pd)
|
|
|
|
{
|
2014-07-06 04:15:21 -07:00
|
|
|
old_parent_pd->children = eina_list_remove_list(old_parent_pd->children,
|
|
|
|
pd->parent_list);
|
|
|
|
pd->parent_list = NULL;
|
2013-12-26 12:11:48 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("CONTACT DEVS!!! SHOULD NEVER HAPPEN!!! Old parent %p for object %p is not a valid Eo object.",
|
|
|
|
pd->parent, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
eo_xunref(obj, pd->parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set new parent */
|
|
|
|
if (parent_id)
|
|
|
|
{
|
2014-06-03 03:23:53 -07:00
|
|
|
Eo_Base_Data *parent_pd = NULL;
|
|
|
|
parent_pd = eo_data_scope_get(parent_id, EO_BASE_CLASS);
|
2013-12-26 12:11:48 -08:00
|
|
|
|
|
|
|
if (EINA_LIKELY(parent_pd != NULL))
|
|
|
|
{
|
|
|
|
pd->parent = parent_id;
|
|
|
|
parent_pd->children = eina_list_append(parent_pd->children,
|
|
|
|
obj);
|
2014-07-06 04:15:21 -07:00
|
|
|
pd->parent_list = eina_list_last(parent_pd->children);
|
2013-12-26 12:11:48 -08:00
|
|
|
eo_xref(obj, pd->parent);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pd->parent = NULL;
|
|
|
|
ERR("New parent %p for object %p is not a valid Eo object.",
|
|
|
|
parent_id, obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pd->parent = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static Eo *
|
|
|
|
_eo_base_parent_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd)
|
2013-12-26 12:11:48 -08:00
|
|
|
{
|
|
|
|
return pd->parent;
|
|
|
|
}
|
|
|
|
|
2014-08-29 01:55:02 -07:00
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_eo_base_finalized_get(Eo *obj_id, Eo_Base_Data *pd EINA_UNUSED)
|
|
|
|
{
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
|
|
|
|
|
|
|
|
return obj->finalized;
|
|
|
|
}
|
|
|
|
|
2013-12-26 12:11:48 -08:00
|
|
|
/* Children accessor */
|
|
|
|
typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
|
|
|
|
struct _Eo_Children_Iterator
|
|
|
|
{
|
|
|
|
Eina_Iterator iterator;
|
|
|
|
Eina_List *current;
|
|
|
|
_Eo_Object *obj;
|
|
|
|
Eo *obj_id;
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_children_iterator_next(Eo_Children_Iterator *it, void **data)
|
|
|
|
{
|
|
|
|
if (!it->current) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (data) *data = eina_list_data_get(it->current);
|
|
|
|
it->current = eina_list_next(it->current);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eo *
|
|
|
|
_eo_children_iterator_container(Eo_Children_Iterator *it)
|
|
|
|
{
|
|
|
|
return it->obj_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eo_children_iterator_free(Eo_Children_Iterator *it)
|
|
|
|
{
|
|
|
|
_Eo_Class *klass;
|
|
|
|
_Eo_Object *obj;
|
|
|
|
|
|
|
|
klass = (_Eo_Class*) it->obj->klass;
|
|
|
|
obj = it->obj;
|
|
|
|
|
|
|
|
eina_spinlock_take(&klass->iterators.trash_lock);
|
|
|
|
if (klass->iterators.trash_count < 8)
|
|
|
|
{
|
|
|
|
klass->iterators.trash_count++;
|
|
|
|
eina_trash_push(&klass->iterators.trash, it);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free(it);
|
|
|
|
}
|
|
|
|
eina_spinlock_release(&klass->iterators.trash_lock);
|
|
|
|
|
|
|
|
_eo_unref(obj);
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static Eina_Iterator *
|
|
|
|
_eo_base_children_iterator_new(Eo *obj_id, Eo_Base_Data *pd)
|
2013-12-26 12:11:48 -08:00
|
|
|
{
|
|
|
|
_Eo_Class *klass;
|
|
|
|
Eo_Children_Iterator *it;
|
|
|
|
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
|
|
|
|
|
|
|
|
if (!pd->children) return NULL;
|
|
|
|
|
|
|
|
klass = (_Eo_Class *) obj->klass;
|
|
|
|
|
|
|
|
eina_spinlock_take(&klass->iterators.trash_lock);
|
|
|
|
it = eina_trash_pop(&klass->iterators.trash);
|
|
|
|
if (it)
|
|
|
|
{
|
|
|
|
klass->iterators.trash_count--;
|
|
|
|
memset(it, 0, sizeof (Eo_Children_Iterator));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
it = calloc(1, sizeof (Eo_Children_Iterator));
|
|
|
|
}
|
|
|
|
eina_spinlock_release(&klass->iterators.trash_lock);
|
|
|
|
if (!it) return NULL;
|
|
|
|
|
|
|
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
2014-04-17 10:36:10 -07:00
|
|
|
it->current = pd->children;
|
2013-12-26 12:11:48 -08:00
|
|
|
it->obj = _eo_ref(obj);
|
|
|
|
it->obj_id = obj_id;
|
|
|
|
|
|
|
|
it->iterator.next = FUNC_ITERATOR_NEXT(_eo_children_iterator_next);
|
|
|
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eo_children_iterator_container);
|
|
|
|
it->iterator.free = FUNC_ITERATOR_FREE(_eo_children_iterator_free);
|
|
|
|
|
|
|
|
return (Eina_Iterator *)it;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_dbg_info_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd EINA_UNUSED, Eo_Dbg_Info *root_node EINA_UNUSED)
|
2013-12-25 06:13:41 -08:00
|
|
|
{ /* No info required in the meantime */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_key_data_del(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo_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));
|
|
|
|
_eo_generic_data_node_free(node);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Weak reference. */
|
|
|
|
|
|
|
|
static inline size_t
|
2014-06-03 03:23:53 -07:00
|
|
|
_wref_count(Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
size_t count = 0;
|
|
|
|
if (!pd->wrefs)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
Eo ***itr;
|
2013-12-26 12:00:23 -08:00
|
|
|
for (itr = pd->wrefs; *itr; itr++)
|
2013-12-25 06:13:41 -08:00
|
|
|
count++;
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_wref_add(Eo *obj, Eo_Base_Data *pd, Eo **wref)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
size_t count;
|
2013-12-26 11:56:59 -08:00
|
|
|
Eo ***tmp;
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
count = _wref_count(pd);
|
|
|
|
count += 1; /* New wref. */
|
|
|
|
|
2013-12-26 11:56:59 -08:00
|
|
|
tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * (count + 1));
|
|
|
|
if (!tmp) return;
|
|
|
|
pd->wrefs = tmp;
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
pd->wrefs[count - 1] = wref;
|
|
|
|
pd->wrefs[count] = NULL;
|
|
|
|
*wref = obj;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN void
|
|
|
|
_eo_base_wref_del(Eo *obj, Eo_Base_Data *pd, Eo **wref)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
size_t count;
|
|
|
|
|
|
|
|
if (*wref != obj)
|
|
|
|
{
|
|
|
|
ERR("Wref is a weak ref to %p, while this function was called on %p.",
|
|
|
|
*wref, obj);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pd->wrefs)
|
|
|
|
{
|
|
|
|
ERR("There are no weak refs for object %p", obj);
|
|
|
|
*wref = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move the last item in the array instead of the current wref. */
|
|
|
|
count = _wref_count(pd);
|
|
|
|
|
|
|
|
{
|
|
|
|
Eo ***itr;
|
2013-12-26 12:00:23 -08:00
|
|
|
for (itr = pd->wrefs; *itr; itr++)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
if (*itr == wref)
|
|
|
|
{
|
|
|
|
*itr = pd->wrefs[count - 1];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*itr)
|
|
|
|
{
|
|
|
|
ERR("Wref %p is not associated with object %p", wref, obj);
|
|
|
|
*wref = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count > 1)
|
|
|
|
{
|
2013-12-26 11:56:59 -08:00
|
|
|
Eo ***tmp;
|
2013-12-25 06:13:41 -08:00
|
|
|
// No count--; because of the NULL that is not included in the count. */
|
2013-12-26 11:56:59 -08:00
|
|
|
tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * count);
|
|
|
|
if (!tmp) return;
|
|
|
|
pd->wrefs = tmp;
|
2013-12-25 06:13:41 -08:00
|
|
|
pd->wrefs[count - 1] = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free(pd->wrefs);
|
|
|
|
pd->wrefs = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wref = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2014-06-03 03:23:53 -07:00
|
|
|
_wref_destruct(Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo ***itr;
|
|
|
|
if (!pd->wrefs)
|
|
|
|
return;
|
|
|
|
|
2013-12-26 12:00:23 -08:00
|
|
|
for (itr = pd->wrefs; *itr; itr++)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
**itr = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(pd->wrefs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF Weak reference. */
|
|
|
|
|
|
|
|
/* Event callbacks */
|
|
|
|
|
|
|
|
/* Callbacks */
|
|
|
|
|
2014-05-19 07:17:08 -07:00
|
|
|
/* XXX: Legacy support, remove when legacy is dead. */
|
|
|
|
static Eina_Hash *_legacy_events_hash = NULL;
|
|
|
|
static const char *_legacy_event_desc = "Dynamically generated legacy event";
|
|
|
|
|
|
|
|
EAPI const Eo_Event_Description *
|
|
|
|
eo_base_legacy_only_event_description_get(const char *_event_name)
|
|
|
|
{
|
|
|
|
Eina_Stringshare *event_name = eina_stringshare_add(_event_name);
|
|
|
|
Eo_Event_Description *event_desc = eina_hash_find(_legacy_events_hash, event_name);
|
|
|
|
if (!event_desc)
|
|
|
|
{
|
|
|
|
event_desc = calloc(1, sizeof(Eo_Event_Description));
|
|
|
|
event_desc->name = event_name;
|
|
|
|
event_desc->doc = _legacy_event_desc;
|
2014-05-29 01:24:28 -07:00
|
|
|
eina_hash_add(_legacy_events_hash, event_name, event_desc);
|
2014-05-19 07:17:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eina_stringshare_del(event_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return event_desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_legacy_events_hash_free_cb(void *_desc)
|
|
|
|
{
|
|
|
|
Eo_Event_Description *desc = _desc;
|
|
|
|
eina_stringshare_del(desc->name);
|
|
|
|
free(desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF Legacy */
|
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
struct _Eo_Callback_Description
|
|
|
|
{
|
|
|
|
Eo_Callback_Description *next;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
Eo_Callback_Array_Item item;
|
|
|
|
const Eo_Callback_Array_Item *item_array;
|
|
|
|
} items;
|
2015-03-31 07:18:27 -07:00
|
|
|
const Eo_Callback_Array_Item *item_array;
|
2013-12-25 06:13:41 -08:00
|
|
|
void *func_data;
|
|
|
|
Eo_Callback_Priority priority;
|
|
|
|
|
|
|
|
Eina_Bool delete_me : 1;
|
|
|
|
Eina_Bool func_array : 1;
|
2015-03-30 07:46:44 -07:00
|
|
|
Eina_Bool is_legacy_counter : 1;
|
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
};
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-25 06:42:34 -07:00
|
|
|
/* Actually remove, doesn't care about walking list, or delete_me */
|
|
|
|
static void
|
|
|
|
_eo_callback_remove(Eo_Event_Callbacks *ec, Eo_Callback_Description *cb)
|
|
|
|
{
|
|
|
|
Eo_Callback_Description *itr, *pitr = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
itr = ec->callbacks;
|
|
|
|
|
|
|
|
for ( ; itr; )
|
|
|
|
{
|
|
|
|
Eo_Callback_Description *titr = itr;
|
|
|
|
itr = itr->next;
|
|
|
|
|
|
|
|
if (titr == cb)
|
|
|
|
{
|
|
|
|
if (pitr)
|
|
|
|
{
|
|
|
|
pitr->next = titr->next;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ec->callbacks = titr->next;
|
|
|
|
}
|
|
|
|
free(titr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pitr = titr;
|
2015-03-31 07:18:27 -07:00
|
|
|
}
|
2015-03-25 06:42:34 -07:00
|
|
|
}
|
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
/* Actually remove, doesn't care about walking list, or delete_me */
|
|
|
|
static void
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_callback_remove_all(Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
2015-03-18 02:53:54 -07:00
|
|
|
Eo_Event_Callbacks *cbs;
|
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
EINA_INARRAY_FOREACH(pd->callbacks, cbs)
|
|
|
|
{
|
2015-03-30 07:46:44 -07:00
|
|
|
while (cbs->callbacks)
|
|
|
|
{
|
|
|
|
Eo_Callback_Description *next = cbs->callbacks->next;
|
|
|
|
free(cbs->callbacks);
|
|
|
|
cbs->callbacks = next;
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
|
|
|
static void
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_callbacks_clear(Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo_Callback_Description *cb = NULL;
|
|
|
|
|
|
|
|
/* If there are no deletions waiting. */
|
|
|
|
if (!pd->deletions_waiting)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Abort if we are currently walking the list. */
|
|
|
|
if (pd->walking_list > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pd->deletions_waiting = EINA_FALSE;
|
2015-03-24 23:59:24 -07:00
|
|
|
Eo_Event_Callbacks *cbs;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
EINA_INARRAY_FOREACH(pd->callbacks, cbs)
|
|
|
|
{
|
2015-03-26 02:41:36 -07:00
|
|
|
for (cb = cbs->callbacks; cb; )
|
2015-03-24 23:59:24 -07:00
|
|
|
{
|
2015-03-26 02:41:36 -07:00
|
|
|
Eo_Callback_Description *titr = cb;
|
|
|
|
cb = cb->next;
|
|
|
|
|
|
|
|
if (titr->delete_me)
|
|
|
|
{
|
|
|
|
_eo_callback_remove(cbs, titr);
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
|
|
|
}
|
2015-03-18 02:53:54 -07:00
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
|
2015-03-25 09:44:45 -07:00
|
|
|
static void
|
2015-03-25 06:42:34 -07:00
|
|
|
_eo_callbacks_list_sorted_insert( Eo_Event_Callbacks *ec, Eo_Callback_Description *cb)
|
|
|
|
{
|
|
|
|
Eo_Callback_Description *itr, *itrp = NULL;
|
|
|
|
for (itr = ec->callbacks; itr && (itr->priority < cb->priority);
|
|
|
|
itr = itr->next)
|
|
|
|
{
|
|
|
|
itrp = itr;
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
|
2015-03-25 06:42:34 -07:00
|
|
|
if (itrp)
|
|
|
|
{
|
|
|
|
cb->next = itrp->next;
|
|
|
|
itrp->next = cb;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cb->next = ec->callbacks;
|
|
|
|
ec->callbacks = cb;
|
|
|
|
}
|
|
|
|
}
|
2015-03-30 07:46:44 -07:00
|
|
|
int
|
|
|
|
_eo_base_event_compare( const void* e1 , const void* e2){
|
|
|
|
|
|
|
|
if( ((Eo_Event_Callbacks*)e1)->event_name == ((Eo_Event_Callbacks*)e2)->event_name)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
if( ((Eo_Event_Callbacks*)e1)->event_name > ((Eo_Event_Callbacks*)e2)->event_name)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
2015-03-18 02:53:54 -07:00
|
|
|
static void
|
2015-03-25 06:42:34 -07:00
|
|
|
_eo_callbacks_sorted_insert(Eo_Base_Data *pd, Eo_Callback_Description *cb, const Eo_Event_Description *desc)
|
2015-03-18 02:53:54 -07:00
|
|
|
{
|
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
if (!desc)
|
|
|
|
{
|
|
|
|
DBG("sorted insert NULL event!\n");
|
2015-03-18 02:53:54 -07:00
|
|
|
return;
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
2015-03-30 07:46:44 -07:00
|
|
|
{
|
|
|
|
//adding to events conter - statistics
|
|
|
|
unsigned int index = ((unsigned long long int )desc)%63;
|
|
|
|
if( (pd->have_events & (1<<index) )==0){
|
|
|
|
pd->events_counter++;
|
|
|
|
pd->have_events |= 1<<index;
|
|
|
|
}
|
|
|
|
}
|
2015-03-26 02:41:36 -07:00
|
|
|
pd->callbacks_counter++;//avi debug
|
|
|
|
|
2015-03-30 07:46:44 -07:00
|
|
|
Eina_Stringshare *event_name;
|
|
|
|
if (desc->doc != _legacy_event_desc)
|
|
|
|
{
|
|
|
|
legacy_events_inserted++;
|
|
|
|
event_name = eina_stringshare_add(desc->name);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
event_name = desc->name;
|
|
|
|
regular_events_inserted++;
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
Eo_Event_Callbacks *cbs;
|
2015-03-31 07:18:27 -07:00
|
|
|
Eo_Event_Callbacks ec = { desc, event_name , cb };
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-30 07:46:44 -07:00
|
|
|
cb->next=NULL;
|
2015-03-31 07:18:27 -07:00
|
|
|
int index = eina_inarray_search_sorted ( pd->callbacks, &ec , _eo_base_event_compare );
|
|
|
|
/* EINA_INARRAY_FOREACH(pd->callbacks, cbs)
|
|
|
|
{
|
|
|
|
// if(_cb_desc_match(desc, cbs->event))
|
|
|
|
if(event_name == cbs->event_name)
|
|
|
|
{
|
|
|
|
_eo_callbacks_list_sorted_insert(cbs, cb);
|
|
|
|
if (desc->doc != _legacy_event_desc)
|
|
|
|
eina_stringshare_del(event_name);
|
2015-03-26 02:41:36 -07:00
|
|
|
|
2015-03-31 07:18:27 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}*/
|
2015-03-30 07:46:44 -07:00
|
|
|
|
2015-03-31 07:18:27 -07:00
|
|
|
if(index !=-1){
|
|
|
|
cbs =eina_inarray_nth(pd->callbacks , index );
|
|
|
|
_eo_callbacks_list_sorted_insert(cbs, cb);
|
|
|
|
if (desc->doc != _legacy_event_desc)
|
|
|
|
eina_stringshare_del(event_name);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2015-03-31 07:18:27 -07:00
|
|
|
|
|
|
|
// eina_inarray_push(pd->callbacks, &ec);
|
|
|
|
eina_inarray_insert_sorted(pd->callbacks , &ec , _eo_base_event_compare );
|
2015-03-30 07:46:44 -07:00
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
}
|
|
|
|
|
2015-03-25 06:42:34 -07:00
|
|
|
EOLIAN static void _eo_base_event_callback_priority_add(Eo *obj, Eo_Base_Data *pd,
|
2015-03-18 02:53:54 -07:00
|
|
|
const Eo_Event_Description *desc, Eo_Callback_Priority priority, Eo_Event_Cb func, const void *data)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo_Callback_Description *cb;
|
|
|
|
|
|
|
|
cb = calloc(1, sizeof(*cb));
|
2013-12-26 11:56:59 -08:00
|
|
|
if (!cb) return;
|
2013-12-25 06:13:41 -08:00
|
|
|
cb->items.item.desc = desc;
|
|
|
|
cb->items.item.func = func;
|
2015-03-18 02:53:54 -07:00
|
|
|
cb->func_data = (void *) data;
|
2013-12-25 06:13:41 -08:00
|
|
|
cb->priority = priority;
|
2015-03-18 02:53:54 -07:00
|
|
|
cb->func_array = EINA_FALSE;
|
2015-03-31 07:18:27 -07:00
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
cb->delete_me = EINA_FALSE;
|
2015-03-25 06:42:34 -07:00
|
|
|
_eo_callbacks_sorted_insert(pd, cb, desc);
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
{
|
|
|
|
const Eo_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}};
|
2014-04-02 01:46:34 -07:00
|
|
|
eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, (void *)arr));
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_callback_del(Eo *obj, Eo_Base_Data *pd,
|
2015-03-18 02:53:54 -07:00
|
|
|
const Eo_Event_Description *desc,
|
|
|
|
Eo_Event_Cb func,
|
|
|
|
const void *user_data)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo_Callback_Description *cb;
|
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
Eo_Event_Callbacks *cbs;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
EINA_INARRAY_FOREACH(pd->callbacks, cbs)
|
|
|
|
{
|
2015-03-25 06:42:34 -07:00
|
|
|
for (cb = cbs->callbacks; cb; cb = cb->next)
|
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
{
|
2015-03-18 02:53:54 -07:00
|
|
|
if ((cb->items.item.desc == desc) && (cb->items.item.func == func) &&
|
|
|
|
(cb->func_data == user_data))
|
|
|
|
{
|
|
|
|
const Eo_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}};
|
|
|
|
|
|
|
|
cb->delete_me = EINA_TRUE;
|
|
|
|
pd->deletions_waiting = EINA_TRUE;
|
|
|
|
_eo_callbacks_clear(pd);
|
|
|
|
eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, (void *)arr); );
|
|
|
|
return;
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
DBG("Callback of object %p with function %p and data %p not found.", obj, func, user_data);
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_callback_array_priority_add(Eo *obj, Eo_Base_Data *pd,
|
2015-03-24 23:59:24 -07:00
|
|
|
const Eo_Callback_Array_Item *array,
|
|
|
|
Eo_Callback_Priority priority,
|
|
|
|
const void *user_data)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
2015-03-24 08:03:51 -07:00
|
|
|
const Eo_Callback_Array_Item *it;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
|
|
|
for (it = array; it->func; it++)
|
|
|
|
{
|
|
|
|
Eo_Callback_Description *cb;
|
|
|
|
|
|
|
|
cb = calloc(1, sizeof(*cb));
|
|
|
|
if (!cb) return;
|
|
|
|
cb->items.item.desc = it->desc;
|
|
|
|
cb->items.item.func = it->func;
|
|
|
|
|
|
|
|
cb->func_data = (void *) user_data;
|
|
|
|
cb->priority = priority;
|
2015-03-31 07:18:27 -07:00
|
|
|
cb->item_array = array;
|
2015-03-18 02:53:54 -07:00
|
|
|
cb->func_array = EINA_TRUE;
|
|
|
|
cb->delete_me = EINA_FALSE;
|
2015-03-25 06:42:34 -07:00
|
|
|
_eo_callbacks_sorted_insert(pd, cb,it->desc);
|
2015-03-18 02:53:54 -07:00
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
|
|
|
|
{
|
2015-03-18 02:53:54 -07:00
|
|
|
eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_ADD, (void *)array) );
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_callback_array_del(Eo *obj, Eo_Base_Data *pd,
|
2015-03-24 23:59:24 -07:00
|
|
|
const Eo_Callback_Array_Item *array,
|
|
|
|
const void *user_data)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eo_Callback_Description *cb;
|
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
Eo_Event_Callbacks *cbs;
|
2015-03-18 02:53:54 -07:00
|
|
|
int count = 0;
|
2015-03-24 23:59:24 -07:00
|
|
|
if (!pd->callbacks) goto end;
|
|
|
|
EINA_INARRAY_FOREACH(pd->callbacks, cbs)
|
|
|
|
{
|
2015-03-25 06:42:34 -07:00
|
|
|
for (cb = cbs->callbacks; cb; cb = cb->next)
|
|
|
|
{
|
2015-03-31 07:18:27 -07:00
|
|
|
if ((cb->item_array == array) && (cb->func_data == user_data))
|
2015-03-18 02:53:54 -07:00
|
|
|
{
|
|
|
|
cb->delete_me = EINA_TRUE;
|
|
|
|
pd->deletions_waiting = EINA_TRUE;
|
|
|
|
count++;
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count > 0)
|
2014-05-19 07:28:49 -07:00
|
|
|
{
|
2015-03-18 02:53:54 -07:00
|
|
|
_eo_callbacks_clear(pd);
|
|
|
|
eo_do(obj, eo_event_callback_call(EO_EV_CALLBACK_DEL, (void *)array) );
|
|
|
|
return;
|
2014-05-19 07:28:49 -07:00
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
end:
|
2015-03-18 02:53:54 -07:00
|
|
|
DBG("Callback of object %p with function array %p and data %p not found.", obj, array, user_data);
|
2014-05-19 07:28:49 -07:00
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_eo_base_event_callback_call(Eo *obj_id, Eo_Base_Data *pd,
|
2015-03-26 02:41:36 -07:00
|
|
|
const Eo_Event_Description *desc,
|
|
|
|
void *event_info)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
Eina_Bool ret;
|
|
|
|
Eo_Callback_Description *cb;
|
|
|
|
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
|
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
if(!desc){
|
|
|
|
printf("call bad event!");
|
2015-03-24 23:59:24 -07:00
|
|
|
return EINA_FALSE;
|
2015-03-18 02:53:54 -07:00
|
|
|
}
|
|
|
|
|
2015-03-26 02:41:36 -07:00
|
|
|
pd->called_counter++;//avi debug
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2015-03-26 02:41:36 -07:00
|
|
|
clock_t start_time = clock();
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
Eo_Event_Callbacks *cbs;
|
|
|
|
Eina_Bool found = EINA_FALSE;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-30 07:46:44 -07:00
|
|
|
|
|
|
|
Eina_Stringshare *event_name;
|
|
|
|
if (desc->doc != _legacy_event_desc)
|
|
|
|
{
|
|
|
|
|
|
|
|
event_name = eina_stringshare_add(desc->name);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
event_name = desc->name;
|
|
|
|
}
|
|
|
|
Eo_Event_Callbacks ec = { desc,event_name , NULL };
|
2015-03-31 07:18:27 -07:00
|
|
|
if( pd->callbacks->len < 7 ){ //if small array simple search will be faster
|
|
|
|
EINA_INARRAY_FOREACH(pd->callbacks, cbs)
|
2015-03-24 23:59:24 -07:00
|
|
|
{
|
2015-03-31 07:18:27 -07:00
|
|
|
pd->called_loop_counter++;//avi debug
|
|
|
|
// if(_cb_desc_match(desc, cbs->event))
|
|
|
|
if(event_name == cbs->event_name)
|
|
|
|
{
|
|
|
|
found = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
2015-03-31 07:18:27 -07:00
|
|
|
if(found==EINA_FALSE) {pd->called_sum_clocks +=clock()-start_time;//avi dbg
|
|
|
|
return EINA_FALSE;}
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-31 07:18:27 -07:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
int index = eina_inarray_search_sorted ( pd->callbacks, &ec , _eo_base_event_compare );
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-31 07:18:27 -07:00
|
|
|
if(index==-1) {pd->called_sum_clocks +=clock()-start_time;//avi dbg
|
|
|
|
return EINA_FALSE;}
|
2015-03-30 07:46:44 -07:00
|
|
|
|
2015-03-31 07:18:27 -07:00
|
|
|
cbs =eina_inarray_nth(pd->callbacks , index );
|
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
ret = EINA_TRUE;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-24 23:59:24 -07:00
|
|
|
_eo_ref(obj);
|
|
|
|
pd->walking_list++;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2015-03-26 02:41:36 -07:00
|
|
|
for (cb = cbs->callbacks; cb; cb = cb->next)
|
2015-03-24 23:59:24 -07:00
|
|
|
{
|
2015-03-31 07:18:27 -07:00
|
|
|
|
2015-03-25 09:44:45 -07:00
|
|
|
pd->called_loop_counter++;//avi debug
|
2013-12-25 06:13:41 -08:00
|
|
|
if (!cb->delete_me)
|
|
|
|
{
|
2015-03-31 07:18:27 -07:00
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
if (( !cb->items.item.desc->unfreezable) &&
|
|
|
|
(event_freeze_count || pd->event_freeze_count))
|
|
|
|
continue;
|
2015-03-25 09:44:45 -07:00
|
|
|
unsigned int before_func=clock();
|
2015-03-18 02:53:54 -07:00
|
|
|
/* Abort callback calling if the func says so. */
|
|
|
|
if (!cb->items.item.func((void *) cb->func_data, obj_id, desc,
|
|
|
|
(void *) event_info))
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
2015-03-18 02:53:54 -07:00
|
|
|
ret = EINA_FALSE;
|
2015-03-26 02:41:36 -07:00
|
|
|
start_time+=clock()-before_func;
|
2015-03-18 02:53:54 -07:00
|
|
|
goto end;
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
2015-03-26 02:41:36 -07:00
|
|
|
start_time+=clock()-before_func;
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
2015-03-24 23:59:24 -07:00
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
end:
|
2015-03-26 02:41:36 -07:00
|
|
|
pd->called_sum_clocks +=clock()-start_time;//avi dbg
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
pd->walking_list--;
|
|
|
|
_eo_callbacks_clear(pd);
|
|
|
|
_eo_unref(obj);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_event_forwarder_callback(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info)
|
|
|
|
{
|
|
|
|
(void) obj;
|
|
|
|
Eo *new_obj = (Eo *) data;
|
2013-07-25 17:34:46 -07:00
|
|
|
Eina_Bool ret = EINA_FALSE;
|
2013-12-25 06:13:41 -08:00
|
|
|
|
2014-04-02 01:46:34 -07:00
|
|
|
eo_do(new_obj, ret = eo_event_callback_call(desc, (void *)event_info); );
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Change default priority? Maybe call later? */
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_callback_forwarder_add(Eo *obj, Eo_Base_Data *pd EINA_UNUSED,
|
2013-12-25 06:13:41 -08:00
|
|
|
const Eo_Event_Description *desc,
|
|
|
|
Eo *new_obj)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* FIXME: Add it EO_MAGIC_RETURN(new_obj, EO_EINA_MAGIC); */
|
|
|
|
|
2014-04-02 01:46:34 -07:00
|
|
|
eo_do(obj, eo_event_callback_add(desc, _eo_event_forwarder_callback, new_obj); );
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_callback_forwarder_del(Eo *obj, Eo_Base_Data *pd EINA_UNUSED,
|
2013-12-25 06:13:41 -08:00
|
|
|
const Eo_Event_Description *desc,
|
|
|
|
Eo *new_obj)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* FIXME: Add it EO_MAGIC_RETURN(new_obj, EO_EINA_MAGIC); */
|
|
|
|
|
2014-04-02 01:46:34 -07:00
|
|
|
eo_do(obj, eo_event_callback_del(desc, _eo_event_forwarder_callback, new_obj); );
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_freeze(Eo *obj EINA_UNUSED, Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
pd->event_freeze_count++;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_event_thaw(Eo *obj, Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
if (pd->event_freeze_count > 0)
|
|
|
|
{
|
|
|
|
pd->event_freeze_count--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("Events for object %p have already been thawed.", obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static int
|
|
|
|
_eo_base_event_freeze_count_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
return pd->event_freeze_count;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
2014-07-24 06:41:23 -07:00
|
|
|
_eo_base_event_global_freeze(Eo *klass EINA_UNUSED, void *pd EINA_UNUSED)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
event_freeze_count++;
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
2014-07-24 06:41:23 -07:00
|
|
|
_eo_base_event_global_thaw(Eo *klass EINA_UNUSED, void *pd EINA_UNUSED)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
if (event_freeze_count > 0)
|
|
|
|
{
|
|
|
|
event_freeze_count--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("Global events have already been thawed.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static int
|
2014-07-24 06:41:23 -07:00
|
|
|
_eo_base_event_global_freeze_count_get(Eo *klass EINA_UNUSED, void *pd EINA_UNUSED)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
return event_freeze_count;
|
|
|
|
}
|
|
|
|
|
2014-10-21 04:37:00 -07:00
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_eo_base_composite_attach(Eo *parent_id, Eo_Base_Data *pd EINA_UNUSED, Eo *comp_obj_id)
|
|
|
|
{
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
|
|
|
|
|
|
|
|
if (!eo_isa(parent_id, _eo_class_id_get(comp_obj->klass))) return EINA_FALSE;
|
|
|
|
|
|
|
|
{
|
|
|
|
Eina_List *itr;
|
|
|
|
Eo *emb_obj_id;
|
|
|
|
EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id)
|
|
|
|
{
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE);
|
|
|
|
if(emb_obj->klass == comp_obj->klass)
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
comp_obj->composite = EINA_TRUE;
|
|
|
|
parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
|
|
|
|
|
|
|
|
eo_do(comp_obj_id, eo_parent_set(parent_id));
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_eo_base_composite_detach(Eo *parent_id, Eo_Base_Data *pd EINA_UNUSED, Eo *comp_obj_id)
|
|
|
|
{
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(parent_id, parent, EINA_FALSE);
|
|
|
|
|
|
|
|
if (!comp_obj->composite)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
comp_obj->composite = EINA_FALSE;
|
|
|
|
parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id);
|
|
|
|
eo_do(comp_obj_id, eo_parent_set(NULL));
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_eo_base_composite_part_is(Eo *comp_obj_id, Eo_Base_Data *pd EINA_UNUSED)
|
|
|
|
{
|
|
|
|
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
|
|
|
|
|
|
|
return comp_obj->composite;
|
|
|
|
}
|
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
/* Eo_Dbg */
|
|
|
|
EAPI void
|
2014-04-02 01:46:34 -07:00
|
|
|
eo_dbg_info_free(Eo_Dbg_Info *info)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
eina_value_flush(&(info->value));
|
|
|
|
free(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_dbg_info_setup(const Eina_Value_Type *type, void *mem)
|
|
|
|
{
|
|
|
|
memset(mem, 0, type->value_size);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_dbg_info_flush(const Eina_Value_Type *type EINA_UNUSED, void *_mem)
|
|
|
|
{
|
|
|
|
Eo_Dbg_Info *mem = *(Eo_Dbg_Info **) _mem;
|
|
|
|
eina_stringshare_del(mem->name);
|
|
|
|
eina_value_flush(&(mem->value));
|
|
|
|
free(mem);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_dbg_info_copy(const Eina_Value_Type *type EINA_UNUSED, const void *_src, void *_dst)
|
|
|
|
{
|
|
|
|
const Eo_Dbg_Info **src = (const Eo_Dbg_Info **) _src;
|
|
|
|
Eo_Dbg_Info **dst = _dst;
|
2013-12-26 11:56:59 -08:00
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
*dst = calloc(1, sizeof(Eo_Dbg_Info));
|
2013-12-26 11:56:59 -08:00
|
|
|
if (!*dst) return EINA_FALSE;
|
2013-12-25 06:13:41 -08:00
|
|
|
(*dst)->name = eina_stringshare_ref((*src)->name);
|
|
|
|
eina_value_copy(&((*src)->value), &((*dst)->value));
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_dbg_info_convert_to(const Eina_Value_Type *type EINA_UNUSED, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
|
|
|
|
{
|
|
|
|
/* FIXME: For the meanwhile, just use the inner type for the value. */
|
|
|
|
const Eo_Dbg_Info **src = (const Eo_Dbg_Info **) type_mem;
|
|
|
|
if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
|
|
|
|
convert == EINA_VALUE_TYPE_STRING)
|
|
|
|
{
|
|
|
|
Eina_Bool ret;
|
|
|
|
const char *other_mem;
|
|
|
|
char *inner_val = eina_value_to_string(&(*src)->value);
|
|
|
|
other_mem = inner_val;
|
|
|
|
ret = eina_value_type_pset(convert, convert_mem, &other_mem);
|
|
|
|
free(inner_val);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_error_set(EINA_ERROR_VALUE_FAILED);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_dbg_info_pset(const Eina_Value_Type *type EINA_UNUSED, void *_mem, const void *_ptr)
|
|
|
|
{
|
|
|
|
Eo_Dbg_Info **mem = _mem;
|
|
|
|
if (*mem)
|
|
|
|
free(*mem);
|
|
|
|
*mem = (void *) _ptr;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_eo_dbg_info_pget(const Eina_Value_Type *type EINA_UNUSED, const void *_mem, void *_ptr)
|
|
|
|
{
|
|
|
|
Eo_Dbg_Info **ptr = _ptr;
|
|
|
|
*ptr = (void *) _mem;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-04-02 01:46:34 -07:00
|
|
|
static const Eina_Value_Type _EO_DBG_INFO_TYPE = {
|
2013-12-25 06:13:41 -08:00
|
|
|
EINA_VALUE_TYPE_VERSION,
|
|
|
|
sizeof(Eo_Dbg_Info *),
|
|
|
|
"Eo_Dbg_Info_Ptr",
|
|
|
|
_eo_dbg_info_setup,
|
|
|
|
_eo_dbg_info_flush,
|
|
|
|
_eo_dbg_info_copy,
|
|
|
|
NULL,
|
|
|
|
_eo_dbg_info_convert_to,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
_eo_dbg_info_pset,
|
|
|
|
_eo_dbg_info_pget
|
|
|
|
};
|
|
|
|
|
2014-04-02 01:46:34 -07:00
|
|
|
EAPI const Eina_Value_Type *EO_DBG_INFO_TYPE = &_EO_DBG_INFO_TYPE;
|
2013-12-25 06:13:41 -08:00
|
|
|
|
|
|
|
|
|
|
|
/* EOF event callbacks */
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
/* EO_BASE_CLASS stuff */
|
|
|
|
#define MY_CLASS EO_BASE_CLASS
|
2013-12-25 06:13:41 -08:00
|
|
|
|
2015-03-25 09:44:45 -07:00
|
|
|
static __attribute__((destructor)) void finish(void)
|
|
|
|
{
|
2015-03-30 07:46:44 -07:00
|
|
|
printf("calbacks stats-All objects!: num objects=%u total time=%f \
|
|
|
|
called cal times= %u called loops=%u called clocks=%f called sec=%f \
|
|
|
|
callbacks count=%u events counter=%u legacy_events_inserted=%u regular_events_inserted=%u \n",
|
2015-03-26 02:41:36 -07:00
|
|
|
objects_counter,(double)(clock()-start_clock)/CLOCKS_PER_SEC, called_counter,
|
|
|
|
called_loop_counter,(double)called_sum_clocks,
|
|
|
|
(double)called_sum_clocks/CLOCKS_PER_SEC, callbacks_counter ,
|
2015-03-30 07:46:44 -07:00
|
|
|
events_counter, legacy_events_inserted, regular_events_inserted
|
2015-03-25 09:44:45 -07:00
|
|
|
);//avi debug
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_eo_base_constructor(Eo *obj, Eo_Base_Data *pd EINA_UNUSED)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
DBG("%p - %s.", obj, eo_class_name_get(MY_CLASS));
|
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
pd->callbacks = eina_inarray_new(sizeof(Eo_Event_Callbacks), 10 );//added by avi
|
|
|
|
|
2015-03-26 02:41:36 -07:00
|
|
|
pd->called_counter=0;
|
|
|
|
pd->callbacks_counter=0;
|
|
|
|
pd-> called_loop_counter=0;
|
|
|
|
|
|
|
|
pd-> called_loop_counter=0;
|
|
|
|
|
|
|
|
pd-> called_sum_clocks =0;
|
|
|
|
pd->events_counter=0;
|
|
|
|
pd->have_events = 0;
|
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
_eo_condtor_done(obj);
|
|
|
|
}
|
|
|
|
|
2014-07-24 07:01:36 -07:00
|
|
|
EOLIAN static void
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_base_destructor(Eo *obj, Eo_Base_Data *pd)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
2013-11-08 04:24:40 -08:00
|
|
|
Eo *child;
|
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
DBG("%p - %s.", obj, eo_class_name_get(MY_CLASS));
|
2015-03-26 02:41:36 -07:00
|
|
|
if( pd->callbacks_counter>0 ){//only with atleast one calllbacks
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2015-03-26 02:41:36 -07:00
|
|
|
called_counter+=pd->called_counter;
|
|
|
|
callbacks_counter+=pd->callbacks_counter;
|
|
|
|
called_loop_counter+= pd->called_loop_counter;
|
|
|
|
arrays_counter+=pd->arrays_counter;
|
|
|
|
called_inner_loop_counter+=pd->called_inner_loop_counter;
|
|
|
|
called_sum_clocks+=pd-> called_sum_clocks;
|
|
|
|
events_counter+=pd->events_counter;
|
2015-03-25 09:44:45 -07:00
|
|
|
|
2015-03-26 02:41:36 -07:00
|
|
|
objects_counter++;
|
|
|
|
}
|
2013-12-25 06:13:41 -08:00
|
|
|
|
2013-11-08 04:24:40 -08:00
|
|
|
EINA_LIST_FREE(pd->children, child)
|
2014-04-02 01:46:34 -07:00
|
|
|
eo_do(child, eo_parent_set(NULL));
|
2013-11-08 04:24:40 -08:00
|
|
|
|
2015-03-25 06:42:34 -07:00
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_generic_data_del_all(pd);
|
|
|
|
_wref_destruct(pd);
|
|
|
|
_eo_callback_remove_all(pd);
|
2013-12-25 06:13:41 -08:00
|
|
|
|
2015-03-18 02:53:54 -07:00
|
|
|
eina_inarray_free(pd->callbacks);//added by avi
|
2015-03-24 23:59:24 -07:00
|
|
|
pd->callbacks = NULL;
|
2015-03-18 02:53:54 -07:00
|
|
|
|
2013-12-25 06:13:41 -08:00
|
|
|
_eo_condtor_done(obj);
|
|
|
|
}
|
|
|
|
|
2014-07-24 07:01:36 -07:00
|
|
|
EOLIAN static Eo *
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_base_finalize(Eo *obj, Eo_Base_Data *pd EINA_UNUSED)
|
2014-05-30 03:17:36 -07:00
|
|
|
{
|
|
|
|
return _eo_add_internal_end(obj);
|
|
|
|
}
|
|
|
|
|
2014-07-24 07:01:36 -07:00
|
|
|
EOLIAN static void
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_base_class_constructor(Eo_Class *klass EINA_UNUSED)
|
2013-12-25 06:13:41 -08:00
|
|
|
{
|
|
|
|
event_freeze_count = 0;
|
2014-05-19 07:17:08 -07:00
|
|
|
_legacy_events_hash = eina_hash_stringshared_new(_legacy_events_hash_free_cb);
|
|
|
|
}
|
|
|
|
|
2014-07-24 07:01:36 -07:00
|
|
|
EOLIAN static void
|
2014-06-03 03:23:53 -07:00
|
|
|
_eo_base_class_destructor(Eo_Class *klass EINA_UNUSED)
|
2014-05-19 07:17:08 -07:00
|
|
|
{
|
|
|
|
eina_hash_free(_legacy_events_hash);
|
2013-12-25 06:13:41 -08:00
|
|
|
}
|
|
|
|
|
2014-06-03 03:23:53 -07:00
|
|
|
#include "eo_base.eo.c"
|