From 7197da21f6bcc1aaa5d1905228e0e2ec1caf3fa8 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 17 Jul 2023 16:54:35 +1000 Subject: Basic playlists for upcoming Beware under-testing and bugs. Just getting something barebones in so that I can do rN+1 bringup --- src/playlist/include/source.hpp | 105 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/playlist/include/source.hpp (limited to 'src/playlist/include/source.hpp') 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 + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include +#include +#include +#include +#include + +#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 = 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 = 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*) + -> 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 = 0; + + /* + * Restarts iteration from this source's initial value. + */ + virtual auto Reset() -> void = 0; +}; + +class IndexRecordSource : public IResetableSource { + public: + IndexRecordSource(std::weak_ptr db, + std::shared_ptr>); + + IndexRecordSource(std::weak_ptr db, + std::shared_ptr>, + std::size_t, + std::shared_ptr>, + std::size_t); + + auto Current() -> std::optional override; + auto Advance() -> std::optional override; + auto Peek(std::size_t n, std::vector*) + -> std::size_t override; + + auto Previous() -> std::optional override; + auto Reset() -> void override; + + private: + std::weak_ptr db_; + + std::shared_ptr> initial_page_; + ssize_t initial_item_; + + std::shared_ptr> current_page_; + ssize_t current_item_; +}; + +} // namespace playlist -- cgit v1.2.3