discomfitor pushed a commit to branch master.

http://git.enlightenment.org/apps/empc.git/commit/?id=39bc858b20ca0a0ba2c1427ce64d57163b819dd2

commit 39bc858b20ca0a0ba2c1427ce64d57163b819dd2
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Mon Feb 8 11:52:46 2016 -0500

    handle incremental queue version updating in the ui
    
    this removes a number of workarounds related to deleting items from the 
queue
    and significantly improves ui responsiveness when editing the queue
    
    ref T3147
---
 src/bin/empc.c | 203 +++++++++++++++++++++++++++++++++------------------------
 1 file changed, 119 insertions(+), 84 deletions(-)

diff --git a/src/bin/empc.c b/src/bin/empc.c
index 8a7ffeb..dc8585c 100644
--- a/src/bin/empc.c
+++ b/src/bin/empc.c
@@ -32,7 +32,6 @@ static unsigned int empd_port;
 static Eldbus_Pending *config_call;
 
 static int empd_state = 0;
-static int noclear = 0;
 
 static Evas_Object *win = NULL;
 static Evas_Object *bg[2] = {NULL};
@@ -113,7 +112,7 @@ static size_t empc_module_size[EMPC_MODULE_TYPE_LAST] =
 static void queue_list_header_image(void *data, Empc_Fetch_Request *req, 
Evas_Object *obj);
 static void filesystem_base(Eldbus_Proxy *proxy, void *data, Eldbus_Pending 
*pending, Eldbus_Error_Info *error, Eina_Value *args);
 static void filesystem_item_image(void *data, Empc_Fetch_Request *req, 
Evas_Object *obj);
-static void queue_list_handler(Eina_Value *value, Eina_Bool cached);
+static void queue_list_handler(Eina_Value *value, Eina_Bool update);
 static void filesystem_next(void *data, Evas_Object *obj, void *event_info);
 static void filesystem_prev(void);
 static Evas_Object *filesystem_new(const char *uri);
@@ -1864,7 +1863,7 @@ static void
 queue_list_cached(Eldbus_Proxy *proxy EINA_UNUSED, void *data, Eldbus_Pending 
*pending EINA_UNUSED, Eldbus_Error_Info *error EINA_UNUSED, Eina_Value *value)
 {
    if (value)
-     queue_list_handler(value, EINA_TRUE);
+     queue_list_handler(value, EINA_FALSE);
    if ((empd_songid == -1) && ((long)data == -1))
      empd_empdd_status_call(empd_proxy);
 }
