evas: refactor efl_input_event and remove some of the lifecycle hack.

Differential Revision: https://phab.enlightenment.org/D6101
This commit is contained in:
Cedric BAIL 2018-05-04 13:00:53 -07:00
parent c447b61756
commit fe14abd929
11 changed files with 128 additions and 151 deletions

View File

@ -3511,7 +3511,7 @@ _ecore_evas_mouse_move_process_internal(Ecore_Evas *ee,
efl_event_callback_legacy_call(ee->evas,
_event_description_get(ev->action), evt);
efl_del(evt);
efl_unref(evt);
}
EAPI void
@ -4729,7 +4729,7 @@ _direct_mouse_move_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Move *info)
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
efl_del(evt);
efl_unref(evt);
return processed;
}
@ -4764,7 +4764,7 @@ _direct_mouse_wheel_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Wheel *info)
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
efl_del(evt);
efl_unref(evt);
return processed;
}
@ -4794,7 +4794,7 @@ _direct_mouse_inout(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info, Efl_Pointe
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
efl_del(evt);
efl_unref(evt);
return processed;
}
@ -4924,7 +4924,7 @@ _direct_axis_update_cb(Ecore_Evas *ee, const Ecore_Event_Axis_Update *info)
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
efl_del(evt);
efl_unref(evt);
return processed;
}
@ -4966,7 +4966,7 @@ _direct_key_updown_cb(Ecore_Evas *ee, const Ecore_Event_Key *info, Eina_Bool dow
efl_event_callback_legacy_call(e, EFL_EVENT_KEY_UP, evt);
processed = ev->evas_done;
efl_del(evt);
efl_unref(evt);
return processed;
}

View File

@ -2471,7 +2471,7 @@ _input_pointer_iterator_free(Input_Pointer_Iterator *it)
Efl_Input_Pointer *ptr;
EINA_LIST_FREE(it->list, ptr)
efl_del(ptr);
efl_unref(ptr);
eina_iterator_free(it->real_iterator);
free(it);
}

View File

@ -64,6 +64,73 @@ _efl_input_event_efl_object_provider_find(const Eo *obj, void *pd EINA_UNUSED, c
return efl_provider_find(efl_super(obj, MY_CLASS), klass);
}
static Eina_Hash *_cached_events = NULL;
static void
_del_hook(Eo *evt)
{
Efl_Input_Event *cached;
const Eo *klass = efl_class_get(evt);
cached = eina_hash_find(_cached_events, &klass);
if (!cached)
{
efl_reuse(evt);
eina_hash_add(_cached_events, &klass, evt);
efl_input_reset(evt);
}
else
{
efl_del_intercept_set(evt, NULL);
efl_unref(evt);
}
}
static void
_noref_death(void *data EINA_UNUSED, const Efl_Event *event)
{
efl_event_callback_del(event->object, EFL_EVENT_NOREF, _noref_death, NULL);
efl_del(event->object);
}
Efl_Input_Event *
efl_input_event_instance_get(Eo *klass, Eo *owner)
{
Efl_Input_Event *evt;
if (efl_invalidated_get(owner)) return NULL;
if (!_cached_events)
_cached_events = eina_hash_pointer_new(EINA_FREE_CB(efl_unref));
evt = eina_hash_find(_cached_events, &klass);
if (evt)
{
// eina_hash_del will call efl_unref, so prevent the destruction of the object
evt = efl_ref(evt);
eina_hash_del(_cached_events, &klass, evt);
efl_parent_set(evt, owner);
efl_unref(evt); // Remove reference before turning on self destruction
efl_event_callback_add(evt, EFL_EVENT_NOREF, _noref_death, NULL);
}
else
{
evt = efl_add(klass, owner,
efl_event_callback_add(efl_added, EFL_EVENT_NOREF, _noref_death, NULL),
efl_del_intercept_set(efl_added, _del_hook));
}
return efl_ref(evt);
}
void
efl_input_event_instance_clean(Eo *klass)
{
if (!_cached_events) return ;
eina_hash_del(_cached_events, &klass, NULL);
}
/* Internal EO APIs */
EOAPI EFL_FUNC_BODY_CONST(efl_input_legacy_info_get, void *, NULL)

View File

