diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-12-05 11:36:34 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-12-05 11:36:34 +1100 |
| commit | 4f5422e906b1d17720592d97bc0d5e82a71b1e5f (patch) | |
| tree | 4e8116510d57fb54c30fc18f1fe591a9aff4e3a0 /src/audio/include | |
| parent | 67f2f2de8393951d2eabac26f9afab2dc9388713 (diff) | |
| download | tangara-fw-4f5422e906b1d17720592d97bc0d5e82a71b1e5f.tar.gz | |
Rewrite the track queue to work directly with database iterators
Diffstat (limited to 'src/audio/include')
| -rw-r--r-- | src/audio/include/track_queue.hpp | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/src/audio/include/track_queue.hpp b/src/audio/include/track_queue.hpp index 0be2384a..9d5ef5b2 100644 --- a/src/audio/include/track_queue.hpp +++ b/src/audio/include/track_queue.hpp @@ -11,6 +11,7 @@ #include <mutex> #include <vector> +#include "database.hpp" #include "source.hpp" #include "track.hpp" @@ -27,67 +28,78 @@ namespace audio { * * Instances of this class are broadly safe to use from multiple tasks; each * method represents an atomic operation. No guarantees are made about - * consistency between calls however. For example, there may be data changes - * between consecutive calls to AddNext() and GetUpcoming(); + * consistency between calls however. */ class TrackQueue { public: TrackQueue(); + class Editor { + public: + ~Editor(); + + // Cannot be copied or moved. + Editor(const Editor&) = delete; + Editor& operator=(const Editor&) = delete; + + private: + friend TrackQueue; + + Editor(TrackQueue&); + + std::lock_guard<std::recursive_mutex> lock_; + bool has_current_changed_; + }; + + auto Edit() -> Editor; + /* Returns the currently playing track. */ - auto GetCurrent() const -> std::optional<database::TrackId>; + auto Current() const -> std::optional<database::TrackId>; + /* Returns, in order, tracks that have been queued to be played next. */ - auto GetUpcoming(std::size_t limit) const -> std::vector<database::TrackId>; + auto PeekNext(std::size_t limit) const -> std::vector<database::TrackId>; /* - * Enqueues a track, placing it immediately after the current track and - * before anything already queued. - * - * If there is no current track, the given track will begin playback. + * Returns the tracks in the queue that have already been played, ordered + * most recently played first. */ - auto AddNext(database::TrackId) -> void; - auto AddNext(std::shared_ptr<playlist::ISource>) -> void; + auto PeekPrevious(std::size_t limit) const -> std::vector<database::TrackId>; - auto IncludeNext(std::shared_ptr<playlist::IResetableSource>) -> void; + auto GetCurrentPosition() const -> size_t; + auto GetTotalSize() const -> size_t; - /* - * Enqueues a track, placing it the end of all enqueued tracks. - * - * If there is no current track, the given track will begin playback. - */ - auto AddLast(database::TrackId) -> void; - auto AddLast(std::shared_ptr<playlist::ISource>) -> void; - - auto IncludeLast(std::shared_ptr<playlist::IResetableSource>) -> void; + using Item = std::variant<database::TrackId, database::TrackIterator>; + auto Insert(Editor&, Item, size_t) -> void; + auto Append(Editor&, Item i) -> void; /* * Advances to the next track in the queue, placing the current track at the * front of the 'played' queue. */ - auto Next() -> void; - auto Previous() -> void; + auto Next(Editor&) -> std::optional<database::TrackId>; + auto Previous(Editor&) -> std::optional<database::TrackId>; + + auto SkipTo(Editor&, database::TrackId) -> void; /* * Removes all tracks from all queues, and stops any currently playing track. */ - auto Clear() -> void; - - auto Position() -> size_t; - auto Size() -> size_t; + auto Clear(Editor&) -> void; + // Cannot be copied or moved. TrackQueue(const TrackQueue&) = delete; TrackQueue& operator=(const TrackQueue&) = delete; private: - mutable std::mutex mutex_; - - std::list<std::variant<database::TrackId, - std::shared_ptr<playlist::IResetableSource>>> - played_; - std::list<std::variant<database::TrackId, - std::shared_ptr<playlist::ISource>, - std::shared_ptr<playlist::IResetableSource>>> - enqueued_; + // FIXME: Make this a shared_mutex so that multithread reads don't block. + mutable std::recursive_mutex mutex_; + + std::optional<database::TrackId> current_; + + // Note: stored in reverse order, i.e. most recent played it at the *back* of + // this vector. + std::pmr::vector<database::TrackId> played_; + std::pmr::vector<Item> enqueued_; }; } // namespace audio |