@@ -2170,23 +2169,16 @@ queue_list_item_realize(void *data EINA_UNUSED, 
Evas_Object *obj EINA_UNUSED, vo
 static void
 queue_list_delete_list(const Eina_List *items)
 {
-   Eina_List *l, *headers = NULL;
+   Eina_List *l;
    int start = -1, num = 0, total = 0;
-   Elm_Object_Item *it, *next, *hdr = NULL;
+   Elm_Object_Item *it, *next;
    Eina_Bool del_playing = EINA_FALSE;
    Empd_Empdd_Song *so;
-   unsigned int sub = 0;
 
    if (!items) return;
    l = eina_list_sort(eina_list_clone(items), 0, 
(Eina_Compare_Cb)queue_list_sort);
    EINA_LIST_FREE(l, it)
      {
-        if (hdr != elm_genlist_item_parent_get(it))
-          {
-             hdr = elm_genlist_item_parent_get(it);
-             headers = eina_list_append(headers, hdr);
-             sub = elm_genlist_item_subitems_count(hdr);
-          }
         /* check for contiguous selection */
         so = elm_object_item_data_get(it);
         if (start == -1)
@@ -2205,18 +2197,10 @@ queue_list_delete_list(const Eina_List *items)
              start = -1, num = 0;
              if (!del_playing)
                total += num;
-             if (!sub)
-               headers = eina_list_remove(headers, hdr);
           }
         else
-          num++, sub--;
-        elm_object_item_del(it);
+          num++;
      }
-   noclear++;
-   if (!sub)
-     headers = eina_list_remove(headers, hdr);
-   EINA_LIST_FREE(headers, hdr)
-     elm_genlist_item_fields_update(hdr, EMPC_TEXT_TIME, 
ELM_GENLIST_ITEM_FIELD_TEXT);
    if (!num) return;
    empd_empdd_delete_list_range_call(empd_proxy, start, num - 1);
    if ((!del_playing) || (empd_state != MPD_STATE_PLAY)) return;
@@ -2236,7 +2220,7 @@ static void
 queue_list_delete_inverted(void)
 {
    const Eina_List *items;
-   Eina_List *l, *headers = NULL;
+   Eina_List *l;
    int start = -1;
    Elm_Object_Item *it, *prev, *next, *hdr = NULL;
    int del_playing = -1;
@@ -2265,10 +2249,7 @@ queue_list_delete_inverted(void)
    EINA_LIST_FREE(l, it)
      {
         if (hdr != elm_genlist_item_parent_get(it))
-          {
-             hdr = elm_genlist_item_parent_get(it);
-             headers = eina_list_append(headers, hdr);
-          }
+          hdr = elm_genlist_item_parent_get(it);
         next = elm_genlist_item_next_get(it);
         prev = elm_genlist_item_prev_get(it);
         so = elm_object_item_data_get(next);
@@ -2299,8 +2280,6 @@ queue_list_delete_inverted(void)
              start = -1;
           }
      }
-   EINA_LIST_FREE(headers, hdr)
-     elm_genlist_item_fields_update(hdr, EMPC_TEXT_TIME, 
ELM_GENLIST_ITEM_FIELD_TEXT);
    if (start == -1) return;
    empd_empdd_delete_list_range_call(empd_proxy, start, -1);
    if ((!del_playing) || (empd_state != MPD_STATE_PLAY)) return;
@@ -2692,25 +2671,24 @@ queue_list_find_insert_point(Empd_Empdd_Song *so)
    Elm_Object_Item *it, *itp;
    Empd_Empdd_Song *soi;
 
+   if (!elm_genlist_items_count(queue_list)) return NULL;
    if ((unsigned int)so->song_pos > (elm_genlist_items_count(queue_list) / 2))
      {
         it = elm_genlist_last_item_get(queue_list);
-        if (!it) return NULL;
         do
           {
              soi = elm_object_item_data_get(it);
-             if (so->song_pos > soi->song_pos) return it;
+             if (so->song_pos >= soi->song_pos) return it;
              it = elm_genlist_item_prev_get(it);
           } while (it);
         return NULL;
      }
 
    itp = it = elm_genlist_first_item_get(queue_list);
-   if (!it) return NULL;
    do
      {
         soi = elm_object_item_data_get(it);
-        if (so->song_pos < soi->song_pos) return itp;
+        if (so->song_pos <= soi->song_pos) return itp;
         itp = it;
         it = elm_genlist_item_next_get(it);
      } while (it);
@@ -2785,15 +2763,12 @@ queue_list_item_unselect(void *data EINA_UNUSED, 
Evas_Object *obj, void *event_i
 }
 
 static void
-queue_list_handler(Eina_Value *value, Eina_Bool cached)
+queue_list_handler(Eina_Value *value, Eina_Bool update)
 {
    Empd_Array_Songs *songs = NULL;
    Empd_Empdd_Song *so;
    const char *album = NULL, *artist = NULL;
    Elm_Object_Item *itl = NULL, *ith = NULL;
-   int x, y, w, h;
-   Eina_Bool reset = EINA_FALSE;
-   Eina_List *sel = NULL;
    static Elm_Genlist_Item_Class queue_itc = {
       .item_style = "default",
       .func = {
@@ -2817,57 +2792,110 @@ queue_list_handler(Eina_Value *value, Eina_Bool cached)
         EINA_LOG_ERR("conversion failure");
         return;
      }
-   if ((!cached) && (!noclear))
+   if (update && songs->songs)
      {
-        Elm_Object_Item *it;
-        const Eina_List *l, *its = elm_genlist_selected_items_get(queue_list);
-        elm_scroller_region_get(queue_list, &x, &y, &w, &h);
-        if (its)
+        Elm_Object_Item *insert;
+        Empd_Empdd_Song *exist;
+
+        so = eina_list_data_get(songs->songs);
+        /* find existing song with first updated song's id */
+        insert = eina_hash_find(empd_current_queue, &so->songid);
+        if (insert)
           {
-             EINA_LIST_FOREACH(its, l, it)
-               sel = eina_list_append(sel, 
Empd_Empdd_Song_copy(elm_object_item_data_get(it)));
+             exist = elm_object_item_data_get(insert);
+             if (exist->song_pos > so->song_pos)
+               {
+                  /* songs removed before existing item:
+                   * - remove items until exist has target position
+                   */
+                  int target = so->song_pos;
+                  Elm_Object_Item *prev, *next = insert;
+
+                  do
+                    {
+                       insert = elm_genlist_item_prev_get(next);
+                       if (elm_genlist_item_subitems_count(insert))
+                         insert = elm_genlist_item_prev_get(insert);
+                       if (!insert) break;
+                       exist = elm_object_item_data_get(insert);
+                       if (exist->song_pos < target) break;
+                       elm_object_item_del(insert);
+                    } while (insert);
+                  prev = elm_genlist_item_prev_get(next);
+                  if (prev)
+                    {
+                       Elm_Object_Item *parent;
+                       Empd_Empdd_Song *a, *b;
+
+                       parent = elm_genlist_item_parent_get(next);
+                       a = elm_object_item_data_get(prev);
+                       b = elm_object_item_data_get(parent);
+                       /* check whether the previous album can be merged with 
the next one */
+                       if ((a->artist == b->artist) && (a->album == b->album) 
&&
+                           (parent != elm_genlist_item_parent_get(prev)))
+                         elm_object_item_del(parent);
+                    }
+               }
+          }
+     }
+   else if (update)
+     {
+        while ((unsigned int)eina_hash_population(empd_current_queue) > 
empd_queue_length)
+          {
+             Elm_Object_Item *it;
+
+             /* skip header item... */
+             it = 
elm_genlist_item_prev_get(elm_genlist_last_item_get(queue_list));
+             elm_object_item_del(it);
           }
-        queue_list_clear();
-        reset = EINA_TRUE;
      }
    EINA_LIST_FREE(songs->songs, so)
      {
         Elm_Object_Item *it = NULL;
         Empd_Empdd_Song *sop;
 
-        if (cached || noclear)
+        it = eina_hash_find(empd_current_queue, &so->songid);
+        if (it)
           {
-             it = eina_hash_find(empd_current_queue, &so->songid);
-             if (it)
+             Empd_Empdd_Song *ss = elm_object_item_data_get(it);
+             if (Empd_Empdd_Song_eq(so, ss))
+               {
+                  Empd_Empdd_Song_free(so);
+                  so = ss;
+               }
+             else
                {
-                  Empd_Empdd_Song *ss = elm_object_item_data_get(it);
-                  if (Empd_Empdd_Song_eq(so, ss))
+                  Elm_Object_Item *parent;
+
+                  parent = elm_genlist_item_parent_get(it);
+                  sop = elm_object_item_data_get(parent);
+                  if (Empd_Empdd_Song_eq(sop, ss))
                     {
-                       Empd_Empdd_Song_free(so);
-                       so = ss;
+                       Empd_Empdd_Song_free(sop);
+                       elm_object_item_data_set(parent, 
Empd_Empdd_Song_copy(so));
+                       elm_genlist_item_update(parent);
                     }
-                  else
+                  Empd_Empdd_Song_free(ss);
+                  elm_object_item_data_set(it, so);
+                  elm_genlist_item_update(it);
+                  if (so->songid == empd_songid)
                     {
-                       Empd_Empdd_Song_free(ss);
-                       elm_object_item_data_set(it, so);
-                       elm_genlist_item_update(it);
-                       if (so->songid == empd_songid)
+                       if ((so->track != empd_song_track) || (empd_song_title 
!= so->title))
                          {
-                            if ((so->track != empd_song_track) || 
(empd_song_title != so->title))
-                              {
-                                 empd_song_track = so->track;
-                                 eina_stringshare_refplace(&empd_song_title, 
so->title);
-                                 title_text_set();
-                                 elm_object_tooltip_hide(bg[background_num]);
-                              }
+                            empd_song_track = so->track;
+                            eina_stringshare_refplace(&empd_song_title, 
so->title);
+                            title_text_set();
+                            elm_object_tooltip_hide(bg[background_num]);
                          }
                     }
-                  ith = elm_genlist_item_parent_get(it);
                }
+             ith = elm_genlist_item_parent_get(it);
           }
+
         if (!it)
           {
              Elm_Object_Item *itp = NULL;
+             Eina_Bool end = EINA_FALSE;
 
              if (((!album) && (!artist)) || (album != so->album) || (artist != 
so->artist) || (!ith))
                {
@@ -2882,25 +2910,29 @@ queue_list_handler(Eina_Value *value, Eina_Bool cached)
                               {
                                  use = EINA_TRUE;
                                  ith = elm_genlist_item_parent_get(itp);
-                                 if (!ith) ith = itp, itp = NULL;
                               }
+                            if (itp && (itp == 
elm_genlist_last_item_get(queue_list)))
+                              end = EINA_TRUE;
                          }
                     }
                   if (!use)
                     {
                        char buf[1024];
 
-                       if (itp)
-                         ith = elm_genlist_item_insert_after(queue_list, 
&header_itc, Empd_Empdd_Song_copy(so), NULL, itp, ELM_GENLIST_ITEM_GROUP, NULL, 
NULL);
-                       else
+                       if (end || (!itp))
                          ith = elm_genlist_item_append(queue_list, 
&header_itc, Empd_Empdd_Song_copy(so), NULL, ELM_GENLIST_ITEM_GROUP, NULL, 
NULL);
+                       else
+                         ith = elm_genlist_item_insert_after(queue_list, 
&header_itc, Empd_Empdd_Song_copy(so), NULL, itp, ELM_GENLIST_ITEM_GROUP, NULL, 
NULL);
                        snprintf(buf, sizeof(buf), "%s:::%s", so->artist, 
so->album);
                        //INF("NEW HEADER(%p): %s", ith, buf);
                        eina_hash_list_append(empd_current_queue_headers, buf, 
ith);
                        elm_genlist_item_select_mode_set(ith, 
ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
+                       itp = NULL;
                     }
                }
-             if (itp)
+             if (end || (!itp))
+               it = elm_genlist_item_append(queue_list, &queue_itc, so, ith, 
ELM_GENLIST_ITEM_NONE, queue_list_item_select, NULL);
+             else if (itp)
                it = elm_genlist_item_insert_after(queue_list, &queue_itc, so, 
ith, itp, ELM_GENLIST_ITEM_NONE, queue_list_item_select, NULL);
              else
                it = elm_genlist_item_sorted_insert(queue_list, &queue_itc, so, 
ith, ELM_GENLIST_ITEM_NONE, (Eina_Compare_Cb)queue_list_sort, 
queue_list_item_select, NULL);
@@ -2931,27 +2963,29 @@ queue_list_handler(Eina_Value *value, Eina_Bool cached)
         artist = so->artist;
         itl = it;
      }
-   selecting = EINA_TRUE;
-   EINA_LIST_FREE(sel, so)
-     {
-        itl = eina_hash_find(empd_current_queue, &so->songid);
-        if (itl)
-          elm_genlist_item_selected_set(itl, EINA_TRUE);
-        Empd_Empdd_Song_free(so);
-     }
-   selecting = EINA_FALSE;
    free(songs);
-   if (noclear)
-     noclear--;
-   if (reset)
-     elm_scroller_region_show(queue_list, x, y, w, h);
 }
 
 static Eina_Bool
 empc_queue_list(void *d EINA_UNUSED, int t EINA_UNUSED, 
Empd_Empdd_QueueList_Data *ev)
 {
+   Elm_Object_Item *it;
+
+   it = empd_song_item;
    queue_list_handler(ev->value, EINA_FALSE);
-   if (empd_song_item)
+   if ((!it) || (it != empd_song_item))
+     elm_genlist_item_show(empd_song_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+empc_queue_list_changes(void *d EINA_UNUSED, int t EINA_UNUSED, 
Empd_Empdd_QueueList_Data *ev)
+{
+   Elm_Object_Item *it;
+
+   it = empd_song_item;
+   queue_list_handler(ev->value, EINA_TRUE);
+   if ((!it) || (it != empd_song_item))
      elm_genlist_item_show(empd_song_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
    return ECORE_CALLBACK_RENEW;
 }
@@ -3851,6 +3885,7 @@ main(int argc, char *argv[])
    E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_PERMISSION_FAILED_EVENT, 
empc_permission_fail, NULL);
    E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_STATUS_EVENT, empc_status, NULL);
    E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_QUEUE_LIST_EVENT, 
empc_queue_list, NULL);
+   E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_QUEUE_CHANGES_META_EVENT, 
empc_queue_list_changes, NULL);
    E_LIST_HANDLER_APPEND(handlers, EMPD_EMPDD_DATABASE_UPDATE_END_EVENT, 
empc_database_end, NULL);
    E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_BACKGROUND_CHANGED_EVENT, 
empc_bg_changed, NULL);
 

-- 


Reply via email to