summaryrefslogtreecommitdiff
path: root/src/audio/include/track_queue.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/include/track_queue.hpp')
-rw-r--r--src/audio/include/track_queue.hpp82
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