Handle the loading state whilst appending many tracks better

1) Update the queue length periodically so that the user can see we're
   working
2) Clear any previous track and display "loading..." instead
custom
jacqueline 8 months ago committed by cooljqln
parent d3c15bf070
commit 9ec8d6dafc
  1. 13
      lua/playing.lua
  2. 1
      src/tangara/audio/audio_events.hpp
  3. 5
      src/tangara/audio/audio_fsm.cpp
  4. 12
      src/tangara/audio/track_queue.cpp
  5. 10
      src/tangara/ui/ui_fsm.cpp
  6. 1
      src/tangara/ui/ui_fsm.hpp

@ -226,7 +226,18 @@ return screen:new {
end end
end), end),
playback.track:bind(function(track) playback.track:bind(function(track)
if not track then return end if not track then
if queue.loading:get() then
title:set { text = "Loading..." }
else
title:set { text = "" }
end
artist:set { text = "" }
cur_time:set { text = format_time(0) }
end_time:set { text = format_time(0) }
scrubber:set { value = 0 }
return
end
if track.duration then if track.duration then
end_time:set { text = format_time(track.duration) } end_time:set { text = format_time(track.duration) }
else else

@ -103,6 +103,7 @@ struct QueueUpdate : tinyfsm::Event {
kRepeatingLastTrack, kRepeatingLastTrack,
kTrackFinished, kTrackFinished,
kDeserialised, kDeserialised,
kBulkLoadingUpdate,
}; };
Reason reason; Reason reason;
}; };

@ -112,10 +112,13 @@ void AudioState::react(const QueueUpdate& ev) {
cmd.new_track = std::monostate{}; cmd.new_track = std::monostate{};
} }
break; break;
case QueueUpdate::kBulkLoadingUpdate:
// Bulk loading updates are informational only; a separate QueueUpdate
// event will be sent when loading is done.
case QueueUpdate::kDeserialised: case QueueUpdate::kDeserialised:
default:
// The current track is deserialised separately in order to retain seek // The current track is deserialised separately in order to retain seek
// position. // position.
default:
return; return;
} }

@ -26,6 +26,7 @@
#include "database/track.hpp" #include "database/track.hpp"
#include "events/event_queue.hpp" #include "events/event_queue.hpp"
#include "memory_resource.hpp" #include "memory_resource.hpp"
#include "random.hpp"
#include "tasks.hpp" #include "tasks.hpp"
#include "track_queue.hpp" #include "track_queue.hpp"
#include "ui/ui_fsm.hpp" #include "ui/ui_fsm.hpp"
@ -190,6 +191,8 @@ auto TrackQueue::append(Item i) -> void {
// doesn't block. // doesn't block.
bg_worker_.Dispatch<void>([=, this]() { bg_worker_.Dispatch<void>([=, this]() {
database::TrackIterator it = std::get<database::TrackIterator>(i); database::TrackIterator it = std::get<database::TrackIterator>(i);
size_t next_update_at = 10;
while (true) { while (true) {
auto next = *it; auto next = *it;
if (!next) { if (!next) {
@ -205,7 +208,16 @@ auto TrackQueue::append(Item i) -> void {
} }
} }
it++; it++;
// Appending very large iterators can take a while. Send out periodic
// queue updates during them so that the user has an idea what's going
// on.
if (!--next_update_at) {
next_update_at = util::sRandom->RangeInclusive(10, 20);
notifyChanged(false, Reason::kBulkLoadingUpdate);
}
} }
{ {
const std::unique_lock<std::shared_mutex> lock(mutex_); const std::unique_lock<std::shared_mutex> lock(mutex_);
updateShuffler(was_queue_empty); updateShuffler(was_queue_empty);

@ -225,6 +225,7 @@ lua::Property UiState::sQueueRandom{false, [](const lua::LuaValue& val) {
sServices->track_queue().random(new_val); sServices->track_queue().random(new_val);
return true; return true;
}}; }};
lua::Property UiState::sQueueLoading{false};
lua::Property UiState::sVolumeCurrentPct{ lua::Property UiState::sVolumeCurrentPct{
0, [](const lua::LuaValue& val) { 0, [](const lua::LuaValue& val) {
@ -424,7 +425,7 @@ void UiState::react(const system_fsm::BatteryStateChanged& ev) {
} }
} }
void UiState::react(const audio::QueueUpdate&) { void UiState::react(const audio::QueueUpdate& update) {
auto& queue = sServices->track_queue(); auto& queue = sServices->track_queue();
auto queue_size = queue.totalSize(); auto queue_size = queue.totalSize();
sQueueSize.setDirect(static_cast<int>(queue_size)); sQueueSize.setDirect(static_cast<int>(queue_size));
@ -439,6 +440,12 @@ void UiState::react(const audio::QueueUpdate&) {
sQueueRandom.setDirect(queue.random()); sQueueRandom.setDirect(queue.random());
sQueueRepeat.setDirect(queue.repeat()); sQueueRepeat.setDirect(queue.repeat());
sQueueReplay.setDirect(queue.replay()); sQueueReplay.setDirect(queue.replay());
if (update.reason == audio::QueueUpdate::Reason::kBulkLoadingUpdate) {
sQueueLoading.setDirect(true);
} else {
sQueueLoading.setDirect(false);
}
} }
void UiState::react(const audio::PlaybackUpdate& ev) { void UiState::react(const audio::PlaybackUpdate& ev) {
@ -614,6 +621,7 @@ void Lua::entry() {
{"replay", &sQueueReplay}, {"replay", &sQueueReplay},
{"repeat_track", &sQueueRepeat}, {"repeat_track", &sQueueRepeat},
{"random", &sQueueRandom}, {"random", &sQueueRandom},
{"loading", &sQueueLoading},
}); });
registry.AddPropertyModule("volume", registry.AddPropertyModule("volume",
{ {

@ -122,6 +122,7 @@ class UiState : public tinyfsm::Fsm<UiState> {
static lua::Property sQueueReplay; static lua::Property sQueueReplay;
static lua::Property sQueueRepeat; static lua::Property sQueueRepeat;
static lua::Property sQueueRandom; static lua::Property sQueueRandom;
static lua::Property sQueueLoading;
static lua::Property sVolumeCurrentPct; static lua::Property sVolumeCurrentPct;
static lua::Property sVolumeCurrentDb; static lua::Property sVolumeCurrentDb;

Loading…
Cancel
Save