elm_flipselector: fixed flipselector item deletion process 96/122296/2
authorJaeun Choi <jaeun12.choi@samsung.com>
Fri, 31 Mar 2017 04:21:05 +0000 (13:21 +0900)
committerJaeun Choi <jaeun12.choi@samsung.com>
Fri, 31 Mar 2017 05:21:14 +0000 (14:21 +0900)
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

origin: upstream
a4d2c51d1404c1d8563dd7ac37e64ee105aa6226
e2d1da14b8f9a8dfcce6e470a10e28635a2c641d

Change-Id: Ia46233558797fcfd208304946fb55fd881d8b11d
Signed-off-by: Jaeun Choi <jaeun12.choi@samsung.com>
src/lib/elm_flipselector.c
src/lib/elm_widget_flipselector.h

index 646f9c13bad690e7016df70e7a6ca4662b6f2746..a1ed26d9cb233f7cae21657afff891cd028c4202 100644 (file)
@@ -283,47 +283,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_eo_base_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);
+        eo_do_super(eo_item, ELM_FLIPSELECTOR_ITEM_CLASS, eo_destructor());
+
+        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);
+   eo_do_super(eo_item, ELM_FLIPSELECTOR_ITEM_CLASS, eo_destructor());
+
    _sentinel_eval(sd);
-   _update_view(sd->obj);
 
-   eo_do_super(eo_item, ELM_FLIPSELECTOR_ITEM_CLASS, eo_destructor());
+   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 *
@@ -587,6 +604,7 @@ _elm_flipselector_evas_object_smart_del(Eo *obj, Elm_Flipselector_Data *sd)
      eo_do(DATA_GET(sd->items), elm_wdg_item_del());
 
    ecore_timer_del(sd->spin);
+   ecore_job_del(sd->view_update);
 
    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
 }
index 9309233be723b79c6fe95ce6071a248b92e3db9d..f5a5244c7dd37bcf282cd95023883e9d5ce17f1b 100644 (file)
@@ -33,6 +33,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;
@@ -40,6 +41,7 @@ struct _Elm_Flipselector_Data
    int                   walking;
    Eina_Bool             evaluating : 1;
    Eina_Bool             deleting : 1;
+   Eina_Bool             need_update : 1;
    Evas_Object           *access_top_button;
    Evas_Object           *access_bottom_button;
 };