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
This commit is contained in:
parent
4db0a19dd3
commit
ba50156ec4
|
@ -77,6 +77,7 @@ typedef enum
|
|||
EMPD_COMMAND_UPDATE,
|
||||
EMPD_COMMAND_FIND,
|
||||
EMPD_COMMAND_IDLE,
|
||||
EMPD_COMMAND_QUEUE_CHANGES_META,
|
||||
} EMPD_Command;
|
||||
|
||||
static const char *cmd_txt[] =
|
||||
|
@ -113,6 +114,7 @@ static const char *cmd_txt[] =
|
|||
CMD_TXT(EMPD_COMMAND_UPDATE)
|
||||
CMD_TXT(EMPD_COMMAND_FIND)
|
||||
CMD_TXT(EMPD_COMMAND_IDLE)
|
||||
CMD_TXT(EMPD_COMMAND_QUEUE_CHANGES_META)
|
||||
};
|
||||
|
||||
typedef enum
|
||||
|
@ -124,6 +126,7 @@ typedef enum
|
|||
EMPD_SIGNAL_STATUS,
|
||||
EMPD_SIGNAL_CURRENT_SONG,
|
||||
EMPD_SIGNAL_QUEUE_LIST,
|
||||
EMPD_SIGNAL_QUEUE_CHANGES_META,
|
||||
EMPD_SIGNAL_DATABASE_UPDATE_BEGIN,
|
||||
EMPD_SIGNAL_DATABASE_UPDATE_END,
|
||||
} EMPD_Signals;
|
||||
|
@ -144,6 +147,7 @@ static const Eldbus_Signal empd_signals[] =
|
|||
{"s", "artist"}, {"s", "composer"}, {"s", "title"}, {"s", "album"}, {"i", "track"},
|
||||
{"s", "name"}, {"s", "date"}, {"s", "disc"}, {"s", "genre"}, {"i", "song_pos"}, {"i", "songid"}), 0},
|
||||
[EMPD_SIGNAL_QUEUE_LIST] = {"QueueList", ELDBUS_ARGS({"a(stusssisssii)", "array_of_songs"}), 0},
|
||||
[EMPD_SIGNAL_QUEUE_CHANGES_META] = {"QueueChangesMeta", ELDBUS_ARGS({"a(stusssisssii)", "array_of_songs"}), 0},
|
||||
[EMPD_SIGNAL_DATABASE_UPDATE_BEGIN] = {"DatabaseUpdateBegin", NULL, 0},
|
||||
[EMPD_SIGNAL_DATABASE_UPDATE_END] = {"DatabaseUpdateEnd", NULL, 0},
|
||||
{NULL, NULL, 0}
|
||||
|
@ -160,6 +164,7 @@ static Eldbus_Service_Interface *empd_iface = NULL;
|
|||
|
||||
static Eina_Bool fetching_queue = EINA_FALSE;
|
||||
static unsigned int empd_queue_version = 0;
|
||||
static unsigned int empd_queue_length = 0;
|
||||
static int empd_songid = -1;
|
||||
static int empd_dbupdate = 0;
|
||||
|
||||
|
@ -341,16 +346,13 @@ pinger_cb(void *d EINA_UNUSED)
|
|||
}
|
||||
|
||||
static void
|
||||
queue_list_send(Eldbus_Message *msg, unsigned int start, long num)
|
||||
queue_list_info_send(Eldbus_Message *msg, Eina_List *queue_list, unsigned int start, long num, Eina_Bool sig)
|
||||
{
|
||||
Eldbus_Message_Iter *iter, *array, *struc;
|
||||
Eina_List *l;
|
||||
struct mpd_song *so;
|
||||
unsigned int cur = 0;
|
||||
Eina_Bool sig = !msg;
|
||||
|
||||
if (!msg)
|
||||
msg = eldbus_service_signal_new(empd_iface, EMPD_SIGNAL_QUEUE_LIST);
|
||||
iter = eldbus_message_iter_get(msg);
|
||||
array = eldbus_message_iter_container_new(iter, 'a', "(stusssisssii)");
|
||||
EINA_LIST_FOREACH(queue_list, l, so)
|
||||
|
@ -374,18 +376,14 @@ queue_list_send(Eldbus_Message *msg, unsigned int start, long num)
|
|||
eldbus_service_signal_send(empd_iface, msg);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
queue_item_each_free(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
||||
static void
|
||||
queue_list_send(Eldbus_Message *msg, unsigned int start, long num)
|
||||
{
|
||||
mpd_song_free(data);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
Eina_Bool sig = !msg;
|
||||
|
||||
static Eina_Bool
|
||||
lsinfo_item_each_free(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
||||
{
|
||||
mpd_entity_free(data);
|
||||
return EINA_TRUE;
|
||||
if (!msg)
|
||||
msg = eldbus_service_signal_new(empd_iface, EMPD_SIGNAL_QUEUE_LIST);
|
||||
queue_list_info_send(msg, empd->current_queue, start, num, sig);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -488,7 +486,6 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
|
|||
case MPD_IDLE_QUEUE:
|
||||
if (!empd->pinger)
|
||||
pinger_cb(NULL);
|
||||
queue_fetch();
|
||||
break;
|
||||
case MPD_IDLE_UPDATE:
|
||||
if (!empd_dbupdate)
|
||||
|
@ -551,18 +548,30 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
|
|||
mpd_status_get_total_time(st), mpd_status_get_elapsed_time(st), mpd_status_get_kbit_rate(st),
|
||||
af ? af->sample_rate : 0, af ? af->bits : 0, af ? af->channels : 0,
|
||||
mpd_status_get_next_song_pos(st), mpd_status_get_next_song_id(st), empd_dbupdate);
|
||||
if (((!empd->current_queue) && (!mpd_status_get_queue_length(st))) ||
|
||||
((!empd_queue_version) && empd->current_queue &&
|
||||
(eina_list_count(empd->current_queue) == mpd_status_get_queue_length(st))))
|
||||
empd_queue_length = mpd_status_get_queue_length(st);
|
||||
/* if (no queue exists) */
|
||||
if ((!empd->current_queue) && (!empd_queue_length))
|
||||
empd_queue_version = mpd_status_get_queue_version(st);
|
||||
if ((empd_queue_version && (empd_queue_version != mpd_status_get_queue_version(st))) ||
|
||||
((!empd->current_queue) && (mpd_status_get_queue_length(st))) ||
|
||||
(empd->current_queue && mpd_status_get_queue_length(st) &&
|
||||
(eina_list_count(empd->current_queue) != mpd_status_get_queue_length(st))))
|
||||
/* if (queue exists but has not been fetched) */
|
||||
else if ((!empd->current_queue) && (mpd_status_get_queue_length(st)))
|
||||
{
|
||||
if (queue_fetch())
|
||||
empd_queue_version = mpd_status_get_queue_version(st);
|
||||
queue_fetch();
|
||||
empd_queue_version = mpd_status_get_queue_version(st);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int version = mpd_status_get_queue_version(st);
|
||||
for (; empd_queue_version < version; empd_queue_version++)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%u", empd_queue_version);
|
||||
cmd_append(EMPD_COMMAND_QUEUE_CHANGES_META);
|
||||
mpd_async_send_command(empd->async, "plchanges", buf, NULL);
|
||||
pinger_cb(NULL);
|
||||
}
|
||||
}
|
||||
status_pending = EINA_FALSE;
|
||||
switch (mpd_status_get_state(st))
|
||||
{
|
||||
case MPD_STATE_PLAY:
|
||||
|
@ -601,6 +610,7 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
|
|||
}
|
||||
case EMPD_COMMAND_CURRENT_SONG:
|
||||
case EMPD_COMMAND_QUEUE_LIST:
|
||||
case EMPD_COMMAND_QUEUE_CHANGES_META:
|
||||
{
|
||||
struct mpd_song *so;
|
||||
|
||||
|
@ -646,6 +656,35 @@ fdh_func(void *d EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
|
|||
mpd_song_get_pos(so), mpd_song_get_id(so));
|
||||
mpd_song_free(so);
|
||||
}
|
||||
else if (cmd_get() == EMPD_COMMAND_QUEUE_CHANGES_META)
|
||||
{
|
||||
Eina_List *l, *ll;
|
||||
Eldbus_Message *msg;
|
||||
|
||||
if (res != MPD_PARSER_SUCCESS)
|
||||
break;
|
||||
|
||||
msg = eldbus_service_signal_new(empd_iface, EMPD_SIGNAL_QUEUE_CHANGES_META);
|
||||
queue_list_info_send(msg, empd->pending, 0, -1, 1);
|
||||
if (!empd->pending)
|
||||
{
|
||||
while (eina_list_count(empd->current_queue) > empd_queue_length)
|
||||
{
|
||||
mpd_song_free(eina_list_last_data_get(empd->current_queue));
|
||||
empd->current_queue = eina_list_remove_list(empd->current_queue,
|
||||
eina_list_last(empd->current_queue));
|
||||
}
|
||||
break;
|
||||
}
|
||||
so = eina_list_data_get(empd->pending);
|
||||
EINA_LIST_FOREACH_SAFE(eina_list_nth_list(empd->current_queue, mpd_song_get_pos(so)), l, ll, so)
|
||||
{
|
||||
mpd_song_free(so);
|
||||
empd->current_queue = eina_list_remove_list(empd->current_queue, l);
|
||||
}
|
||||
empd->current_queue = eina_list_merge(empd->current_queue, empd->pending);
|
||||
empd->pending = NULL;
|
||||
}
|
||||
else if (cmd_get() == EMPD_COMMAND_QUEUE_LIST)
|
||||
{
|
||||
if (res != MPD_PARSER_SUCCESS)
|
||||
|
|
|
@ -175,6 +175,9 @@
|
|||
<signal name="QueueList">
|
||||
<arg type="a(stusssisssii)" name="array_of_songs" direction="out" />
|
||||
</signal>
|
||||
<signal name="QueueChangesMeta">
|
||||
<arg type="a(stusssisssii)" name="array_of_songs" direction="out" />
|
||||
</signal>
|
||||
<signal name="LoginFailed">
|
||||
<arg type="s" name="host" direction="out" />
|
||||
<arg type="u" name="port" direction="out" />
|
||||
|
|
Loading…
Reference in New Issue