diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-07-17 16:54:35 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-07-17 16:54:35 +1000 |
| commit | 7197da21f6bcc1aaa5d1905228e0e2ec1caf3fa8 (patch) | |
| tree | f24f81cba08160d45d7e994dc31f48506e823e49 /src/playlist/include/source.hpp | |
| parent | b6bc6b9e47605ede9bffe50445d1afe3acf0ab49 (diff) | |
| download | tangara-fw-7197da21f6bcc1aaa5d1905228e0e2ec1caf3fa8.tar.gz | |
Basic playlists for upcoming
Beware under-testing and bugs. Just getting something barebones in so
that I can do rN+1 bringup
Diffstat (limited to 'src/playlist/include/source.hpp')
| -rw-r--r-- | src/playlist/include/source.hpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/playlist/include/source.hpp b/src/playlist/include/source.hpp new file mode 100644 index 00000000..069c1e93 --- /dev/null +++ b/src/playlist/include/source.hpp @@ -0,0 +1,105 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <deque> +#include <memory> +#include <mutex> +#include <variant> +#include <vector> + +#include "bloom_filter.hpp" +#include "database.hpp" +#include "future_fetcher.hpp" +#include "random.hpp" +#include "track.hpp" + +namespace playlist { + +/* + * Stateful interface for iterating over a collection of tracks by id. + */ +class ISource { + public: + virtual ~ISource() {} + + virtual auto Current() -> std::optional<database::TrackId> = 0; + + /* + * Discards the current track id and continues to the next in this source. + * Returns the new current track id. + */ + virtual auto Advance() -> std::optional<database::TrackId> = 0; + + /* + * Repeatedly advances until a track with the given id is the current track. + * Returns false if this source ran out of tracks before the requested id + * was encounted, true otherwise. + */ + virtual auto AdvanceTo(database::TrackId id) -> bool { + for (auto t = Current(); t.has_value(); t = Advance()) { + if (*t == id) { + return true; + } + } + return false; + } + + /* + * Places the next n tracks into the given vector, in order. Does not change + * the value returned by Current(). + */ + virtual auto Peek(std::size_t n, std::vector<database::TrackId>*) + -> std::size_t = 0; +}; + +/* + * A Source that supports restarting iteration from its original initial + * value. + */ +class IResetableSource : public ISource { + public: + virtual ~IResetableSource() {} + + virtual auto Previous() -> std::optional<database::TrackId> = 0; + + /* + * Restarts iteration from this source's initial value. + */ + virtual auto Reset() -> void = 0; +}; + +class IndexRecordSource : public IResetableSource { + public: + IndexRecordSource(std::weak_ptr<database::Database> db, + std::shared_ptr<database::Result<database::IndexRecord>>); + + IndexRecordSource(std::weak_ptr<database::Database> db, + std::shared_ptr<database::Result<database::IndexRecord>>, + std::size_t, + std::shared_ptr<database::Result<database::IndexRecord>>, + std::size_t); + + auto Current() -> std::optional<database::TrackId> override; + auto Advance() -> std::optional<database::TrackId> override; + auto Peek(std::size_t n, std::vector<database::TrackId>*) + -> std::size_t override; + + auto Previous() -> std::optional<database::TrackId> override; + auto Reset() -> void override; + + private: + std::weak_ptr<database::Database> db_; + + std::shared_ptr<database::Result<database::IndexRecord>> initial_page_; + ssize_t initial_item_; + + std::shared_ptr<database::Result<database::IndexRecord>> current_page_; + ssize_t current_item_; +}; + +} // namespace playlist |