@ -2,6 +2,9 @@
# include <config.h>
#endif
#include "evas_common_private.h"
#include "evas_private.h"
#define EFL_INPUT_EVENT_PROTECTED
#include <Evas.h>
@ -13,29 +16,6 @@
#define MY_CLASS EFL_INPUT_FOCUS_CLASS
static Efl_Input_Focus *s_cached_event = NULL;
static void
_del_hook(Eo *evt)
{
if (!s_cached_event)
{
if (efl_parent_get(evt))
{
efl_ref(evt);
efl_parent_set(evt, NULL);
}
efl_reuse(evt);
s_cached_event = evt;
efl_input_reset(s_cached_event);
}
else
{
efl_del_intercept_set(evt, NULL);
efl_unref(evt);
}
}
static void
_efl_input_focus_free(Efl_Input_Focus_Data *pd)
{
@ -59,18 +39,6 @@ _efl_input_focus_efl_object_destructor(Eo *obj,
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_efl_input_focus_class_destructor(Efl_Class *klass EINA_UNUSED)
{
// this is a strange situation...
efl_del_intercept_set(s_cached_event, NULL);
if (efl_parent_get(s_cached_event))
efl_del(s_cached_event);
else
efl_unref(s_cached_event);
s_cached_event = NULL;
}
EOLIAN static void
_efl_input_focus_object_set(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd,
Efl_Object *object)
@ -134,29 +102,26 @@ _efl_input_focus_efl_duplicate_duplicate(const Eo *obj, Efl_Input_Focus_Data *pd
}
EOLIAN static Efl_Input_Focus *
_efl_input_focus_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EINA_UNUSED,
_efl_input_focus_efl_input_event_instance_get(Eo *klass, void *_pd EINA_UNUSED,
Eo *owner, void **priv)
{
Efl_Input_Focus_Data *ev;
Efl_Input_Focus *evt;
if (s_cached_event)
{
evt = s_cached_event;
s_cached_event = NULL;
efl_parent_set(evt, owner);
}
else
{
evt = efl_add(MY_CLASS, owner);
efl_del_intercept_set(evt, _del_hook);
}
evt = efl_input_event_instance_get(klass, owner);
if (!evt) return NULL;
ev = efl_data_scope_get(evt, MY_CLASS);
if (priv) *priv = ev;
return evt;
}
EOLIAN static void
_efl_input_focus_class_destructor(Efl_Class *klass)
{
efl_input_event_instance_clean(klass);
}
EOLIAN static void
_efl_input_focus_efl_input_event_reset(Eo *obj, Efl_Input_Focus_Data *pd)
{

View File

@ -83,15 +83,22 @@ _efl_input_hold_efl_object_destructor(Eo *obj, Efl_Input_Hold_Data *pd)
}
EOLIAN static Efl_Input_Event *
_efl_input_hold_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EINA_UNUSED,
_efl_input_hold_efl_input_event_instance_get(Eo *klass, void *_pd EINA_UNUSED,
Efl_Object *owner, void **priv)
{
// TODO: Implement a cache. Depends only on how many hold events we trigger.
Efl_Input_Event *evt = efl_add(MY_CLASS, owner);
Efl_Input_Event *evt = efl_input_event_instance_get(klass, owner);;
if (!evt) return NULL;
if (priv) *priv = efl_data_scope_get(evt, MY_CLASS);
return evt;
}
EOLIAN static void
_efl_input_hold_class_destructor(Efl_Class *klass)
{
efl_input_event_instance_clean(klass);
}
EOLIAN static void
_efl_input_hold_efl_input_event_reset(Eo *obj, Efl_Input_Hold_Data *pd)
{

View File

@ -10,6 +10,7 @@ class Efl.Input.Hold (Efl.Object, Efl.Input.Event)
}
}
implements {
class.destructor;
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Input.Event.reset;

View File

@ -12,50 +12,18 @@
#define MY_CLASS EFL_INPUT_KEY_CLASS
static Efl_Input_Key *s_cached_event = NULL;
static void
_del_hook(Eo *evt)
{
if (!s_cached_event)
{
if (efl_parent_get(evt))
{
efl_ref(evt);
efl_parent_set(evt, NULL);
}
efl_reuse(evt);
s_cached_event = evt;
efl_input_reset(s_cached_event);
}
else
{
efl_del_intercept_set(evt, NULL);
efl_unref(evt);
}
}
EOLIAN static Efl_Input_Key *
_efl_input_key_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EINA_UNUSED,
_efl_input_key_efl_input_event_instance_get(Eo *klass, void *_pd EINA_UNUSED,
Eo *owner, void **priv)
{
Efl_Input_Key_Data *ev;
Efl_Input_Key *evt;
Evas *evas;
if (s_cached_event)
{
evt = s_cached_event;
s_cached_event = NULL;
efl_parent_set(evt, owner);
}
else
{
evt = efl_add(EFL_INPUT_KEY_CLASS, owner);
efl_del_intercept_set(evt, _del_hook);
}
evt = efl_input_event_instance_get(klass, owner);
if (!evt) return NULL;
ev = efl_data_scope_get(evt, EFL_INPUT_KEY_CLASS);
ev = efl_data_scope_get(evt, klass);
ev->fake = EINA_FALSE;
if (priv) *priv = ev;
@ -71,15 +39,9 @@ _efl_input_key_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EIN
}
EOLIAN static void
_efl_input_key_class_destructor(Efl_Class *klass EINA_UNUSED)
_efl_input_key_class_destructor(Efl_Class *klass)
{
// this is a strange situation...
efl_del_intercept_set(s_cached_event, NULL);
if (efl_parent_get(s_cached_event))
efl_del(s_cached_event);
else
efl_unref(s_cached_event);
s_cached_event = NULL;
efl_input_event_instance_clean(klass);
}
EOLIAN static Efl_Object *

View File

@ -23,56 +23,30 @@
* Do not add any logic here.
*/
static Efl_Input_Pointer *s_cached_event = NULL;
static void
_del_hook(Eo *evt)
{
if (!s_cached_event)
{
if (efl_parent_get(evt))
{
efl_ref(evt);
efl_parent_set(evt, NULL);
}
efl_reuse(evt);
s_cached_event = evt;
efl_input_reset(s_cached_event);
}
else
{
efl_del_intercept_set(evt, NULL);
efl_unref(evt);
}
}
/* internal eo */
static Efl_Input_Pointer *
_efl_input_pointer_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EINA_UNUSED,
_efl_input_pointer_efl_input_event_instance_get(Eo *klass, void *_pd EINA_UNUSED,
Eo *owner, void **priv)
{
Efl_Input_Pointer_Data *ev;
Efl_Input_Pointer *evt;
if (s_cached_event)
{
evt = s_cached_event;
s_cached_event = NULL;
efl_parent_set(evt, owner);
}
else
{
evt = efl_add(EFL_INPUT_POINTER_CLASS, owner);
efl_del_intercept_set(evt, _del_hook);
}
evt = efl_input_event_instance_get(klass, owner);
if (!evt) return NULL;
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
ev = efl_data_scope_get(evt, klass);
ev->fake = EINA_FALSE;
if (priv) *priv = ev;
return evt;
}
EOLIAN static void
_efl_input_pointer_class_destructor(Efl_Class *klass)
{
efl_input_event_instance_clean(klass);
}
EAPI void
efl_input_pointer_finalize(Efl_Input_Pointer *obj)
{
@ -100,18 +74,6 @@ efl_input_pointer_finalize(Efl_Input_Pointer *obj)
ev->pressed_buttons = pdata->button;
}
EOLIAN static void
_efl_input_pointer_class_destructor(Efl_Class *klass EINA_UNUSED)
{
// this is a strange situation...
efl_del_intercept_set(s_cached_event, NULL);
if (efl_parent_get(s_cached_event))
efl_del(s_cached_event);
else
efl_unref(s_cached_event);
s_cached_event = NULL;
}
EOLIAN static Efl_Object *
_efl_input_pointer_efl_object_constructor(Eo *obj, Efl_Input_Pointer_Data *pd)
{
@ -151,6 +113,16 @@ _efl_input_pointer_efl_duplicate_duplicate(const Eo *obj, Efl_Input_Pointer_Data
Efl_Input_Pointer_Data *ev;
Efl_Input_Focus *evt;
if (efl_invalidated_get(obj))
{
ERR("Object %s has already been invalidated and can't be duplicated.", efl_debug_name_get(obj));
return NULL;
}
if (!efl_parent_get(obj))
{
ERR("Object %s has not parent during duplicate.", efl_debug_name_get(obj));
return NULL;
}
evt = efl_add(MY_CLASS, efl_parent_get(obj),
efl_allow_parent_unref_set(efl_added, EINA_TRUE));
ev = efl_data_scope_get(evt, MY_CLASS);

View File

@ -134,7 +134,7 @@ _evas_focus_dispatch_event(Evas_Object_Protected_Data *obj, Efl_Input_Device *se
evt, _evas_object_event_new(),
efl_object_focus_event);
evas_event_callback_call(obj->layer->evas->evas, cb_evas, evt);
efl_del(evt);
efl_unref(evt);
}
static void

View File

@ -710,7 +710,7 @@ _evas_canvas_focus_inout_dispatch(Eo *eo_e, Efl_Input_Device *seat,
efl_event_callback_call(eo_e,
in ? EFL_EVENT_FOCUS_IN : EFL_EVENT_FOCUS_OUT,
evt);
efl_del(evt);
efl_unref(evt);
}
EOLIAN static void

View File

@ -1881,6 +1881,9 @@ void _evas_device_cleanup(Evas *e);
Evas_Device *_evas_device_top_get(const Evas *e);
/* legacy/eo events */
Efl_Input_Event *efl_input_event_instance_get(Eo *klass, Eo *owner);
void efl_input_event_instance_clean(Eo *klass);
void *efl_input_pointer_legacy_info_fill(Evas *eo_evas, Efl_Input_Key *eo_ev, Evas_Callback_Type type, Evas_Event_Flags **pflags);
void *efl_input_key_legacy_info_fill(Efl_Input_Key *evt, Evas_Event_Flags **pflags);
void *efl_input_hold_legacy_info_fill(Efl_Input_Hold *evt, Evas_Event_Flags **pflags);