summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2016-02-08 11:52:46 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2016-02-06 21:01:39 -0500
commitba50156ec42fb3ed2ebab97f1812b7f1b2890bd9 (patch)
tree4045e4d4de6d45d5a0f5e079b6b4db6f666282ac /src
parent4db0a19dd39cf09c1b0d3e0fea7a47a2e86dfcc8 (diff)
add signal/handling for managing queue list changes using incremental updates
this is a significantly more lightweight method of updating the current queue after any changes have been made, allowing clients to perform updates on only part of the current queue instead of receiving the entire thing in a giant chunk any time a change occurs
Diffstat (limited to 'src')
-rw-r--r--src/bin/empdd.c87
-rw-r--r--src/bin/empdd.xml3
2 files changed, 66 insertions, 24 deletions
diff --git a/src/bin/empdd.c b/src/bin/empdd.c
index 9aebb70..6d4d5ef 100644
--- a/src/bin/empdd.c
+++ b/src/bin/empdd.c
@@ -77,6 +77,7 @@ typedef enum
77 EMPD_COMMAND_UPDATE, 77 EMPD_COMMAND_UPDATE,
78 EMPD_COMMAND_FIND, 78 EMPD_COMMAND_FIND,
79 EMPD_COMMAND_IDLE, 79 EMPD_COMMAND_IDLE,
80 EMPD_COMMAND_QUEUE_CHANGES_META,
80} EMPD_Command; 81} EMPD_Command;
81 82
82static const char *cmd_txt[] = 83static const char *cmd_txt[] =
@@ -113,6 +114,7 @@ static const char *cmd_txt[] =
113 CMD_TXT(EMPD_COMMAND_UPDATE) 114 CMD_TXT(EMPD_COMMAND_UPDATE)
114 CMD_TXT(EMPD_COMMAND_FIND) 115 CMD_TXT(EMPD_COMMAND_FIND)
115 CMD_TXT(EMPD_COMMAND_IDLE) 116 CMD_TXT(EMPD_COMMAND_IDLE)
117 CMD_TXT(EMPD_COMMAND_QUEUE_CHANGES_META)
116}; 118};
117 119
118typedef enum 120typedef enum
@@ -124,6 +126,7 @@ typedef enum
124 EMPD_SIGNAL_STATUS, 126 EMPD_SIGNAL_STATUS,
125 EMPD_SIGNAL_CURRENT_SONG, 127 EMPD_SIGNAL_CURRENT_SONG,
126 EMPD_SIGNAL_QUEUE_LIST, 128 EMPD_SIGNAL_QUEUE_LIST,
129 EMPD_SIGNAL_QUEUE_CHANGES_META,
127 EMPD_SIGNAL_DATABASE_UPDATE_BEGIN, 130 EMPD_SIGNAL_DATABASE_UPDATE_BEGIN,
128 EMPD_SIGNAL_DATABASE_UPDATE_END, 131 EMPD_SIGNAL_DATABASE_UPDATE_END,
129} EMPD_Signals; 132} EMPD_Signals;
@@ -144,6 +147,7 @@ static const Eldbus_Signal empd_signals[] =
144 {"s", "artist"}, {"s", "composer"}, {"s", "title"}, {"s", "album"}, {"i", "track"}, 147 {"s", "artist"}, {"s", "composer"}, {"s", "title"}, {"s", "album"}, {"i", "track"},
145 {"s", "name"}, {"s", "date"}, {"s", "disc"}, {"s", "genre"}, {"i", "song_pos"}, {"i", "songid"}), 0}, 148 {"s", "name"}, {"s", "date"}, {"s", "disc"}, {"s", "genre"}, {"i", "song_pos"}, {"i", "songid"}), 0},
146 [EMPD_SIGNAL_QUEUE_LIST] = {"QueueList", ELDBUS_ARGS({"a(stusssisssii)", "array_of_songs"}), 0}, 149 [EMPD_SIGNAL_QUEUE_LIST] = {"QueueList", ELDBUS_ARGS({"a(stusssisssii)", "array_of_songs"}), 0},
150 [EMPD_SIGNAL_QUEUE_CHANGES_META] = {"QueueChangesMeta", ELDBUS_ARGS({"a(stusssisssii)", "array_of_songs"}), 0},
147 [EMPD_SIGNAL_DATABASE_UPDATE_BEGIN] = {"DatabaseUpdateBegin", NULL, 0}, 151 [EMPD_SIGNAL_DATABASE_UPDATE_BEGIN] = {"DatabaseUpdateBegin", NULL, 0},
148 [EMPD_SIGNAL_DATABASE_UPDATE_END] = {"DatabaseUpdateEnd", NULL, 0}, 152 [EMPD_SIGNAL_DATABASE_UPDATE_END] = {"DatabaseUpdateEnd", NULL, 0},
149 {NULL, NULL, 0} 153 {NULL, NULL, 0}
@@ -160,6 +164,7 @@ static Eldbus_Service_Interface *empd_iface = NULL;
160 164
161static Eina_Bool fetching_queue = EINA_FALSE; 165static Eina_Bool fetching_queue = EINA_FALSE;
162static unsigned int empd_queue_version = 0; 166static unsigned int empd_queue_version = 0;
167static unsigned int empd_queue_length = 0;
163static int empd_songid = -1; 168static int empd_songid = -1;
164static int empd_dbupdate = 0; 169static int empd_dbupdate = 0;
165 170
@@ -341,16 +346,13 @@ pinger_cb(void *d EINA_UNUSED)
341} 346}
342 347
343static void 348static void
344queue_list_send(Eldbus_Message *msg, unsigned int start, long num) 349queue_list_info_send(Eldbus_Message *msg, Eina_List *queue_list, unsigned int start, long num, Eina_Bool sig)
345{ 350{
346 Eldbus_Message_Iter *iter, *array, *struc; 351 Eldbus_Message_Iter *iter, *array, *struc;
347 Eina_List *l; 352 Eina_List *l;
348 struct mpd_song *so; 353 struct mpd_song *so;
349 unsigned int cur = 0; 354 unsigned int cur = 0;
350 Eina_Bool sig = !msg;
351 355
352 if (!msg)
353 msg = eldbus_service_signal_new(empd_iface, EMPD_SIGNAL_QUEUE_LIST);
354 iter = eldbus_message_iter_get(msg); 356 iter = eldbus_message_iter_get(msg);
355 array = eldbus_message_iter_container_new(iter, 'a', "(stusssisssii)"); 357 array = eldbus_message_iter_container_new(iter, 'a', "(stusssisssii)");
356 EINA_LIST_FOREACH(queue_list, l, so) 358 EINA_LIST_FOREACH(queue_list, l, so)
@@ -374,18 +376,14 @@ queue_list_send(Eldbus_Message *msg, unsigned int start, long num)
374 eldbus_service_signal_send(empd_iface, msg); 376 eldbus_service_signal_send(empd_iface, msg);
375} 377}
376 378
377static Eina_Bool 379static void
378queue_item_each_free(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED) 380queue_list_send(Eldbus_Message *msg, unsigned int start, long num)
379{ 381{
380 mpd_song_free(data); 382 Eina_Bool sig = !msg;
381 return EINA_TRUE;
382}
383 383
384static Eina_Bool 384 if (!msg)
385lsinfo_item_each_free(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED) 385 msg = eldbus_service_signal_new(empd_iface, EMPD_SIGNAL_QUEUE_LIST);
386{ 386 queue_list_info_send(msg, empd->current_queue, start, num, sig);
387 mpd_entity_free(data);
388 return EINA_TRUE;
389} 387}
390 388
391static Eina_Bool 389static Eina_Bool
@@ -488,7 +486,6 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
488 case MPD_IDLE_QUEUE: 486 case MPD_IDLE_QUEUE:
489 if (!empd->pinger) 487 if (!empd->pinger)
490 pinger_cb(NULL); 488 pinger_cb(NULL);
491 queue_fetch();
492 break; 489 break;
493 case MPD_IDLE_UPDATE: 490 case MPD_IDLE_UPDATE:
494 if (!empd_dbupdate) 491 if (!empd_dbupdate)
@@ -551,18 +548,30 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
551 mpd_status_get_total_time(st), mpd_status_get_elapsed_time(st), mpd_status_get_kbit_rate(st), 548 mpd_status_get_total_time(st), mpd_status_get_elapsed_time(st), mpd_status_get_kbit_rate(st),
552 af ? af->sample_rate : 0, af ? af->bits : 0, af ? af->channels : 0, 549 af ? af->sample_rate : 0, af ? af->bits : 0, af ? af->channels : 0,
553 mpd_status_get_next_song_pos(st), mpd_status_get_next_song_id(st), empd_dbupdate); 550 mpd_status_get_next_song_pos(st), mpd_status_get_next_song_id(st), empd_dbupdate);
554 if (((!empd->current_queue) && (!mpd_status_get_queue_length(st))) || 551 empd_queue_length = mpd_status_get_queue_length(st);
555 ((!empd_queue_version) && empd->current_queue && 552 /* if (no queue exists) */
556 (eina_list_count(empd->current_queue) == mpd_status_get_queue_length(st)))) 553 if ((!empd->current_queue) && (!empd_queue_length))
557 empd_queue_version = mpd_status_get_queue_version(st); 554 empd_queue_version = mpd_status_get_queue_version(st);
558 if ((empd_queue_version && (empd_queue_version != mpd_status_get_queue_version(st))) || 555 /* if (queue exists but has not been fetched) */
559 ((!empd->current_queue) && (mpd_status_get_queue_length(st))) || 556 else if ((!empd->current_queue) && (mpd_status_get_queue_length(st)))
560 (empd->current_queue && mpd_status_get_queue_length(st) &&
561 (eina_list_count(empd->current_queue) != mpd_status_get_queue_length(st))))
562 { 557 {
563 if (queue_fetch()) 558 queue_fetch();
564 empd_queue_version = mpd_status_get_queue_version(st); 559 empd_queue_version = mpd_status_get_queue_version(st);
565 } 560 }
561 else
562 {
563 unsigned int version = mpd_status_get_queue_version(st);
564 for (; empd_queue_version < version; empd_queue_version++)
565 {
566 char buf[64];
567
568 snprintf(buf, sizeof(buf), "%u", empd_queue_version);
569 cmd_append(EMPD_COMMAND_QUEUE_CHANGES_META);
570 mpd_async_send_command(empd->async, "plchanges", buf, NULL);
571 pinger_cb(NULL);
572 }
573 }
574 status_pending = EINA_FALSE;
566 switch (mpd_status_get_state(st)) 575 switch (mpd_status_get_state(st))
567 { 576 {
568 case MPD_STATE_PLAY: 577 case MPD_STATE_PLAY:
@@ -601,6 +610,7 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
601 } 610 }
602 case EMPD_COMMAND_CURRENT_SONG: 611 case EMPD_COMMAND_CURRENT_SONG:
603 case EMPD_COMMAND_QUEUE_LIST: 612 case EMPD_COMMAND_QUEUE_LIST:
613 case EMPD_COMMAND_QUEUE_CHANGES_META:
604 { 614 {
605 struct mpd_song *so; 615 struct mpd_song *so;
606 616
@@ -646,6 +656,35 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
646 mpd_song_get_pos(so), mpd_song_get_id(so)); 656 mpd_song_get_pos(so), mpd_song_get_id(so));
647 mpd_song_free(so); 657 mpd_song_free(so);
648 } 658 }
659 else if (cmd_get() == EMPD_COMMAND_QUEUE_CHANGES_META)
660 {
661 Eina_List *l, *ll;
662 Eldbus_Message *msg;
663
664 if (res != MPD_PARSER_SUCCESS)
665 break;
666
667 msg = eldbus_service_signal_new(empd_iface, EMPD_SIGNAL_QUEUE_CHANGES_META);
668 queue_list_info_send(msg, empd->pending, 0, -1, 1);
669 if (!empd->pending)
670 {
671 while (eina_list_count(empd->current_queue) > empd_queue_length)
672 {
673 mpd_song_free(eina_list_last_data_get(empd->current_queue));
674 empd->current_queue = eina_list_remove_list(empd->current_queue,
675 eina_list_last(empd->current_queue));
676 }
677 break;
678 }
679 so = eina_list_data_get(empd->pending);
680 EINA_LIST_FOREACH_SAFE(eina_list_nth_list(empd->current_queue, mpd_song_get_pos(so)), l, ll, so)
681 {
682 mpd_song_free(so);
683 empd->current_queue = eina_list_remove_list(empd->current_queue, l);
684 }
685 empd->current_queue = eina_list_merge(empd->current_queue, empd->pending);
686 empd->pending = NULL;
687 }
649 else if (cmd_get() == EMPD_COMMAND_QUEUE_LIST) 688 else if (cmd_get() == EMPD_COMMAND_QUEUE_LIST)
650 { 689 {
651 if (res != MPD_PARSER_SUCCESS) 690 if (res != MPD_PARSER_SUCCESS)
diff --git a/src/bin/empdd.xml b/src/bin/empdd.xml
index d638406..0a7c6a4 100644
--- a/src/bin/empdd.xml
+++ b/src/bin/empdd.xml
@@ -175,6 +175,9 @@
175 <signal name="QueueList"> 175 <signal name="QueueList">
176 <arg type="a(stusssisssii)" name="array_of_songs" direction="out" /> 176 <arg type="a(stusssisssii)" name="array_of_songs" direction="out" />
177 </signal> 177 </signal>
178 <signal name="QueueChangesMeta">
179 <arg type="a(stusssisssii)" name="array_of_songs" direction="out" />
180 </signal>
178 <signal name="LoginFailed"> 181 <signal name="LoginFailed">
179 <arg type="s" name="host" direction="out" /> 182 <arg type="s" name="host" direction="out" />
180 <arg type="u" name="port" direction="out" /> 183 <arg type="u" name="port" direction="out" />