From 57fa16d28909164e478c3bc8b46b557b6e84edf8 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 1 Apr 2014 20:11:57 -0400 Subject: [PATCH] queue: Update design for queues Signed-off-by: Anna Schumaker --- DESIGN | 285 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 142 insertions(+), 143 deletions(-) diff --git a/DESIGN b/DESIGN index 90cbb5bd..17ea7dbd 100644 --- a/DESIGN +++ b/DESIGN @@ -857,6 +857,148 @@ Track Tag: +Queue: + Queues are lists of songs that the user has requested to play. They + are the main interface for all music played by Ocarina. + +- Flags: + enum queue_flag { + Q_ENABLED (1 << 0), + Q_RANDOM (1 << 1), + Q_REPEAT (1 << 2), + Q_NO_SORT (1 << 3), + }; + +- Sort info: + struct sort_info { + sort_t field; + bool ascending; + }; + +- Sorting: + Sorting is done using std::stable_sort() to make sure that orders won't + change unexpectedly. The default sort order is (SORT_ARTIST, true), + (SORT_YEAR, true), (SORT_TRACK, true). + +- Queue: + class Queue { + private: + vector _tracks; + list _sort_order; + unsigned int _cur; + unsigned int _flags; + unsigned int _length; + + public: + Queue(unsigned int); + void read(File &); + void write(File &); + + void set_flag(queue_flag); + void unset_flag(queue_flag); + bool has_flag(queue_flag); + + unsigned int add(Track *); + void del(Track *); + void del(unsigned int); + void updated(Track *); + + unsigned int size(); + const std::string size_str(); + const std::string length_str(); + + void sort(sort_t, bool, bool); + + Track *next(); + void track_selected(unsigned int); + }; + +File Format: + File << flags << tracks.size() << tracks[0] << tracks[1] << ... << tracks[N]; + +- API + Queue :: Queue(unsigned int flags); + Initialize a new queue with the appropriate flags set and with + default sorting. + Set _length = 0, _cur = 0. + + void Queue :: read(File &f); + Read queue from file. + + void Queue :: write(File &f); + Write queue to file. + + void Queue :: set_flag(queue_flag f); + Set the appropriate flag. + + void Queue :: unset_flag(queue_flag f); + Unset the appropriate flag. + + bool Queue :: has_flag(queue_flag f); + Return true if the queue has the flag enabled and false + otherwise. + + unsigned int Queue :: add(Track *track); + Add a new track to the tracks vector and return the index. + Increase length by the length of the track. + + void Queue :: del(Track *track); + Remove all instances of the requested track from the queue. + + void Queue :: del(unsigned int queue_id); + Remove the track at the given index from the queue. + + void Queue :: updated(Track *track); + Find all indexes of the updated track and notify the UI that + it has changed. + + unsigned int Queue :: size(); + Return the number of tracks currently on the queue. + + const std::string Queue :: size_str(); + Return the number of tracks currently on the queue, in string + form. + + const std::string Queue :: length_str(); + Return the remaining length of the queue in a human-readable + format. + + void Queue :: sort(sort_t field, bool ascending, bool reset); + Add a new sort field to the end of the sort order, then + resort the queue. If reset is set to true, clear the sorting + list before appending. + + Track *Queue :: next(); + Return the next track to play. + + if (tracks.size() == 0) + return NULL; + + if (flags & PL_RANDOM): + _cur += rand() % tracks.size(); + else: + _cur += 1; + + if (_cur >= tracks.size()) + _cur -= tracks.size(); + track = tracks[_cur]; + + if (!(flags & PL_REPEAT)): + del(_cur); + return track; + + void Queue :: track_selected(unsigned int queue_id); + Set _cur to queue_id. If PQ_REPEAT is not set, remove the + track from the queue. + + + + + + + + + Library: (lib/library.cpp) The library manages databases containing track information added by the user. Ocarina 6 splits the library into multiple database tables for @@ -1002,149 +1144,6 @@ Playlists: (lib/playlist.cpp) -Playqueue: (lib/playqueue.cpp) - Playqueues are a list of songs that the user has requested to play. - -- Flags: - enum playqueue_flags { - PQ_ENABLED (1 << 0), - PQ_RANDOM (1 << 1), - PQ_REPEAT (1 << 2), - }; - -- Sort order: - enum sort_t { - SORT_ARTIST_ASC = 1, - SORT_ARTIST_DESC = 2, - SORT_ALBUM_ASC = 3, - SORT_ALBUM_DESC = 4, - SORT_COUNT_ASC = 5, - SORT_COUNT_DESC = 6, - SORT_GENRE_ASC = 7, - SORT_GENRE_DESC = 8, - SORT_LENGTH_ASC = 9, - SORT_LENGTH_DESC = 10, - SORT_PLAYED_ASC = 11, - SORT_PLAYED_DESC = 12, - SORT_TITLE_ASC = 13, - SORT_TITLE_DESC = 14, - SORT_TRACK_ASC = 15, - SORT_TRACK_DESC = 16, - SORT_YEAR_ASC = 17, - SORT_YEAR_DESC = 18, - }; - -- Playqueue: - class Playqueue { - private: - vector tracks; - list sort_order; /* default = { SORT_ARTIST_ASC, - SORT_YEAR_ASC, - SORT_TRACK_ASC }; - unsigned int cur; - unsigned int flags; - unsigned int length; - public: - Playqueue(flags); - void write(File &); - void read(File &); - - void set_flag(playqueue_flags); - void unset_flag(playqueue_flags); - const unsigned int get_flags(); - string get_length(); - - unsigned int add(track_id); - unsigned int add_front(track_id); - void del(playqueue_id); - unsigned int size(); - - void reset_sort(); - void add_sort(sort_t, bool); - void sort(); - - unsigned int next(); - void reset_cur(); - } - - File << flags << tracks.size() << tracks[0] << tracks[1] << ... << tracks[N]; - -- API - Playqueue :: Playlist(unsigned int flags); - Create a new playqueue with the appropriate flags set. - sort_order = { (SORT_ARTIST, true), (SORT_YEAR, true), - (SORT_TRACK, true) }; - - unsigned int Playqueue :: add(unsigned int track_id); - unsigned int Playqueue :: add_front(unsigned int track_id); - Add a new track to the tracks vector and return the index. If - add_front is called, the track will be added to the front of - the playqueue (index = 0). - length += track.length. - - void Playqueue :: del(unsigned int playqueue_id); - Erase tracks[playqueue_id] from the tracks vector. - length -= track.length. - - void Playqueue :: del_track(unsigned int track_id); - Erase all tracks with track id track_id. - - void Playqueue :: set_flag(playqueue_flags flag); - void Playqueue :: unset_flag(playqueue_flags flag); - Set or unset the given flag. - - const unsigned int Playqueue :: get_flags(); - Return the currently enabled flags. - - song Playqueue :: get_length(); - Convert the length variable into a string and return the result - to the caller. - - unsigned int Playqueue :: size(); - Return tracks.size(); - - void Playqueue :: write(File &); - void Playqueue :: read(File &); - Read or write the playqueue to the file. - - void Playqueue :: reset_sort(); - Reset the sort_order list to empty. - - void Playqueue :: add_sort(sort_t type, bool ascending); - Add a new term to the sort order. - - void Playqueue :: sort(); - Perform a stable sort on the entire playqueue. Compare tracks - based on the sort_order list. - - unsigned int Playqueue :: next(); - Return the next track_id to play. - - if (tracks.size() == 0) - throw -EEXIST; - - if (flags & PL_RANDOM): - cur += rand() % tracks.size(); - else: - cur += 1; - - if (cur > = tracks.size()) - cur -= tracks.size(); - track = tracks[cur]; - - if (!(flags & PL_REPEAT)): - length -= track.length; - tracks.erase(cur); - return track; - - void Playqueue :: reset_cur(); - This function is intended to be used by the audio layer when - managing the recently played playqueue. - - cur = 0; - - - Deck: (lib/deck.cpp) The playqueue deck is used to hold the temporary playqueues created by the user.