std::string -> std::pmr::string in psram
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include "freertos/FreeRTOSConfig_arch.h"
|
||||
#include "freertos/projdefs.h"
|
||||
#include "index.hpp"
|
||||
#include "memory_resource.hpp"
|
||||
#include "service_locator.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
@@ -49,7 +50,7 @@ int CmdListDir(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
std::pmr::string path;
|
||||
if (argc > 1) {
|
||||
std::ostringstream builder;
|
||||
builder << argv[1];
|
||||
@@ -102,13 +103,13 @@ void RegisterListDir() {
|
||||
}
|
||||
|
||||
int CmdPlayFile(int argc, char** argv) {
|
||||
static const std::string usage = "usage: play [file or id]";
|
||||
static const std::pmr::string usage = "usage: play [file or id]";
|
||||
if (argc < 2) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string path_or_id = argv[1];
|
||||
std::pmr::string path_or_id = argv[1];
|
||||
bool is_id = true;
|
||||
for (const auto& it : path_or_id) {
|
||||
if (!std::isdigit(it)) {
|
||||
@@ -121,13 +122,15 @@ int CmdPlayFile(int argc, char** argv) {
|
||||
database::TrackId id = std::atoi(argv[1]);
|
||||
AppConsole::sServices->track_queue().AddLast(id);
|
||||
} else {
|
||||
std::ostringstream path;
|
||||
path << '/' << argv[1];
|
||||
std::pmr::string path{&memory::kSpiRamResource};
|
||||
path += '/';
|
||||
path += argv[1];
|
||||
for (int i = 2; i < argc; i++) {
|
||||
path << ' ' << argv[i];
|
||||
path += ' ';
|
||||
path += argv[i];
|
||||
}
|
||||
|
||||
events::Audio().Dispatch(audio::PlayFile{.filename = path.str()});
|
||||
events::Audio().Dispatch(audio::PlayFile{.filename = path});
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -143,7 +146,7 @@ void RegisterPlayFile() {
|
||||
}
|
||||
|
||||
int CmdDbInit(int argc, char** argv) {
|
||||
static const std::string usage = "usage: db_init";
|
||||
static const std::pmr::string usage = "usage: db_init";
|
||||
if (argc != 1) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -170,7 +173,7 @@ void RegisterDbInit() {
|
||||
}
|
||||
|
||||
int CmdDbTracks(int argc, char** argv) {
|
||||
static const std::string usage = "usage: db_tracks";
|
||||
static const std::pmr::string usage = "usage: db_tracks";
|
||||
if (argc != 1) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -211,7 +214,7 @@ void RegisterDbTracks() {
|
||||
int CmdDbIndex(int argc, char** argv) {
|
||||
std::cout << std::endl;
|
||||
vTaskDelay(1);
|
||||
static const std::string usage = "usage: db_index [id] [choices ...]";
|
||||
static const std::pmr::string usage = "usage: db_index [id] [choices ...]";
|
||||
|
||||
auto db = AppConsole::sServices->database().lock();
|
||||
if (!db) {
|
||||
@@ -292,7 +295,7 @@ void RegisterDbIndex() {
|
||||
}
|
||||
|
||||
int CmdDbDump(int argc, char** argv) {
|
||||
static const std::string usage = "usage: db_dump";
|
||||
static const std::pmr::string usage = "usage: db_dump";
|
||||
if (argc != 1) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -306,14 +309,14 @@ int CmdDbDump(int argc, char** argv) {
|
||||
|
||||
std::cout << "=== BEGIN DUMP ===" << std::endl;
|
||||
|
||||
std::unique_ptr<database::Result<std::string>> res(db->GetDump(5).get());
|
||||
std::unique_ptr<database::Result<std::pmr::string>> res(db->GetDump(5).get());
|
||||
while (true) {
|
||||
for (std::string s : res->values()) {
|
||||
for (const std::pmr::string& s : res->values()) {
|
||||
std::cout << s << std::endl;
|
||||
}
|
||||
if (res->next_page()) {
|
||||
auto continuation = res->next_page().value();
|
||||
res.reset(db->GetPage<std::string>(&continuation).get());
|
||||
res.reset(db->GetPage<std::pmr::string>(&continuation).get());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -340,7 +343,7 @@ int CmdTasks(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const std::string usage = "usage: tasks";
|
||||
static const std::pmr::string usage = "usage: tasks";
|
||||
if (argc != 1) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -362,7 +365,7 @@ int CmdTasks(int argc, char** argv) {
|
||||
size_t end_num_tasks =
|
||||
uxTaskGetSystemState(end_status, num_tasks, &end_elapsed_ticks);
|
||||
|
||||
std::vector<std::pair<uint32_t, std::string>> info_strings;
|
||||
std::vector<std::pair<uint32_t, std::pmr::string>> info_strings;
|
||||
for (int i = 0; i < start_num_tasks; i++) {
|
||||
int k = -1;
|
||||
for (int j = 0; j < end_num_tasks; j++) {
|
||||
@@ -383,7 +386,7 @@ int CmdTasks(int argc, char** argv) {
|
||||
auto depth = uxTaskGetStackHighWaterMark2(start_status[i].xHandle);
|
||||
float depth_kib = static_cast<float>(depth) / 1024.0f;
|
||||
|
||||
std::ostringstream str;
|
||||
std::ostringstream str{};
|
||||
str << start_status[i].pcTaskName;
|
||||
if (str.str().size() < 8) {
|
||||
str << "\t\t";
|
||||
@@ -410,7 +413,7 @@ int CmdTasks(int argc, char** argv) {
|
||||
str << std::fixed << std::setprecision(1) << (time_percent * 100);
|
||||
str << "%";
|
||||
|
||||
info_strings.push_back({run_time, str.str()});
|
||||
info_strings.push_back({run_time, std::pmr::string{str.str()}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +447,7 @@ void RegisterTasks() {
|
||||
}
|
||||
|
||||
int CmdHeaps(int argc, char** argv) {
|
||||
static const std::string usage = "usage: heaps";
|
||||
static const std::pmr::string usage = "usage: heaps";
|
||||
if (argc != 1) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -484,7 +487,7 @@ static heap_trace_record_t* sTraceRecords = nullptr;
|
||||
static bool sIsTracking = false;
|
||||
|
||||
int CmdAllocs(int argc, char** argv) {
|
||||
static const std::string usage = "usage: allocs";
|
||||
static const std::pmr::string usage = "usage: allocs";
|
||||
if (argc != 1) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -521,7 +524,7 @@ void RegisterAllocs() {
|
||||
#endif
|
||||
|
||||
int CmdBtList(int argc, char** argv) {
|
||||
static const std::string usage = "usage: bt_list <index>";
|
||||
static const std::pmr::string usage = "usage: bt_list <index>";
|
||||
if (argc > 2) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
@@ -563,13 +566,13 @@ void RegisterBtList() {
|
||||
}
|
||||
|
||||
int CmdSamd(int argc, char** argv) {
|
||||
static const std::string usage = "usage: samd [flash|charge|off]";
|
||||
static const std::pmr::string usage = "usage: samd [flash|charge|off]";
|
||||
if (argc != 2) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string cmd{argv[1]};
|
||||
std::pmr::string cmd{argv[1]};
|
||||
if (cmd == "flash") {
|
||||
std::cout << "resetting samd..." << std::endl;
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
|
||||
@@ -52,16 +52,17 @@ FatfsAudioInput::~FatfsAudioInput() {
|
||||
vSemaphoreDelete(has_new_stream_);
|
||||
}
|
||||
|
||||
auto FatfsAudioInput::SetPath(std::future<std::optional<std::string>> fut)
|
||||
auto FatfsAudioInput::SetPath(std::future<std::optional<std::pmr::string>> fut)
|
||||
-> void {
|
||||
std::lock_guard<std::mutex> guard{new_stream_mutex_};
|
||||
pending_path_.reset(
|
||||
new database::FutureFetcher<std::optional<std::string>>(std::move(fut)));
|
||||
new database::FutureFetcher<std::optional<std::pmr::string>>(
|
||||
std::move(fut)));
|
||||
|
||||
xSemaphoreGive(has_new_stream_);
|
||||
}
|
||||
|
||||
auto FatfsAudioInput::SetPath(const std::string& path) -> void {
|
||||
auto FatfsAudioInput::SetPath(const std::pmr::string& path) -> void {
|
||||
std::lock_guard<std::mutex> guard{new_stream_mutex_};
|
||||
if (OpenFile(path)) {
|
||||
xSemaphoreGive(has_new_stream_);
|
||||
@@ -114,7 +115,7 @@ auto FatfsAudioInput::NextStream() -> std::shared_ptr<codecs::IStream> {
|
||||
}
|
||||
}
|
||||
|
||||
auto FatfsAudioInput::OpenFile(const std::string& path) -> bool {
|
||||
auto FatfsAudioInput::OpenFile(const std::pmr::string& path) -> bool {
|
||||
ESP_LOGI(kTag, "opening file %s", path.c_str());
|
||||
|
||||
database::TrackTags tags;
|
||||
|
||||
@@ -31,7 +31,7 @@ struct QueueUpdate : tinyfsm::Event {
|
||||
};
|
||||
|
||||
struct PlayFile : tinyfsm::Event {
|
||||
std::string filename;
|
||||
std::pmr::string filename;
|
||||
};
|
||||
|
||||
struct VolumeChanged : tinyfsm::Event {};
|
||||
|
||||
@@ -37,8 +37,8 @@ class FatfsAudioInput : public IAudioSource {
|
||||
* Immediately cease reading any current source, and begin reading from the
|
||||
* given file path.
|
||||
*/
|
||||
auto SetPath(std::future<std::optional<std::string>>) -> void;
|
||||
auto SetPath(const std::string&) -> void;
|
||||
auto SetPath(std::future<std::optional<std::pmr::string>>) -> void;
|
||||
auto SetPath(const std::pmr::string&) -> void;
|
||||
auto SetPath() -> void;
|
||||
|
||||
auto HasNewStream() -> bool override;
|
||||
@@ -48,7 +48,7 @@ class FatfsAudioInput : public IAudioSource {
|
||||
FatfsAudioInput& operator=(const FatfsAudioInput&) = delete;
|
||||
|
||||
private:
|
||||
auto OpenFile(const std::string& path) -> bool;
|
||||
auto OpenFile(const std::pmr::string& path) -> bool;
|
||||
|
||||
auto ContainerToStreamType(database::Container)
|
||||
-> std::optional<codecs::StreamType>;
|
||||
@@ -60,7 +60,7 @@ class FatfsAudioInput : public IAudioSource {
|
||||
|
||||
SemaphoreHandle_t has_new_stream_;
|
||||
|
||||
std::unique_ptr<database::FutureFetcher<std::optional<std::string>>>
|
||||
std::unique_ptr<database::FutureFetcher<std::optional<std::pmr::string>>>
|
||||
pending_path_;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ idf_component_register(
|
||||
SRCS "codec.cpp" "mad.cpp" "foxenflac.cpp" "opus.cpp" "vorbis.cpp"
|
||||
"source_buffer.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES "result" "span" "libmad" "libfoxenflac" "tremor" "opusfile")
|
||||
REQUIRES "result" "span" "libmad" "libfoxenflac" "tremor" "opusfile" "memory")
|
||||
|
||||
target_compile_options("${COMPONENT_LIB}" PRIVATE ${EXTRA_WARNINGS})
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "span.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace codecs {
|
||||
|
||||
/*
|
||||
@@ -69,7 +71,7 @@ class ICodec {
|
||||
kInternalError,
|
||||
};
|
||||
|
||||
static auto ErrorString(Error err) -> std::string {
|
||||
static auto ErrorString(Error err) -> std::pmr::string {
|
||||
switch (err) {
|
||||
case Error::kOutOfInput:
|
||||
return "out of input";
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> input)
|
||||
opus_ = op_open_callbacks(input.get(), &kCallbacks, nullptr, 0, &res);
|
||||
|
||||
if (res < 0) {
|
||||
std::string err;
|
||||
std::pmr::string err;
|
||||
switch (res) {
|
||||
case OP_EREAD:
|
||||
err = "OP_EREAD";
|
||||
|
||||
@@ -88,7 +88,7 @@ auto TremorVorbisDecoder::OpenStream(std::shared_ptr<IStream> input)
|
||||
-> cpp::result<OutputFormat, Error> {
|
||||
int res = ov_open_callbacks(input.get(), &vorbis_, NULL, 0, kCallbacks);
|
||||
if (res < 0) {
|
||||
std::string err;
|
||||
std::pmr::string err;
|
||||
switch (res) {
|
||||
case OV_EREAD:
|
||||
err = "OV_EREAD";
|
||||
|
||||
@@ -7,7 +7,7 @@ idf_component_register(
|
||||
"file_gatherer.cpp" "tag_parser.cpp" "index.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES "result" "span" "esp_psram" "fatfs" "libtags" "komihash" "cbor"
|
||||
"tasks" "shared_string" "util" "tinyfsm" "events" "opusfile")
|
||||
"tasks" "memory" "util" "tinyfsm" "events" "opusfile")
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})
|
||||
|
||||
|
||||
+34
-30
@@ -31,6 +31,7 @@
|
||||
#include "env_esp.hpp"
|
||||
#include "event_queue.hpp"
|
||||
#include "file_gatherer.hpp"
|
||||
#include "memory_resource.hpp"
|
||||
#include "records.hpp"
|
||||
#include "result.hpp"
|
||||
#include "tag_parser.hpp"
|
||||
@@ -195,7 +196,7 @@ auto Database::Update() -> std::future<void> {
|
||||
events::Ui().Dispatch(event::UpdateProgress{
|
||||
.stage = event::UpdateProgress::Stage::kScanningForNewTracks,
|
||||
});
|
||||
file_gatherer_.FindFiles("", [&](const std::string& path) {
|
||||
file_gatherer_.FindFiles("", [&](const std::pmr::string& path) {
|
||||
TrackTags tags;
|
||||
if (!tag_parser_.ReadAndParseTags(path, &tags) ||
|
||||
tags.encoding() == Container::kUnsupported) {
|
||||
@@ -252,9 +253,9 @@ auto Database::Update() -> std::future<void> {
|
||||
}
|
||||
|
||||
auto Database::GetTrackPath(TrackId id)
|
||||
-> std::future<std::optional<std::string>> {
|
||||
return worker_task_->Dispatch<std::optional<std::string>>(
|
||||
[=, this]() -> std::optional<std::string> {
|
||||
-> std::future<std::optional<std::pmr::string>> {
|
||||
return worker_task_->Dispatch<std::optional<std::pmr::string>>(
|
||||
[=, this]() -> std::optional<std::pmr::string> {
|
||||
auto track_data = dbGetTrackData(id);
|
||||
if (track_data) {
|
||||
return track_data->filepath();
|
||||
@@ -362,10 +363,10 @@ auto Database::GetTracks(std::size_t page_size) -> std::future<Result<Track>*> {
|
||||
}
|
||||
|
||||
auto Database::GetDump(std::size_t page_size)
|
||||
-> std::future<Result<std::string>*> {
|
||||
return worker_task_->Dispatch<Result<std::string>*>(
|
||||
[=, this]() -> Result<std::string>* {
|
||||
Continuation<std::string> c{.prefix = "",
|
||||
-> std::future<Result<std::pmr::string>*> {
|
||||
return worker_task_->Dispatch<Result<std::pmr::string>*>(
|
||||
[=, this]() -> Result<std::pmr::string>* {
|
||||
Continuation<std::pmr::string> c{.prefix = "",
|
||||
.start_key = "",
|
||||
.forward = true,
|
||||
.was_prev_forward = true,
|
||||
@@ -385,8 +386,9 @@ template auto Database::GetPage<Track>(Continuation<Track>* c)
|
||||
-> std::future<Result<Track>*>;
|
||||
template auto Database::GetPage<IndexRecord>(Continuation<IndexRecord>* c)
|
||||
-> std::future<Result<IndexRecord>*>;
|
||||
template auto Database::GetPage<std::string>(Continuation<std::string>* c)
|
||||
-> std::future<Result<std::string>*>;
|
||||
template auto Database::GetPage<std::pmr::string>(
|
||||
Continuation<std::pmr::string>* c)
|
||||
-> std::future<Result<std::pmr::string>*>;
|
||||
|
||||
auto Database::dbMintNewTrackId() -> TrackId {
|
||||
TrackId next_id = 1;
|
||||
@@ -466,7 +468,7 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
|
||||
// Work out our starting point. Sometimes this will already done.
|
||||
std::unique_ptr<leveldb::Iterator> it{
|
||||
db_->NewIterator(leveldb::ReadOptions{})};
|
||||
it->Seek(c.start_key);
|
||||
it->Seek({c.start_key.data(), c.start_key.size()});
|
||||
|
||||
// Fix off-by-one if we just changed direction.
|
||||
if (c.forward != c.was_prev_forward) {
|
||||
@@ -478,10 +480,10 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
|
||||
}
|
||||
|
||||
// Grab results.
|
||||
std::optional<std::string> first_key;
|
||||
std::optional<std::pmr::string> first_key;
|
||||
std::vector<T> records;
|
||||
while (records.size() < c.page_size && it->Valid()) {
|
||||
if (!it->key().starts_with(c.prefix)) {
|
||||
if (!it->key().starts_with({c.prefix.data(), c.prefix.size()})) {
|
||||
break;
|
||||
}
|
||||
if (!first_key) {
|
||||
@@ -498,7 +500,8 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
|
||||
}
|
||||
}
|
||||
|
||||
if (!it->Valid() || !it->key().starts_with(c.prefix)) {
|
||||
if (!it->Valid() ||
|
||||
!it->key().starts_with({c.prefix.data(), c.prefix.size()})) {
|
||||
it.reset();
|
||||
}
|
||||
|
||||
@@ -512,7 +515,8 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
|
||||
if (c.forward) {
|
||||
if (it != nullptr) {
|
||||
// We were going forward, and now we want the next page.
|
||||
std::string key = it->key().ToString();
|
||||
std::pmr::string key{it->key().data(), it->key().size(),
|
||||
&memory::kSpiRamResource};
|
||||
next_page = Continuation<T>{
|
||||
.prefix = c.prefix,
|
||||
.start_key = key,
|
||||
@@ -549,7 +553,8 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
|
||||
} else {
|
||||
if (it != nullptr) {
|
||||
// We were going backwards, and we still want to go backwards.
|
||||
std::string key = it->key().ToString();
|
||||
std::pmr::string key{it->key().data(), it->key().size(),
|
||||
&memory::kSpiRamResource};
|
||||
prev_page = Continuation<T>{
|
||||
.prefix = c.prefix,
|
||||
.start_key = key,
|
||||
@@ -566,8 +571,8 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
|
||||
|
||||
template auto Database::dbGetPage<Track>(const Continuation<Track>& c)
|
||||
-> Result<Track>*;
|
||||
template auto Database::dbGetPage<std::string>(
|
||||
const Continuation<std::string>& c) -> Result<std::string>*;
|
||||
template auto Database::dbGetPage<std::pmr::string>(
|
||||
const Continuation<std::pmr::string>& c) -> Result<std::pmr::string>*;
|
||||
|
||||
template <>
|
||||
auto Database::ParseRecord<IndexRecord>(const leveldb::Slice& key,
|
||||
@@ -578,7 +583,7 @@ auto Database::ParseRecord<IndexRecord>(const leveldb::Slice& key,
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> title;
|
||||
std::optional<std::pmr::string> title;
|
||||
if (!val.empty()) {
|
||||
title = val.ToString();
|
||||
}
|
||||
@@ -602,43 +607,42 @@ auto Database::ParseRecord<Track>(const leveldb::Slice& key,
|
||||
}
|
||||
|
||||
template <>
|
||||
auto Database::ParseRecord<std::string>(const leveldb::Slice& key,
|
||||
auto Database::ParseRecord<std::pmr::string>(const leveldb::Slice& key,
|
||||
const leveldb::Slice& val)
|
||||
-> std::optional<std::string> {
|
||||
-> std::optional<std::pmr::string> {
|
||||
std::ostringstream stream;
|
||||
stream << "key: ";
|
||||
if (key.size() < 3 || key.data()[1] != '\0') {
|
||||
stream << key.ToString().c_str();
|
||||
} else {
|
||||
std::string str = key.ToString();
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
for (size_t i = 0; i < key.size(); i++) {
|
||||
if (i == 0) {
|
||||
stream << str[i];
|
||||
stream << key.data()[i];
|
||||
} else if (i == 1) {
|
||||
stream << " / 0x";
|
||||
} else {
|
||||
stream << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<int>(str[i]);
|
||||
<< static_cast<int>(key.data()[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!val.empty()) {
|
||||
stream << "\tval: 0x";
|
||||
std::string str = val.ToString();
|
||||
for (int i = 0; i < val.size(); i++) {
|
||||
stream << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<int>(str[i]);
|
||||
<< static_cast<int>(val.data()[i]);
|
||||
}
|
||||
}
|
||||
return stream.str();
|
||||
std::pmr::string res{stream.str(), &memory::kSpiRamResource};
|
||||
return res;
|
||||
}
|
||||
|
||||
IndexRecord::IndexRecord(const IndexKey& key,
|
||||
std::optional<shared_string> title,
|
||||
std::optional<std::pmr::string> title,
|
||||
std::optional<TrackId> track)
|
||||
: key_(key), override_text_(title), track_(track) {}
|
||||
|
||||
auto IndexRecord::text() const -> std::optional<shared_string> {
|
||||
auto IndexRecord::text() const -> std::optional<std::pmr::string> {
|
||||
if (override_text_) {
|
||||
return override_text_;
|
||||
}
|
||||
|
||||
@@ -13,18 +13,20 @@
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
static_assert(sizeof(TCHAR) == sizeof(char), "TCHAR must be CHAR");
|
||||
|
||||
auto FileGathererImpl::FindFiles(const std::string& root,
|
||||
std::function<void(const std::string&)> cb)
|
||||
-> void {
|
||||
std::deque<std::string> to_explore;
|
||||
auto FileGathererImpl::FindFiles(
|
||||
const std::pmr::string& root,
|
||||
std::function<void(const std::pmr::string&)> cb) -> void {
|
||||
std::pmr::deque<std::pmr::string> to_explore(&memory::kSpiRamResource);
|
||||
to_explore.push_back(root);
|
||||
|
||||
while (!to_explore.empty()) {
|
||||
std::string next_path_str = to_explore.front();
|
||||
std::pmr::string next_path_str = to_explore.front();
|
||||
const TCHAR* next_path = static_cast<const TCHAR*>(next_path_str.c_str());
|
||||
|
||||
FF_DIR dir;
|
||||
@@ -44,16 +46,18 @@ auto FileGathererImpl::FindFiles(const std::string& root,
|
||||
// System or hidden file. Ignore it and move on.
|
||||
continue;
|
||||
} else {
|
||||
std::stringstream full_path;
|
||||
full_path << next_path_str << "/" << info.fname;
|
||||
std::pmr::string full_path{&memory::kSpiRamResource};
|
||||
full_path += next_path_str;
|
||||
full_path += "/";
|
||||
full_path += info.fname;
|
||||
|
||||
if (info.fattrib & AM_DIR) {
|
||||
// This is a directory. Add it to the explore queue.
|
||||
to_explore.push_back(full_path.str());
|
||||
to_explore.push_back(full_path);
|
||||
} else {
|
||||
// This is a file! Let the callback know about it.
|
||||
// std::invoke(cb, full_path.str(), info);
|
||||
std::invoke(cb, full_path.str());
|
||||
std::invoke(cb, full_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include "leveldb/iterator.h"
|
||||
#include "leveldb/options.h"
|
||||
#include "leveldb/slice.h"
|
||||
#include "memory_resource.hpp"
|
||||
#include "records.hpp"
|
||||
#include "result.hpp"
|
||||
#include "shared_string.h"
|
||||
#include "tag_parser.hpp"
|
||||
#include "tasks.hpp"
|
||||
#include "track.hpp"
|
||||
@@ -33,8 +33,8 @@ namespace database {
|
||||
|
||||
template <typename T>
|
||||
struct Continuation {
|
||||
std::string prefix;
|
||||
std::string start_key;
|
||||
std::pmr::string prefix;
|
||||
std::pmr::string start_key;
|
||||
bool forward;
|
||||
bool was_prev_forward;
|
||||
size_t page_size;
|
||||
@@ -70,17 +70,17 @@ class Result {
|
||||
class IndexRecord {
|
||||
public:
|
||||
explicit IndexRecord(const IndexKey&,
|
||||
std::optional<shared_string>,
|
||||
std::optional<std::pmr::string>,
|
||||
std::optional<TrackId>);
|
||||
|
||||
auto text() const -> std::optional<shared_string>;
|
||||
auto text() const -> std::optional<std::pmr::string>;
|
||||
auto track() const -> std::optional<TrackId>;
|
||||
|
||||
auto Expand(std::size_t) const -> std::optional<Continuation<IndexRecord>>;
|
||||
|
||||
private:
|
||||
IndexKey key_;
|
||||
std::optional<shared_string> override_text_;
|
||||
std::optional<std::pmr::string> override_text_;
|
||||
std::optional<TrackId> track_;
|
||||
};
|
||||
|
||||
@@ -100,7 +100,7 @@ class Database {
|
||||
|
||||
auto Update() -> std::future<void>;
|
||||
|
||||
auto GetTrackPath(TrackId id) -> std::future<std::optional<std::string>>;
|
||||
auto GetTrackPath(TrackId id) -> std::future<std::optional<std::pmr::string>>;
|
||||
|
||||
auto GetTrack(TrackId id) -> std::future<std::optional<Track>>;
|
||||
|
||||
@@ -115,7 +115,7 @@ class Database {
|
||||
auto GetTracksByIndex(const IndexInfo& index, std::size_t page_size)
|
||||
-> std::future<Result<IndexRecord>*>;
|
||||
auto GetTracks(std::size_t page_size) -> std::future<Result<Track>*>;
|
||||
auto GetDump(std::size_t page_size) -> std::future<Result<std::string>*>;
|
||||
auto GetDump(std::size_t page_size) -> std::future<Result<std::pmr::string>*>;
|
||||
|
||||
template <typename T>
|
||||
auto GetPage(Continuation<T>* c) -> std::future<Result<T>*>;
|
||||
@@ -167,8 +167,8 @@ auto Database::ParseRecord<Track>(const leveldb::Slice& key,
|
||||
const leveldb::Slice& val)
|
||||
-> std::optional<Track>;
|
||||
template <>
|
||||
auto Database::ParseRecord<std::string>(const leveldb::Slice& key,
|
||||
auto Database::ParseRecord<std::pmr::string>(const leveldb::Slice& key,
|
||||
const leveldb::Slice& val)
|
||||
-> std::optional<std::string>;
|
||||
-> std::optional<std::pmr::string>;
|
||||
|
||||
} // namespace database
|
||||
|
||||
@@ -19,15 +19,15 @@ class IFileGatherer {
|
||||
public:
|
||||
virtual ~IFileGatherer(){};
|
||||
|
||||
virtual auto FindFiles(const std::string& root,
|
||||
std::function<void(const std::string&)> cb)
|
||||
virtual auto FindFiles(const std::pmr::string& root,
|
||||
std::function<void(const std::pmr::string&)> cb)
|
||||
-> void = 0;
|
||||
};
|
||||
|
||||
class FileGathererImpl : public IFileGatherer {
|
||||
public:
|
||||
virtual auto FindFiles(const std::string& root,
|
||||
std::function<void(const std::string&)> cb)
|
||||
virtual auto FindFiles(const std::pmr::string& root,
|
||||
std::function<void(const std::pmr::string&)> cb)
|
||||
-> void override;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "leveldb/slice.h"
|
||||
|
||||
#include "leveldb/write_batch.h"
|
||||
#include "shared_string.h"
|
||||
#include "memory_resource.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
namespace database {
|
||||
@@ -29,7 +29,7 @@ struct IndexInfo {
|
||||
IndexId id;
|
||||
// Localised, user-friendly description of this index. e.g. "Albums by Artist"
|
||||
// or "All Tracks".
|
||||
std::string name;
|
||||
std::pmr::string name;
|
||||
// Specifier for how this index breaks down the database.
|
||||
std::vector<Tag> components;
|
||||
};
|
||||
@@ -51,7 +51,7 @@ struct IndexKey {
|
||||
|
||||
// The filterable / selectable item that this key represents. "Jacqueline" for
|
||||
// kArtist, "My Cool Album" for kAlbum, etc.
|
||||
std::optional<std::string> item;
|
||||
std::optional<std::pmr::string> item;
|
||||
// If this is a leaf component, the track id for this record.
|
||||
// This could reasonably be the value for a record, but we keep it as a part
|
||||
// of the key to help with disambiguation.
|
||||
@@ -59,8 +59,8 @@ struct IndexKey {
|
||||
};
|
||||
|
||||
auto Index(const IndexInfo&, const Track&, leveldb::WriteBatch*) -> bool;
|
||||
auto ExpandHeader(const IndexKey::Header&, const std::optional<std::string>&)
|
||||
-> IndexKey::Header;
|
||||
auto ExpandHeader(const IndexKey::Header&,
|
||||
const std::optional<std::pmr::string>&) -> IndexKey::Header;
|
||||
|
||||
// Predefined indexes
|
||||
// TODO(jacqueline): Make these defined at runtime! :)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "leveldb/slice.h"
|
||||
|
||||
#include "index.hpp"
|
||||
#include "shared_string.h"
|
||||
#include "memory_resource.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
namespace database {
|
||||
@@ -28,10 +28,10 @@ namespace database {
|
||||
*/
|
||||
class OwningSlice {
|
||||
public:
|
||||
std::string data;
|
||||
std::pmr::string data;
|
||||
leveldb::Slice slice;
|
||||
|
||||
explicit OwningSlice(std::string d);
|
||||
explicit OwningSlice(std::pmr::string d);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -88,6 +88,6 @@ auto TrackIdToBytes(TrackId id) -> OwningSlice;
|
||||
* Converts a track id encoded via TrackIdToBytes back into a TrackId. May
|
||||
* return nullopt if parsing fails.
|
||||
*/
|
||||
auto BytesToTrackId(const std::string& bytes) -> std::optional<TrackId>;
|
||||
auto BytesToTrackId(cpp::span<const char> bytes) -> std::optional<TrackId>;
|
||||
|
||||
} // namespace database
|
||||
|
||||
@@ -16,24 +16,24 @@ namespace database {
|
||||
class ITagParser {
|
||||
public:
|
||||
virtual ~ITagParser() {}
|
||||
virtual auto ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
virtual auto ReadAndParseTags(const std::pmr::string& path, TrackTags* out)
|
||||
-> bool = 0;
|
||||
};
|
||||
|
||||
class GenericTagParser : public ITagParser {
|
||||
public:
|
||||
auto ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
auto ReadAndParseTags(const std::pmr::string& path, TrackTags* out)
|
||||
-> bool override;
|
||||
};
|
||||
|
||||
class TagParserImpl : public ITagParser {
|
||||
public:
|
||||
TagParserImpl();
|
||||
auto ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
auto ReadAndParseTags(const std::pmr::string& path, TrackTags* out)
|
||||
-> bool override;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::unique_ptr<ITagParser>> extension_to_parser_;
|
||||
std::map<std::pmr::string, std::unique_ptr<ITagParser>> extension_to_parser_;
|
||||
GenericTagParser generic_parser_;
|
||||
|
||||
/*
|
||||
@@ -41,16 +41,16 @@ class TagParserImpl : public ITagParser {
|
||||
* cache should be slightly larger than any page sizes in the UI.
|
||||
*/
|
||||
std::mutex cache_mutex_;
|
||||
util::LruCache<16, std::string, TrackTags> cache_;
|
||||
util::LruCache<16, std::pmr::string, TrackTags> cache_;
|
||||
|
||||
// We could also consider keeping caches of artist name -> shared_string and
|
||||
// similar. This hasn't been done yet, as this isn't a common workload in any
|
||||
// of our UI.
|
||||
// We could also consider keeping caches of artist name -> std::pmr::string
|
||||
// and similar. This hasn't been done yet, as this isn't a common workload in
|
||||
// any of our UI.
|
||||
};
|
||||
|
||||
class OpusTagParser : public ITagParser {
|
||||
public:
|
||||
auto ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
auto ReadAndParseTags(const std::pmr::string& path, TrackTags* out)
|
||||
-> bool override;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "leveldb/db.h"
|
||||
#include "shared_string.h"
|
||||
#include "memory_resource.hpp"
|
||||
#include "span.hpp"
|
||||
|
||||
namespace database {
|
||||
@@ -64,7 +64,8 @@ class TrackTags {
|
||||
auto encoding() const -> Container { return encoding_; };
|
||||
auto encoding(Container e) -> void { encoding_ = e; };
|
||||
|
||||
TrackTags() : encoding_(Container::kUnsupported) {}
|
||||
TrackTags()
|
||||
: encoding_(Container::kUnsupported), tags_(&memory::kSpiRamResource) {}
|
||||
|
||||
std::optional<int> channels;
|
||||
std::optional<int> sample_rate;
|
||||
@@ -72,9 +73,9 @@ class TrackTags {
|
||||
|
||||
std::optional<int> duration;
|
||||
|
||||
auto set(const Tag& key, const std::string& val) -> void;
|
||||
auto at(const Tag& key) const -> std::optional<shared_string>;
|
||||
auto operator[](const Tag& key) const -> std::optional<shared_string>;
|
||||
auto set(const Tag& key, const std::pmr::string& val) -> void;
|
||||
auto at(const Tag& key) const -> std::optional<std::pmr::string>;
|
||||
auto operator[](const Tag& key) const -> std::optional<std::pmr::string>;
|
||||
|
||||
/*
|
||||
* Returns a hash of the 'identifying' tags of this track. That is, a hash
|
||||
@@ -90,7 +91,7 @@ class TrackTags {
|
||||
|
||||
private:
|
||||
Container encoding_;
|
||||
std::unordered_map<Tag, shared_string> tags_;
|
||||
std::pmr::unordered_map<Tag, std::pmr::string> tags_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -113,33 +114,33 @@ class TrackTags {
|
||||
class TrackData {
|
||||
private:
|
||||
const TrackId id_;
|
||||
const std::string filepath_;
|
||||
const std::pmr::string filepath_;
|
||||
const uint64_t tags_hash_;
|
||||
const uint32_t play_count_;
|
||||
const bool is_tombstoned_;
|
||||
|
||||
public:
|
||||
/* Constructor used when adding new tracks to the database. */
|
||||
TrackData(TrackId id, const std::string& path, uint64_t hash)
|
||||
TrackData(TrackId id, const std::pmr::string& path, uint64_t hash)
|
||||
: id_(id),
|
||||
filepath_(path),
|
||||
filepath_(path, &memory::kSpiRamResource),
|
||||
tags_hash_(hash),
|
||||
play_count_(0),
|
||||
is_tombstoned_(false) {}
|
||||
|
||||
TrackData(TrackId id,
|
||||
const std::string& path,
|
||||
const std::pmr::string& path,
|
||||
uint64_t hash,
|
||||
uint32_t play_count,
|
||||
bool is_tombstoned)
|
||||
: id_(id),
|
||||
filepath_(path),
|
||||
filepath_(path, &memory::kSpiRamResource),
|
||||
tags_hash_(hash),
|
||||
play_count_(play_count),
|
||||
is_tombstoned_(is_tombstoned) {}
|
||||
|
||||
auto id() const -> TrackId { return id_; }
|
||||
auto filepath() const -> std::string { return filepath_; }
|
||||
auto filepath() const -> std::pmr::string { return filepath_; }
|
||||
auto play_count() const -> uint32_t { return play_count_; }
|
||||
auto tags_hash() const -> uint64_t { return tags_hash_; }
|
||||
auto is_tombstoned() const -> bool { return is_tombstoned_; }
|
||||
@@ -156,7 +157,7 @@ class TrackData {
|
||||
* Clears the tombstone bit of this track, and updates the path to reflect its
|
||||
* new location.
|
||||
*/
|
||||
auto Exhume(const std::string& new_path) const -> TrackData;
|
||||
auto Exhume(const std::pmr::string& new_path) const -> TrackData;
|
||||
|
||||
bool operator==(const TrackData&) const = default;
|
||||
};
|
||||
@@ -178,7 +179,7 @@ class Track {
|
||||
auto data() const -> const TrackData& { return data_; }
|
||||
auto tags() const -> const TrackTags& { return tags_; }
|
||||
|
||||
auto TitleOrFilename() const -> shared_string;
|
||||
auto TitleOrFilename() const -> std::pmr::string;
|
||||
|
||||
bool operator==(const Track&) const = default;
|
||||
Track operator=(const Track& other) const { return Track(other); }
|
||||
|
||||
@@ -41,7 +41,7 @@ const IndexInfo kAllAlbums{
|
||||
};
|
||||
|
||||
static auto missing_component_text(const Track& track, Tag tag)
|
||||
-> std::optional<std::string> {
|
||||
-> std::optional<std::pmr::string> {
|
||||
switch (tag) {
|
||||
case Tag::kArtist:
|
||||
return "Unknown Artist";
|
||||
@@ -76,9 +76,9 @@ auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch)
|
||||
for (std::uint8_t i = 0; i < info.components.size(); i++) {
|
||||
// Fill in the text for this depth.
|
||||
auto text = t.tags().at(info.components.at(i));
|
||||
std::string value;
|
||||
std::pmr::string value;
|
||||
if (text) {
|
||||
std::string orig = *text;
|
||||
std::pmr::string orig = *text;
|
||||
key.item = col.transform(&orig[0], &orig[0] + orig.size());
|
||||
value = *text;
|
||||
} else {
|
||||
@@ -94,7 +94,7 @@ auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch)
|
||||
}
|
||||
|
||||
auto encoded = EncodeIndexKey(key);
|
||||
batch->Put(encoded.slice, value);
|
||||
batch->Put(encoded.slice, {value.data(), value.size()});
|
||||
|
||||
// If there are more components after this, then we need to finish by
|
||||
// narrowing the header with the current title.
|
||||
@@ -106,7 +106,7 @@ auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch)
|
||||
}
|
||||
|
||||
auto ExpandHeader(const IndexKey::Header& header,
|
||||
const std::optional<std::string>& component)
|
||||
const std::optional<std::pmr::string>& component)
|
||||
-> IndexKey::Header {
|
||||
IndexKey::Header ret{header};
|
||||
ret.depth++;
|
||||
|
||||
+22
-14
@@ -8,7 +8,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <memory_resource>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -18,7 +20,7 @@
|
||||
|
||||
#include "index.hpp"
|
||||
#include "komihash.h"
|
||||
#include "shared_string.h"
|
||||
#include "memory_resource.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
// As LevelDB is a key-value store, each record in the database consists of a
|
||||
@@ -47,6 +49,11 @@ static const char kHashPrefix = 'H';
|
||||
static const char kIndexPrefix = 'I';
|
||||
static const char kFieldSeparator = '\0';
|
||||
|
||||
using ostringstream =
|
||||
std::basic_ostringstream<char,
|
||||
std::char_traits<char>,
|
||||
std::pmr::polymorphic_allocator<char>>;
|
||||
|
||||
/*
|
||||
* Helper function for allocating an appropriately-sized byte buffer, then
|
||||
* encoding data into it.
|
||||
@@ -78,7 +85,8 @@ auto cbor_encode(uint8_t** out_buf, T fn) -> std::size_t {
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
OwningSlice::OwningSlice(std::string d) : data(d), slice(data) {}
|
||||
OwningSlice::OwningSlice(std::pmr::string d)
|
||||
: data(d), slice(data.data(), data.size()) {}
|
||||
|
||||
/* 'D/' */
|
||||
auto EncodeDataPrefix() -> OwningSlice {
|
||||
@@ -88,7 +96,7 @@ auto EncodeDataPrefix() -> OwningSlice {
|
||||
|
||||
/* 'D/ 0xACAB' */
|
||||
auto EncodeDataKey(const TrackId& id) -> OwningSlice {
|
||||
std::ostringstream output;
|
||||
ostringstream output;
|
||||
output.put(kDataPrefix).put(kFieldSeparator);
|
||||
output << TrackIdToBytes(id).data;
|
||||
return OwningSlice(output.str());
|
||||
@@ -136,7 +144,7 @@ auto EncodeDataValue(const TrackData& track) -> OwningSlice {
|
||||
return;
|
||||
}
|
||||
});
|
||||
std::string as_str(reinterpret_cast<char*>(buf), buf_len);
|
||||
std::pmr::string as_str(reinterpret_cast<char*>(buf), buf_len);
|
||||
delete buf;
|
||||
return OwningSlice(as_str);
|
||||
}
|
||||
@@ -174,7 +182,7 @@ auto ParseDataValue(const leveldb::Slice& slice) -> std::optional<TrackData> {
|
||||
if (err != CborNoError || !cbor_value_is_unsigned_integer(&val)) {
|
||||
return {};
|
||||
}
|
||||
std::string path(raw_path, len);
|
||||
std::pmr::string path(raw_path, len);
|
||||
delete raw_path;
|
||||
|
||||
err = cbor_value_get_uint64(&val, &raw_int);
|
||||
@@ -208,7 +216,7 @@ auto ParseDataValue(const leveldb::Slice& slice) -> std::optional<TrackData> {
|
||||
|
||||
/* 'H/ 0xBEEF' */
|
||||
auto EncodeHashKey(const uint64_t& hash) -> OwningSlice {
|
||||
std::ostringstream output;
|
||||
ostringstream output;
|
||||
output.put(kHashPrefix).put(kFieldSeparator);
|
||||
|
||||
uint8_t buf[16];
|
||||
@@ -222,7 +230,7 @@ auto EncodeHashKey(const uint64_t& hash) -> OwningSlice {
|
||||
}
|
||||
|
||||
auto ParseHashValue(const leveldb::Slice& slice) -> std::optional<TrackId> {
|
||||
return BytesToTrackId(slice.ToString());
|
||||
return BytesToTrackId({slice.data(), slice.size()});
|
||||
}
|
||||
|
||||
auto EncodeHashValue(TrackId id) -> OwningSlice {
|
||||
@@ -235,7 +243,7 @@ auto EncodeAllIndexesPrefix() -> OwningSlice {
|
||||
return OwningSlice({data, 2});
|
||||
}
|
||||
|
||||
auto AppendIndexHeader(const IndexKey::Header& header, std::ostringstream* out)
|
||||
auto AppendIndexHeader(const IndexKey::Header& header, ostringstream* out)
|
||||
-> void {
|
||||
*out << kIndexPrefix << kFieldSeparator;
|
||||
|
||||
@@ -270,13 +278,13 @@ auto AppendIndexHeader(const IndexKey::Header& header, std::ostringstream* out)
|
||||
return;
|
||||
}
|
||||
});
|
||||
std::string encoded{reinterpret_cast<char*>(buf), buf_len};
|
||||
std::pmr::string encoded{reinterpret_cast<char*>(buf), buf_len};
|
||||
delete buf;
|
||||
*out << encoded << kFieldSeparator;
|
||||
}
|
||||
|
||||
auto EncodeIndexPrefix(const IndexKey::Header& header) -> OwningSlice {
|
||||
std::ostringstream out;
|
||||
ostringstream out;
|
||||
AppendIndexHeader(header, &out);
|
||||
return OwningSlice(out.str());
|
||||
}
|
||||
@@ -296,7 +304,7 @@ auto EncodeIndexPrefix(const IndexKey::Header& header) -> OwningSlice {
|
||||
* id for now, but could reasonably be something like 'release year' as well.
|
||||
*/
|
||||
auto EncodeIndexKey(const IndexKey& key) -> OwningSlice {
|
||||
std::ostringstream out;
|
||||
ostringstream out;
|
||||
|
||||
// Construct the header.
|
||||
AppendIndexHeader(key.header, &out);
|
||||
@@ -319,7 +327,7 @@ auto ParseIndexKey(const leveldb::Slice& slice) -> std::optional<IndexKey> {
|
||||
IndexKey result{};
|
||||
|
||||
auto prefix = EncodeAllIndexesPrefix();
|
||||
if (!slice.starts_with(prefix.data)) {
|
||||
if (!slice.starts_with(prefix.slice)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -409,11 +417,11 @@ auto TrackIdToBytes(TrackId id) -> OwningSlice {
|
||||
cbor_encoder_init(&enc, buf, sizeof(buf), 0);
|
||||
cbor_encode_uint(&enc, id);
|
||||
std::size_t len = cbor_encoder_get_buffer_size(&enc, buf);
|
||||
std::string as_str(reinterpret_cast<char*>(buf), len);
|
||||
std::pmr::string as_str(reinterpret_cast<char*>(buf), len);
|
||||
return OwningSlice(as_str);
|
||||
}
|
||||
|
||||
auto BytesToTrackId(const std::string& bytes) -> std::optional<TrackId> {
|
||||
auto BytesToTrackId(cpp::span<const char> bytes) -> std::optional<TrackId> {
|
||||
CborParser parser;
|
||||
CborValue val;
|
||||
cbor_parser_init(reinterpret_cast<const uint8_t*>(bytes.data()), bytes.size(),
|
||||
|
||||
+21
-17
@@ -6,14 +6,17 @@
|
||||
|
||||
#include "tag_parser.hpp"
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <ff.h>
|
||||
#include <stdint.h>
|
||||
#include <tags.h>
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include <mutex>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "ff.h"
|
||||
#include "opusfile.h"
|
||||
#include "tags.h"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
@@ -25,13 +28,14 @@ const static std::array<std::pair<const char*, Tag>, 5> kVorbisIdToTag = {{
|
||||
{"GENRE", Tag::kGenre},
|
||||
}};
|
||||
|
||||
static auto convert_track_number(int number) -> std::string {
|
||||
static auto convert_track_number(int number) -> std::pmr::string {
|
||||
std::ostringstream oss;
|
||||
oss << std::setw(4) << std::setfill('0') << number;
|
||||
return oss.str();
|
||||
return std::pmr::string(oss.str());
|
||||
}
|
||||
|
||||
static auto convert_track_number(const std::string& raw) -> std::string {
|
||||
static auto convert_track_number(const std::pmr::string& raw)
|
||||
-> std::pmr::string {
|
||||
uint32_t as_int = std::atoi(raw.c_str());
|
||||
return convert_track_number(as_int);
|
||||
}
|
||||
@@ -106,7 +110,7 @@ static void tag(Tagctx* ctx,
|
||||
if (!tag) {
|
||||
return;
|
||||
}
|
||||
std::string value{v};
|
||||
std::pmr::string value{v, &memory::kSpiRamResource};
|
||||
if (value.empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -126,8 +130,8 @@ TagParserImpl::TagParserImpl() {
|
||||
extension_to_parser_["opus"] = std::make_unique<OpusTagParser>();
|
||||
}
|
||||
|
||||
auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
-> bool {
|
||||
auto TagParserImpl::ReadAndParseTags(const std::pmr::string& path,
|
||||
TrackTags* out) -> bool {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{cache_mutex_};
|
||||
std::optional<TrackTags> cached = cache_.Get(path);
|
||||
@@ -139,8 +143,8 @@ auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
|
||||
ITagParser* parser = &generic_parser_;
|
||||
auto dot_pos = path.find_last_of(".");
|
||||
if (dot_pos != std::string::npos && path.size() - dot_pos > 1) {
|
||||
std::string extension = path.substr(dot_pos + 1);
|
||||
if (dot_pos != std::pmr::string::npos && path.size() - dot_pos > 1) {
|
||||
std::pmr::string extension = path.substr(dot_pos + 1);
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
if (extension_to_parser_.contains(extension)) {
|
||||
@@ -157,7 +161,7 @@ auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
// start.
|
||||
if (!out->at(Tag::kAlbumTrack)) {
|
||||
auto slash_pos = path.find_last_of("/");
|
||||
if (slash_pos != std::string::npos && path.size() - slash_pos > 1) {
|
||||
if (slash_pos != std::pmr::string::npos && path.size() - slash_pos > 1) {
|
||||
out->set(Tag::kAlbumTrack, path.substr(slash_pos + 1));
|
||||
}
|
||||
}
|
||||
@@ -175,8 +179,8 @@ auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto GenericTagParser::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
-> bool {
|
||||
auto GenericTagParser::ReadAndParseTags(const std::pmr::string& path,
|
||||
TrackTags* out) -> bool {
|
||||
libtags::Aux aux;
|
||||
aux.tags = out;
|
||||
if (f_stat(path.c_str(), &aux.info) != FR_OK ||
|
||||
@@ -239,9 +243,9 @@ auto GenericTagParser::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto OpusTagParser::ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
-> bool {
|
||||
std::string vfs_path = "/sdcard" + path;
|
||||
auto OpusTagParser::ReadAndParseTags(const std::pmr::string& path,
|
||||
TrackTags* out) -> bool {
|
||||
std::pmr::string vfs_path = "/sdcard" + path;
|
||||
int err;
|
||||
OggOpusFile* f = op_test_file(vfs_path.c_str(), &err);
|
||||
if (f == NULL) {
|
||||
|
||||
@@ -26,23 +26,25 @@ namespace database {
|
||||
|
||||
class TestBackends : public IFileGatherer, public ITagParser {
|
||||
public:
|
||||
std::map<std::string, TrackTags> tracks;
|
||||
std::map<std::pmr::string, TrackTags> tracks;
|
||||
|
||||
auto MakeTrack(const std::string& path, const std::string& title) -> void {
|
||||
auto MakeTrack(const std::pmr::string& path, const std::pmr::string& title)
|
||||
-> void {
|
||||
TrackTags tags;
|
||||
tags.encoding = Encoding::kMp3;
|
||||
tags.title = title;
|
||||
tracks[path] = tags;
|
||||
}
|
||||
|
||||
auto FindFiles(const std::string& root,
|
||||
std::function<void(const std::string&)> cb) -> void override {
|
||||
auto FindFiles(const std::pmr::string& root,
|
||||
std::function<void(const std::pmr::string&)> cb)
|
||||
-> void override {
|
||||
for (auto keyval : tracks) {
|
||||
std::invoke(cb, keyval.first);
|
||||
}
|
||||
}
|
||||
|
||||
auto ReadAndParseTags(const std::string& path, TrackTags* out)
|
||||
auto ReadAndParseTags(const std::pmr::string& path, TrackTags* out)
|
||||
-> bool override {
|
||||
if (tracks.contains(path)) {
|
||||
*out = tracks.at(path);
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
std::string ToHex(const std::string& s) {
|
||||
std::pmr::string ToHex(const std::pmr::string& s) {
|
||||
std::ostringstream ret;
|
||||
|
||||
for (std::string::size_type i = 0; i < s.length(); ++i)
|
||||
for (std::pmr::string::size_type i = 0; i < s.length(); ++i)
|
||||
ret << std::hex << std::setfill('0') << std::setw(2) << std::uppercase
|
||||
<< (int)s[i];
|
||||
|
||||
|
||||
+11
-9
@@ -7,15 +7,16 @@
|
||||
#include "track.hpp"
|
||||
|
||||
#include <komihash.h>
|
||||
#include "shared_string.h"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
auto TrackTags::set(const Tag& key, const std::string& val) -> void {
|
||||
auto TrackTags::set(const Tag& key, const std::pmr::string& val) -> void {
|
||||
tags_[key] = val;
|
||||
}
|
||||
|
||||
auto TrackTags::at(const Tag& key) const -> std::optional<shared_string> {
|
||||
auto TrackTags::at(const Tag& key) const -> std::optional<std::pmr::string> {
|
||||
if (tags_.contains(key)) {
|
||||
return tags_.at(key);
|
||||
}
|
||||
@@ -23,12 +24,13 @@ auto TrackTags::at(const Tag& key) const -> std::optional<shared_string> {
|
||||
}
|
||||
|
||||
auto TrackTags::operator[](const Tag& key) const
|
||||
-> std::optional<shared_string> {
|
||||
-> std::optional<std::pmr::string> {
|
||||
return at(key);
|
||||
}
|
||||
|
||||
/* Helper function to update a komihash stream with a std::string. */
|
||||
auto HashString(komihash_stream_t* stream, const std::string& str) -> void {
|
||||
/* Helper function to update a komihash stream with a std::pmr::string. */
|
||||
auto HashString(komihash_stream_t* stream, const std::pmr::string& str)
|
||||
-> void {
|
||||
komihash_stream_update(stream, str.c_str(), str.length());
|
||||
}
|
||||
|
||||
@@ -58,7 +60,7 @@ auto TrackData::Entomb() const -> TrackData {
|
||||
return TrackData(id_, filepath_, tags_hash_, play_count_, true);
|
||||
}
|
||||
|
||||
auto TrackData::Exhume(const std::string& new_path) const -> TrackData {
|
||||
auto TrackData::Exhume(const std::pmr::string& new_path) const -> TrackData {
|
||||
return TrackData(id_, new_path, tags_hash_, play_count_, false);
|
||||
}
|
||||
|
||||
@@ -68,13 +70,13 @@ void swap(Track& first, Track& second) {
|
||||
second = temp;
|
||||
}
|
||||
|
||||
auto Track::TitleOrFilename() const -> shared_string {
|
||||
auto Track::TitleOrFilename() const -> std::pmr::string {
|
||||
auto title = tags().at(Tag::kTitle);
|
||||
if (title) {
|
||||
return *title;
|
||||
}
|
||||
auto start = data().filepath().find_last_of('/');
|
||||
if (start == std::string::npos) {
|
||||
if (start == std::pmr::string::npos) {
|
||||
return data().filepath();
|
||||
}
|
||||
return data().filepath().substr(start);
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
idf_component_register(
|
||||
SRCS "console.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES "console")
|
||||
REQUIRES "console" "memory")
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})
|
||||
|
||||
@@ -16,16 +16,18 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace console {
|
||||
|
||||
int CmdLogLevel(int argc, char** argv) {
|
||||
static const std::string usage =
|
||||
static const std::pmr::string usage =
|
||||
"usage: loglevel [VERBOSE,DEBUG,INFO,WARN,ERROR,NONE]";
|
||||
if (argc != 2) {
|
||||
std::cout << usage << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::string level_str = argv[1];
|
||||
std::pmr::string level_str = argv[1];
|
||||
std::transform(level_str.begin(), level_str.end(), level_str.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); });
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "bluetooth_types.hpp"
|
||||
#include "esp_a2dp_api.h"
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_types.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "memory_resource.hpp"
|
||||
#include "nvs.hpp"
|
||||
#include "tinyfsm/include/tinyfsm.hpp"
|
||||
|
||||
@@ -108,13 +110,13 @@ auto Bluetooth::SetEventHandler(std::function<void(bluetooth::Event)> cb)
|
||||
bluetooth::BluetoothState::event_handler(cb);
|
||||
}
|
||||
|
||||
auto DeviceName() -> std::string {
|
||||
auto DeviceName() -> std::pmr::string {
|
||||
uint8_t mac[8]{0};
|
||||
esp_efuse_mac_get_default(mac);
|
||||
std::ostringstream name;
|
||||
name << "TANGARA " << std::hex << static_cast<int>(mac[0])
|
||||
<< static_cast<int>(mac[1]);
|
||||
return name.str();
|
||||
return std::pmr::string{name.str(), &memory::kSpiRamResource};
|
||||
}
|
||||
|
||||
namespace bluetooth {
|
||||
@@ -212,7 +214,7 @@ void Disabled::react(const events::Enable&) {
|
||||
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
|
||||
|
||||
// Set a reasonable name for the device.
|
||||
std::string name = DeviceName();
|
||||
std::pmr::string name = DeviceName();
|
||||
esp_bt_dev_set_device_name(name.c_str());
|
||||
|
||||
// Initialise GAP. This controls advertising our device, and scanning for
|
||||
@@ -307,8 +309,8 @@ auto Scanning::OnDeviceDiscovered(esp_bt_gap_cb_param_t* param) -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
device.name =
|
||||
std::string{reinterpret_cast<char*>(name), static_cast<size_t>(length)};
|
||||
device.name = std::pmr::string{reinterpret_cast<char*>(name),
|
||||
static_cast<size_t>(length)};
|
||||
|
||||
bool is_preferred = false;
|
||||
{
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace drivers {
|
||||
namespace bluetooth {
|
||||
|
||||
@@ -11,7 +13,7 @@ typedef std::array<uint8_t, 6> mac_addr_t;
|
||||
|
||||
struct Device {
|
||||
mac_addr_t address;
|
||||
std::string name;
|
||||
std::pmr::string name;
|
||||
uint32_t class_of_device;
|
||||
int8_t signal_strength;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ class FatfsAudioInput {
|
||||
std::shared_ptr<SdStorage> storage_;
|
||||
RingbufHandle_t output_;
|
||||
|
||||
std::string path_;
|
||||
std::pmr::string path_;
|
||||
};
|
||||
|
||||
} // namespace drivers
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "sdmmc_cmd.h"
|
||||
|
||||
#include "gpios.hpp"
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
static const char* kTag = "SDSTORAGE";
|
||||
static const uint8_t kMaxOpenFiles = 8;
|
||||
@@ -74,7 +75,7 @@ auto SdStorage::Create(IGpios& gpio) -> cpp::result<SdStorage*, Error> {
|
||||
// Mount right now, not on first operation.
|
||||
FRESULT ferr = f_mount(fs, "", 1);
|
||||
if (ferr != FR_OK) {
|
||||
std::string err_str;
|
||||
std::pmr::string err_str;
|
||||
switch (ferr) {
|
||||
case FR_DISK_ERR:
|
||||
err_str = "FR_DISK_ERR";
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
namespace drivers {
|
||||
|
||||
static const std::string kTestFilename = "test";
|
||||
static const std::string kTestFilePath =
|
||||
std::string(kStoragePath) + "/" + kTestFilename;
|
||||
static const std::pmr::string kTestFilename = "test";
|
||||
static const std::pmr::string kTestFilePath =
|
||||
std::pmr::string(kStoragePath) + "/" + kTestFilename;
|
||||
|
||||
TEST_CASE("sd card storage", "[integration]") {
|
||||
I2CFixture i2c;
|
||||
@@ -46,7 +46,7 @@ TEST_CASE("sd card storage", "[integration]") {
|
||||
std::ifstream test_file;
|
||||
test_file.open(kTestFilePath.c_str());
|
||||
|
||||
std::string line;
|
||||
std::pmr::string line;
|
||||
REQUIRE(std::getline(test_file, line));
|
||||
REQUIRE(line == "hello here is some test");
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ class Resource : public std::pmr::memory_resource {
|
||||
std::size_t bytes,
|
||||
std::size_t alignment) override;
|
||||
|
||||
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override;
|
||||
bool do_is_equal(
|
||||
const std::pmr::memory_resource& other) const noexcept override;
|
||||
};
|
||||
|
||||
extern Resource kSpiRamResource;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright 2023 jacqueline <me@jacqueline.id.au>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
idf_component_register(SRCS "tasks.cpp" INCLUDE_DIRS "." REQUIRES "span")
|
||||
idf_component_register(SRCS "tasks.cpp" INCLUDE_DIRS "." REQUIRES "span" "memory")
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})
|
||||
|
||||
+10
-8
@@ -12,33 +12,35 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace tasks {
|
||||
|
||||
template <Type t>
|
||||
auto Name() -> std::string;
|
||||
auto Name() -> std::pmr::string;
|
||||
|
||||
template <>
|
||||
auto Name<Type::kUi>() -> std::string {
|
||||
auto Name<Type::kUi>() -> std::pmr::string {
|
||||
return "ui";
|
||||
}
|
||||
template <>
|
||||
auto Name<Type::kAudioDecoder>() -> std::string {
|
||||
auto Name<Type::kAudioDecoder>() -> std::pmr::string {
|
||||
return "audio_dec";
|
||||
}
|
||||
template <>
|
||||
auto Name<Type::kAudioConverter>() -> std::string {
|
||||
auto Name<Type::kAudioConverter>() -> std::pmr::string {
|
||||
return "audio_conv";
|
||||
}
|
||||
template <>
|
||||
auto Name<Type::kDatabase>() -> std::string {
|
||||
auto Name<Type::kDatabase>() -> std::pmr::string {
|
||||
return "db_fg";
|
||||
}
|
||||
template <>
|
||||
auto Name<Type::kDatabaseBackground>() -> std::string {
|
||||
auto Name<Type::kDatabaseBackground>() -> std::pmr::string {
|
||||
return "db_bg";
|
||||
}
|
||||
template <>
|
||||
auto Name<Type::kNvsWriter>() -> std::string {
|
||||
auto Name<Type::kNvsWriter>() -> std::pmr::string {
|
||||
return "nvs";
|
||||
}
|
||||
|
||||
@@ -185,7 +187,7 @@ auto Worker::Main(void* instance) {
|
||||
}
|
||||
}
|
||||
|
||||
Worker::Worker(const std::string& name,
|
||||
Worker::Worker(const std::pmr::string& name,
|
||||
cpp::span<StackType_t> stack,
|
||||
std::size_t queue_size,
|
||||
UBaseType_t priority)
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ enum class Type {
|
||||
};
|
||||
|
||||
template <Type t>
|
||||
auto Name() -> std::string;
|
||||
auto Name() -> std::pmr::string;
|
||||
template <Type t>
|
||||
auto AllocateStack() -> cpp::span<StackType_t>;
|
||||
template <Type t>
|
||||
@@ -76,7 +76,7 @@ auto StartPersistent(BaseType_t core, const std::function<void(void)>& fn)
|
||||
|
||||
class Worker {
|
||||
private:
|
||||
Worker(const std::string& name,
|
||||
Worker(const std::pmr::string& name,
|
||||
cpp::span<StackType_t> stack,
|
||||
std::size_t queue_size,
|
||||
UBaseType_t priority);
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace modals {
|
||||
|
||||
class Confirm : public Modal {
|
||||
public:
|
||||
Confirm(Screen*, const std::string& title, bool has_cancel);
|
||||
Confirm(Screen*, const std::pmr::string& title, bool has_cancel);
|
||||
|
||||
private:
|
||||
lv_obj_t* container_;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace modals {
|
||||
|
||||
class Progress : public Modal {
|
||||
public:
|
||||
Progress(Screen*, std::string title);
|
||||
Progress(Screen*, std::pmr::string title);
|
||||
|
||||
private:
|
||||
lv_obj_t* container_;
|
||||
|
||||
@@ -64,7 +64,7 @@ class Screen {
|
||||
|
||||
class MenuScreen : public Screen {
|
||||
public:
|
||||
MenuScreen(const std::string& title, bool show_back_button = true);
|
||||
MenuScreen(const std::pmr::string& title, bool show_back_button = true);
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace screens {
|
||||
|
||||
class Onboarding : public Screen {
|
||||
public:
|
||||
Onboarding(const std::string& title, bool show_prev, bool show_next);
|
||||
Onboarding(const std::pmr::string& title, bool show_prev, bool show_next);
|
||||
|
||||
private:
|
||||
lv_obj_t* window_;
|
||||
|
||||
@@ -45,7 +45,8 @@ class Playing : public Screen {
|
||||
|
||||
private:
|
||||
auto control_button(lv_obj_t* parent, char* icon) -> lv_obj_t*;
|
||||
auto next_up_label(lv_obj_t* parent, const std::string& text) -> lv_obj_t*;
|
||||
auto next_up_label(lv_obj_t* parent, const std::pmr::string& text)
|
||||
-> lv_obj_t*;
|
||||
|
||||
auto BindTrack(const database::Track& track) -> void;
|
||||
auto ApplyNextUp(const std::vector<database::Track>& tracks) -> void;
|
||||
|
||||
@@ -23,7 +23,7 @@ class TrackBrowser : public Screen {
|
||||
public:
|
||||
TrackBrowser(
|
||||
std::weak_ptr<database::Database> db,
|
||||
const std::string& title,
|
||||
const std::pmr::string& title,
|
||||
std::future<database::Result<database::IndexRecord>*>&& initial_page);
|
||||
~TrackBrowser() {}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "memory_resource.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace widgets {
|
||||
@@ -19,7 +21,7 @@ class TopBar {
|
||||
public:
|
||||
struct Configuration {
|
||||
bool show_back_button;
|
||||
std::string title;
|
||||
std::pmr::string title;
|
||||
};
|
||||
|
||||
enum class PlaybackState {
|
||||
|
||||
@@ -37,7 +37,9 @@ static void button_confirm_cb(lv_event_t* e) {
|
||||
events::Ui().Dispatch(internal::ModalConfirmPressed{});
|
||||
}
|
||||
|
||||
Confirm::Confirm(Screen* host, const std::string& title_text, bool has_cancel)
|
||||
Confirm::Confirm(Screen* host,
|
||||
const std::pmr::string& title_text,
|
||||
bool has_cancel)
|
||||
: Modal(host) {
|
||||
lv_obj_set_layout(root_, LV_LAYOUT_FLEX);
|
||||
lv_obj_set_flex_flow(root_, LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
namespace ui {
|
||||
namespace modals {
|
||||
|
||||
Progress::Progress(Screen* host, std::string title_text) : Modal(host) {
|
||||
Progress::Progress(Screen* host, std::pmr::string title_text) : Modal(host) {
|
||||
lv_obj_set_layout(root_, LV_LAYOUT_FLEX);
|
||||
lv_obj_set_flex_flow(root_, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(root_, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER,
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ auto Screen::CreateTopBar(lv_obj_t* parent,
|
||||
return top_bar_.get();
|
||||
}
|
||||
|
||||
MenuScreen::MenuScreen(const std::string& title, bool show_back_button)
|
||||
MenuScreen::MenuScreen(const std::pmr::string& title, bool show_back_button)
|
||||
: Screen() {
|
||||
lv_group_set_wrap(group_, false);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ static void prev_btn_cb(lv_event_t* ev) {
|
||||
events::Ui().Dispatch(internal::OnboardingNavigate{.forwards = false});
|
||||
}
|
||||
|
||||
Onboarding::Onboarding(const std::string& title,
|
||||
Onboarding::Onboarding(const std::pmr::string& title,
|
||||
bool show_prev,
|
||||
bool show_next) {
|
||||
window_ = lv_win_create(root_, 18);
|
||||
@@ -68,7 +68,8 @@ LinkToManual::LinkToManual() : Onboarding("Welcome!", false, true) {
|
||||
lv_qrcode_update(qr, kManualUrl, sizeof(kManualUrl));
|
||||
}
|
||||
|
||||
static void create_radio_button(lv_obj_t* parent, const std::string& text) {
|
||||
static void create_radio_button(lv_obj_t* parent,
|
||||
const std::pmr::string& text) {
|
||||
lv_obj_t* obj = lv_checkbox_create(parent);
|
||||
lv_checkbox_set_text(obj, text.c_str());
|
||||
// TODO: radio styling
|
||||
|
||||
@@ -96,7 +96,7 @@ auto Playing::control_button(lv_obj_t* parent, char* icon) -> lv_obj_t* {
|
||||
return button;
|
||||
}
|
||||
|
||||
auto Playing::next_up_label(lv_obj_t* parent, const std::string& text)
|
||||
auto Playing::next_up_label(lv_obj_t* parent, const std::pmr::string& text)
|
||||
-> lv_obj_t* {
|
||||
lv_obj_t* button = lv_list_add_btn(parent, NULL, text.c_str());
|
||||
lv_label_set_long_mode(lv_obj_get_child(button, -1), LV_LABEL_LONG_DOT);
|
||||
|
||||
@@ -56,7 +56,7 @@ static void open_sub_menu_cb(lv_event_t* e) {
|
||||
|
||||
static void sub_menu(lv_obj_t* list,
|
||||
lv_group_t* group,
|
||||
const std::string& text,
|
||||
const std::pmr::string& text,
|
||||
Page page) {
|
||||
lv_obj_t* item = lv_list_add_btn(list, NULL, text.c_str());
|
||||
lv_group_add_obj(group, item);
|
||||
@@ -93,8 +93,8 @@ static auto settings_container(lv_obj_t* parent) -> lv_obj_t* {
|
||||
}
|
||||
|
||||
static auto label_pair(lv_obj_t* parent,
|
||||
const std::string& left,
|
||||
const std::string& right) -> lv_obj_t* {
|
||||
const std::pmr::string& left,
|
||||
const std::pmr::string& right) -> lv_obj_t* {
|
||||
lv_obj_t* container = settings_container(parent);
|
||||
lv_obj_t* left_label = lv_label_create(container);
|
||||
lv_label_set_text(left_label, left.c_str());
|
||||
|
||||
@@ -60,7 +60,7 @@ static void item_select_cb(lv_event_t* ev) {
|
||||
|
||||
TrackBrowser::TrackBrowser(
|
||||
std::weak_ptr<database::Database> db,
|
||||
const std::string& title,
|
||||
const std::pmr::string& title,
|
||||
std::future<database::Result<database::IndexRecord>*>&& initial_page)
|
||||
: db_(db),
|
||||
list_(nullptr),
|
||||
|
||||
+1
-1
@@ -297,7 +297,7 @@ void Browse::react(const internal::RecordSelected& ev) {
|
||||
return;
|
||||
}
|
||||
auto query = db->GetPage(&cont.value());
|
||||
std::string title = record.text().value_or("TODO");
|
||||
std::pmr::string title = record.text().value_or("TODO");
|
||||
PushScreen(std::make_shared<screens::TrackBrowser>(
|
||||
sServices->database(), title, std::move(query)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user