Skip to content

User:Nesciens Sandbox On playlist updates

Erik Massop edited this page Nov 4, 2017 · 1 revision

Current updating of playlists

From playlist.c: (In xmms2-theefer jumplists are supported, but these are left out for simplicity and pose no additional difficulty)

/** * Go to next song in playlist according to current playlist mode. * xmms_playlist_current_entry is to be used to retrieve the entry. * * @sa xmms_playlist_current_entry * * @returns FALSE if end of playlist is reached, TRUE otherwise. */ gboolean xmms_playlist_advance (xmms_playlist_t *playlist) {     gint size, currpos;     gboolean ret = TRUE;     xmmsc_coll_t *plcoll;     g_return_val_if_fail (playlist, FALSE);     g_mutex_lock (playlist->mutex);     plcoll = xmms_playlist_get_coll (playlist, "_active", NULL);     if (plcoll == NULL) {         ret = FALSE;     } else if ((size = xmms_playlist_coll_get_size (plcoll)) == 0) {         ret = FALSE;     } else if (!playlist->repeat_one) {         currpos = xmms_playlist_coll_get_currpos (plcoll);         currpos++;         currpos %= size;         xmms_collection_set_int_attr (plcoll, "position", currpos);         ret = (currpos != 0) || playlist->repeat_all;         xmms_object_emit_f (XMMS_OBJECT (playlist),                             XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,                             XMMS_OBJECT_CMD_ARG_UINT32,                             currpos);     }     g_mutex_unlock (playlist->mutex);     return ret; } /**  * Initializes a new xmms_playlist_t.  */ xmms_playlist_t * xmms_playlist_init (void) { ...     xmms_object_connect (XMMS_OBJECT (ret),                          XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,                          on_playlist_updated_chg, ret);     xmms_object_connect (XMMS_OBJECT (ret),                          XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,                          on_playlist_updated_pos, ret); ... }

This is what happens in sequence when xmms_playlist_advance is called:

  1. set new position (0 is last song is played)
  2. set return value (FALSE if playlist ends, TRUE if not.)
  3. emit pos_changed
  4. stop or continue playback depending on return value (by caller of xmms_playlist_advance)
  5. update (connected to pos_changed)

Issues

Stopping after playing of last song in list

When the last song in the playlist is finished playing, playback is stopped, before any kind an update has occurred. The consequence of this is that playback is also stopped if a party shuffle could still provide a new song to be played. This thus disallows upcoming=1 for partshuffle playlists.

Setting position to 0 after playing of last song

When the last song in the playlist is finished playing, the position is set to 0, before an update has occurred. The updating function then has no clue if the last entry has finished playing and the history should be updated, or the user decided to jump to position 0 to play that media again.

Solutions

The solve above mentioned issues the following solutions are possible:

Solution 1

This solution is closest to the current implementation. Its disadvantage is that is does not use a signal to trigger updating, which means a certain knowledge of what function it should call is required. This solution is therefore less viable when (if) service clients are introduced.

  1. set new position (which can be just outside the playlist)

  2. if pos is outside playlist:

    1. update
  3. if pos still outside playlist:

    1. set pos to 0
  4. determine return value

  5. emit pos_changed

  6. playback stopped or continued depending on returned value (by caller of xmms_playlist_advance)

  7. update (connected to pos_changed)

Solution 2

This solution uses a new signal to trigger updates. I doubt if this signal is available, as the daemon has to block until something updated the playlist.

If it is implemented, however, the way to service clients is open. (Except you might need some mutexing mechanism (related to Collaborative Playlist Management esp. solution 1) or the signal should be send to different clients in sequence (instread of parallell); first try client 1. If that fails client 2, and so forth. A client might fail for instance when it is requested to update a different type of playlist than it was made for.)

  1. if playlist not up to date:

    1. block
  2. set new position (which can be right outside the playlist)

  3. if pos is outside playlist:

    1. emit update_playlist
    2. block
  4. if pos still outside playlist:

    1. set pos to 0
  5. determine return value

  6. emit pos_changed

  7. emit update_playlist (if not already done?) (Only blocking when not yet ready if this function is called again; first item of this sequence.)

  8. playback stopped or continued depending on returned value (by caller of xmms_playlist_advance)

  9. update (connected to update_playlist)

Solution 3

This solution is the simplest; just update if this function is called, no signals or whatever. Its disadvantage is again is does not use a signal to trigger updating, which means a certain knowledge of what function it should call is required. This solution is therefore less viable when (if) service clients are introduced.

Also there is always some lag when updating which is only there in the other solution when the list runs out of items to play.

  1. set new position (which can be right outside the playlist)

  2. update

  3. if pos outside playlist:

    1. set pos to 0
  4. determine return value

  5. emit pos_changed

  6. playback stopped or continued depending on returned value (by caller of xmms_playlist_advance)

See also

  • 1294

Nesciens 17:27, 9 December 2006 (CET)

Clone this wiki locally