eunue pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=a4d2c51d1404c1d8563dd7ac37e64ee105aa6226

commit a4d2c51d1404c1d8563dd7ac37e64ee105aa6226
Author: Jaeun Choi <jaeun12.c...@samsung.com>
Date:   Thu Mar 30 20:13:39 2017 +0900

    elm_flipselector: fixed flipselector item deletion process
    
    flipselector item destructor had a severe drawback and this patch fixes it.
    when deleting multiple items at once, the view needs to be updated only 
once.
    however, the destructor updated the view on deletion of
    every single item and it caused a severe performance issue.
    the worst case happened when deleting a flipselector object -
    with 10000 items, it took 10 seconds to finish deletion.
    
    this patch has two points:
    1. if a flipselector object is on deletion, item destructor doesn't update 
the view
    2. otherwise, view update is handled in one job for multiple item deletion
---
 src/lib/elementary/elm_flipselector.c        | 73 +++++++++++++++++-----------
 src/lib/elementary/elm_widget_flipselector.h |  2 +
 2 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/src/lib/elementary/elm_flipselector.c 
b/src/lib/elementary/elm_flipselector.c
index bae941e..dc14ecd 100644
--- a/src/lib/elementary/elm_flipselector.c
+++ b/src/lib/elementary/elm_flipselector.c
@@ -253,47 +253,64 @@ _send_msg(Elm_Flipselector_Data *sd,
    _on_item_changed(sd);
 }
 
+static void
+_view_update(void *data)
+{
+   Evas_Object *obj = data;
+   ELM_FLIPSELECTOR_DATA_GET(obj, sd);
+   Elm_Object_Item *eo_item;
+
+   sd->view_update = NULL;
+   sd->need_update = EINA_FALSE;
+
+   if (sd->current)
+     {
+        eo_item = sd->current->data;
+        ELM_FLIPSELECTOR_ITEM_DATA_GET(eo_item, item);
+        _send_msg(sd, MSG_FLIP_DOWN, (char *)item->label);
+     }
+   else
+     {
+        _send_msg(sd, MSG_FLIP_DOWN, "");
+        elm_layout_signal_emit(obj, "elm,state,button,hidden", "elm");
+     }
+}
+
 EOLIAN static void
 _elm_flipselector_item_efl_object_destructor(Eo *eo_item, 
Elm_Flipselector_Item_Data *item)
 {
-   Elm_Object_Item *eo_item2;
    Eina_List *l;
-
    ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd);
 
-   EINA_LIST_FOREACH(sd->items, l, eo_item2)
+   if (sd->deleting)
      {
-        if (eo_item2 == eo_item)
-          {
-             if (sd->current == l)
-               {
-                  sd->current = l->prev;
-                  if (!sd->current) sd->current = l->next;
-                  if (sd->current)
-                    {
-                       eo_item2 = sd->current->data;
-                       ELM_FLIPSELECTOR_ITEM_DATA_GET(eo_item2, item2);
-                       _send_msg(sd, MSG_FLIP_DOWN, (char *)item2->label);
-                    }
-                  else _send_msg(sd, MSG_FLIP_DOWN, "");
-               }
-             sd->items = eina_list_remove_list(sd->items, l);
-             break;
-          }
+        eina_stringshare_del(item->label);
+        sd->items = eina_list_remove(sd->items, eo_item);
+        efl_destructor(efl_super(eo_item, ELM_FLIPSELECTOR_ITEM_CLASS));
+
+        return;
      }
 
-   if (eina_list_count(sd->items) <= 1)
-      elm_layout_signal_emit
-         (sd->obj, "elm,state,button,hidden", "elm");
-   else
-      elm_layout_signal_emit
-         (sd->obj, "elm,state,button,visible", "elm");
+   if ((sd->current) && (sd->current->data == eo_item))
+     {
+        sd->need_update = EINA_TRUE;
+        l = sd->current->prev;
+        if (!l) l = sd->current->next;
+        if (!l) sd->current = NULL;
+        else sd->current = l;
+     }
 
    eina_stringshare_del(item->label);
+   sd->items = eina_list_remove(sd->items, eo_item);
+   efl_destructor(efl_super(eo_item, ELM_FLIPSELECTOR_ITEM_CLASS));
+
    _sentinel_eval(sd);
-   _update_view(sd->obj);
 
-   efl_destructor(efl_super(eo_item, ELM_FLIPSELECTOR_ITEM_CLASS));
+   if (sd->need_update)
+     {
+        if (sd->view_update) ecore_job_del(sd->view_update);
+        sd->view_update = ecore_job_add(_view_update, WIDGET(item));
+     }
 }
 
 EOLIAN static Eo *
diff --git a/src/lib/elementary/elm_widget_flipselector.h 
b/src/lib/elementary/elm_widget_flipselector.h
index 2e348ab..1fca1a6 100644
--- a/src/lib/elementary/elm_widget_flipselector.h
+++ b/src/lib/elementary/elm_widget_flipselector.h
@@ -32,6 +32,7 @@ struct _Elm_Flipselector_Data
    Eina_List            *sentinel; /* item containing the largest
                                     * label string */
    Ecore_Timer          *spin;
+   Ecore_Job            *view_update;
 
    unsigned int          max_len;
    double                interval, first_interval;
@@ -41,6 +42,7 @@ struct _Elm_Flipselector_Data
    int                   walking;
    Eina_Bool             evaluating : 1;
    Eina_Bool             deleting : 1;
+   Eina_Bool             need_update : 1;
 };
 
 typedef struct _Elm_Flipselector_Item_Data       Elm_Flipselector_Item_Data;

-- 


Reply via email to