summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2020-01-21 14:51:16 -0500
committerMike Blumenkrantz <zmike@samsung.com>2020-01-23 15:25:14 -0500
commitfefeeaf227a527b0750909cda6ee636765f0bccf (patch)
tree04537fb80275ab2241eb5d73b6d8474b617087b4
parentb884e76c7fb452ebb0a26db58974f61c5e2983ec (diff)
downloadefl-fefeeaf227a527b0750909cda6ee636765f0bccf.tar.gz
efl/gesture: redo (and make stupider) hash usage in gesture manager
this rewrites the gesture event dispatcher to use a hash of hashes for tracking which events are being watched on a given object to avoid: * dispatching n gesture events per object to each callback, where n is the number of gesture callbacks for any given type * removing all gesture callbacks when only one callback is removed this is not smart code. it should be improved at some time, but that time is not now. Differential Revision: https://phab.enlightenment.org/D11144
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_manager.c171
1 files changed, 97 insertions, 74 deletions
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_manager.c b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
index db2b3c16a2..b7b5558e94 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_manager.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
@@ -14,7 +14,7 @@ typedef struct _Object_Gesture
typedef struct _Efl_Canvas_Gesture_Manager_Data
{
//Keeps track of all the gesture request for a particular target
- Eina_Hash *m_gesture_contex; // (*target, *event_desc)
+ Eina_Hash *m_gesture_contex; // (*target, Eina_Hash(type, int))
//Keeps all the event directed to this particular object from touch_begin till touch_end
Eina_Hash *m_object_events; // (*target, *efl_gesture_touch)
//Keeps all the recognizer registered to gesture manager
@@ -59,7 +59,7 @@ _efl_canvas_gesture_manager_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_M
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->m_recognizers = eina_hash_pointer_new(EINA_FREE_CB(_hash_unref_cb));
- pd->m_gesture_contex = eina_hash_pointer_new(NULL);
+ pd->m_gesture_contex = eina_hash_pointer_new(EINA_FREE_CB(eina_hash_free));
pd->m_object_events = eina_hash_pointer_new(EINA_FREE_CB(_hash_unref_cb));
pd->m_object_gestures = NULL;
pd->m_gestures_to_delete = NULL;
@@ -136,7 +136,18 @@ _efl_canvas_gesture_manager_callback_add_hook(void *data, Eo *target, const Efl_
if (recognizer)
{
//Add it to the gesture context.
- eina_hash_list_append(pd->m_gesture_contex, &target, type);
+ Eina_Hash *thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
+ int count = 0;
+ /* already present */
+ if (thisisreallystupid)
+ count = (intptr_t)eina_hash_find(thisisreallystupid, &type);
+ else
+ {
+ thisisreallystupid = eina_hash_pointer_new(NULL);
+ eina_hash_set(pd->m_gesture_contex, &target, thisisreallystupid);
+ }
+ count++;
+ eina_hash_set(thisisreallystupid, &type, (intptr_t*)(long)count);
}
}
@@ -148,7 +159,17 @@ _efl_canvas_gesture_manager_callback_del_hook(void *data, Eo *target, const Efl_
Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find(pd->m_recognizers, &type);
if (recognizer)
{
- eina_hash_list_remove(pd->m_gesture_contex, &target, type);
+ Eina_Hash *thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
+ int count;
+
+ if (!thisisreallystupid) return;
+ count = (intptr_t)eina_hash_find(thisisreallystupid, &type);
+ if (!count) return;
+ count--;
+ if (count) return;
+ eina_hash_del_by_key(thisisreallystupid, &type);
+ if (eina_hash_population(thisisreallystupid)) return;
+ eina_hash_del_by_key(pd->m_gesture_contex, &target);
_cleanup_cached_gestures(pd, target, type);
}
}
@@ -157,98 +178,100 @@ void
_efl_canvas_gesture_manager_filter_event(void *data, Eo *target, void *event)
{
Efl_Canvas_Gesture_Manager_Data *pd = data;
- Eina_List *l, *gesture_context;
- const Efl_Event_Description *gesture_type;
+ Eina_Hash *thisisreallystupid;
+ Eina_Iterator *it;
+ const Efl_Event_Description **gtype;
Efl_Canvas_Gesture_Recognizer *recognizer;
Efl_Canvas_Gesture *gesture;
Efl_Canvas_Gesture_Recognizer_Result recog_result;
Efl_Canvas_Gesture_Recognizer_Result recog_state;
Efl_Canvas_Gesture_Touch *touch_event;
- gesture_context = eina_hash_find(pd->m_gesture_contex, &target);
- if (gesture_context)
+ thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
+ if (!thisisreallystupid) return;
+ it = eina_hash_iterator_key_new(thisisreallystupid);
+ EINA_ITERATOR_FOREACH(it, gtype)
{
- EINA_LIST_FOREACH(gesture_context, l, gesture_type)
- {
- //Check there is already created event exist or not.
- touch_event = eina_hash_find(pd->m_object_events, &gesture_type);
+ const Efl_Event_Description *gesture_type = *gtype;
+ //Check there is already created event exist or not.
+ touch_event = eina_hash_find(pd->m_object_events, &gesture_type);
- if (!touch_event)
- {
- touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL);
- eina_hash_add(pd->m_object_events, &gesture_type, touch_event);
- }
+ if (!touch_event)
+ {
+ touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL);
+ eina_hash_add(pd->m_object_events, &gesture_type, touch_event);
+ }
- efl_gesture_touch_point_record(touch_event, event);
+ efl_gesture_touch_point_record(touch_event, event);
- //This is for handling the case that mouse event pairs dont match.
- //Such as the case of canceling gesture recognition after a mouse down.
- if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
- continue;
+ //This is for handling the case that mouse event pairs dont match.
+ //Such as the case of canceling gesture recognition after a mouse down.
+ if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
+ continue;
- recognizer = eina_hash_find(pd->m_recognizers, &gesture_type);
+ recognizer = eina_hash_find(pd->m_recognizers, &gesture_type);
- //If the gesture canceled or already finished by recognizer.
- gesture = _get_state(pd, target, recognizer, gesture_type);
- if (!gesture)
- continue;
+ //If the gesture canceled or already finished by recognizer.
+ gesture = _get_state(pd, target, recognizer, gesture_type);
+ if (!gesture)
+ continue;
- /* this is the "default" value for the event, recognizers may modify it if necessary */
- efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event));
+ /* this is the "default" value for the event, recognizers may modify it if necessary */
+ efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event));
- //Gesture detecting.
- recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event);
- recog_state = recog_result & EFL_GESTURE_RECOGNIZER_RESULT_RESULT_MASK;
+ //Gesture detecting.
+ recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event);
+ recog_state = recog_result & EFL_GESTURE_RECOGNIZER_RESULT_RESULT_MASK;
- Efl_Canvas_Gesture_Recognizer_Data *rd =
- efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
+ Efl_Canvas_Gesture_Recognizer_Data *rd =
+ efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
- if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER)
- {
- if (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_NONE)
- efl_gesture_state_set(gesture, EFL_GESTURE_STATE_STARTED);
- else
- efl_gesture_state_set(gesture, EFL_GESTURE_STATE_UPDATED);
- }
- else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH)
- {
- efl_gesture_state_set(gesture, EFL_GESTURE_STATE_FINISHED);
- }
- else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_MAYBE)
- {
- continue;
- }
- else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)
- {
- if (efl_gesture_state_get(gesture) != EFL_GESTURE_STATE_NONE)
- efl_gesture_state_set(gesture, EFL_GESTURE_STATE_CANCELED);
- else
- {
- if (rd->continues)
- continue;
- goto post_event;
- }
- }
- else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_IGNORE)
+ if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER)
+ {
+ if (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_NONE)
+ efl_gesture_state_set(gesture, EFL_GESTURE_STATE_STARTED);
+ else
+ efl_gesture_state_set(gesture, EFL_GESTURE_STATE_UPDATED);
+ }
+ else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH)
+ {
+ efl_gesture_state_set(gesture, EFL_GESTURE_STATE_FINISHED);
+ }
+ else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_MAYBE)
+ {
+ continue;
+ }
+ else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)
+ {
+ if (efl_gesture_state_get(gesture) != EFL_GESTURE_STATE_NONE)
+ efl_gesture_state_set(gesture, EFL_GESTURE_STATE_CANCELED);
+ else
{
- continue;
+ if (rd->continues)
+ continue;
+ goto post_event;
}
+ }
+ else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_IGNORE)
+ {
+ continue;
+ }
- efl_gesture_timestamp_set(gesture, efl_gesture_touch_cur_timestamp_get(touch_event));
- efl_event_callback_call(target, gesture_type, gesture);
+ efl_gesture_timestamp_set(gesture, efl_gesture_touch_cur_timestamp_get(touch_event));
+ efl_event_callback_call(target, gesture_type, gesture);
post_event:
- //If the current event recognizes the gesture continuously, dont delete gesture.
- if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) &&
- !rd->continues)
- {
- _cleanup_cached_gestures(pd, target, gesture_type);
- eina_hash_del(pd->m_object_events, &gesture_type, NULL);
- //FIXME: delete it by object not list.
- _cleanup_object(pd->m_gestures_to_delete);
- pd->m_gestures_to_delete = NULL;
- }
+ //If the current event recognizes the gesture continuously, dont delete gesture.
+ if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) &&
+ !rd->continues)
+ {
+ _cleanup_cached_gestures(pd, target, gesture_type);
+ eina_hash_del(pd->m_object_events, &gesture_type, NULL);
+ //FIXME: delete it by object not list.
+ _cleanup_object(pd->m_gestures_to_delete);
+ pd->m_gestures_to_delete = NULL;
}
}
+ eina_iterator_free(it);
}
EOLIAN static void