Skip to content

Commit

Permalink
Make currentSong thread safe
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenAlex committed Feb 26, 2025
1 parent 989f27f commit e5e0aab
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 22 deletions.
9 changes: 8 additions & 1 deletion include/UI/ViewControllers/SongList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ DECLARE_CLASS_CODEGEN_INTERFACES(BetterSongSearch::UI::ViewControllers, SongList

void SortAndFilterSongs(FilterTypes::SortMode sort, std::string_view search, bool resetTable);
void ResetTable();
SongDetailsCache::Song const* currentSong = nullptr;

void UpdateDetails();
void SetIsDownloaded(bool isDownloaded, bool downloadable = true);

Expand All @@ -175,4 +175,11 @@ DECLARE_CLASS_CODEGEN_INTERFACES(BetterSongSearch::UI::ViewControllers, SongList
void SongDataError(std::string message);
void PlayerDataLoaded();
void OnSongsLoaded(std::span<SongCore::SongLoader::CustomBeatmapLevel* const> songs);

SongDetailsCache::Song const* GetCurrentSong();
void SetCurrentSong(SongDetailsCache::Song const* song);

private:
std::shared_mutex _currentSongMutex;
SongDetailsCache::Song const* _currentSong = nullptr;
};
3 changes: 2 additions & 1 deletion src/UI/Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ custom_types::Helpers::Coroutine BetterSongSearch::UI::Manager::Debug() {
auto songlist = fcInstance->SongListController;
co_yield reinterpret_cast<System::Collections::IEnumerator*>(UnityEngine::WaitForSeconds::New_ctor(0.1f));
songlist->SelectRandom();
if (songlist->currentSong) {
auto currentSong = songlist->GetCurrentSong();
if (currentSong) {
co_yield reinterpret_cast<System::Collections::IEnumerator*>(UnityEngine::WaitForSeconds::New_ctor(0.1f));
songlist->ShowSongDetails();
co_yield reinterpret_cast<System::Collections::IEnumerator*>(UnityEngine::WaitForSeconds::New_ctor(0.1f));
Expand Down
24 changes: 14 additions & 10 deletions src/UI/ViewControllers/DownloadHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,16 +327,20 @@ void ViewControllers::DownloadHistoryViewController::ProcessDownloads(bool force
hasUnloadedDownloads = false;
}
}
if (fcInstance && fcInstance->SongListController && fcInstance->SongListController->currentSong != nullptr) {
if (currentEntry->status == DownloadHistoryEntry::DownloadStatus::Downloaded) {
// NESTING HELLLL
if (fcInstance->SongListController->currentSong->hash() == currentEntry->hash) {
fcInstance->SongListController->SetIsDownloaded(true);
}
fcInstance->SongListController->songListTable()->RefreshCells(false, true);
} else {
if (fcInstance->SongListController->currentSong->hash() == currentEntry->hash) {
fcInstance->SongListController->SetIsDownloaded(false);

if (fcInstance && fcInstance->SongListController) {
auto currentSong = fcInstance->SongListController->GetCurrentSong();
if (currentSong != nullptr) {
if (currentEntry->status == DownloadHistoryEntry::DownloadStatus::Downloaded) {
// NESTING HELLLL
if (currentSong->hash() == currentEntry->hash) {
fcInstance->SongListController->SetIsDownloaded(true);
}
fcInstance->SongListController->songListTable()->RefreshCells(false, true);
} else {
if (currentSong->hash() == currentEntry->hash) {
fcInstance->SongListController->SetIsDownloaded(false);
}
}
}
}
Expand Down
54 changes: 44 additions & 10 deletions src/UI/ViewControllers/SongList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <algorithm>
#include <future>
#include <shared_mutex>
#include <string>

#include "assets.hpp"
Expand Down Expand Up @@ -375,8 +376,8 @@ void ViewControllers::SongListController::ShowSettings() {
// Song buttons
void ViewControllers::SongListController::Download() {
#ifdef SONGDOWNLOADER

auto songData = this->currentSong;
auto currentSong = GetCurrentSong();
auto songData = currentSong;

if (songData != nullptr) {
fcInstance->DownloadHistoryViewController->TryAddDownload(songData);
Expand Down Expand Up @@ -481,6 +482,7 @@ void ViewControllers::SongListController::Play() {
}

void ViewControllers::SongListController::PlaySong(SongDetailsCache::Song const* songToPlay) {
auto currentSong = GetCurrentSong();
if (songToPlay == nullptr) {
songToPlay = currentSong;
if (currentSong == nullptr) {
Expand Down Expand Up @@ -543,12 +545,14 @@ void ViewControllers::SongListController::ShowBatchDownload() {
}

void ViewControllers::SongListController::ShowSongDetails() {
if (this->currentSong) {
uploadDetailsModal->OpenModal(this->currentSong);
auto currentSong = GetCurrentSong();
if (currentSong) {
uploadDetailsModal->OpenModal(currentSong);
}
}

void ViewControllers::SongListController::UpdateDetails() {
auto currentSong = GetCurrentSong();
if (currentSong == nullptr) {
return;
}
Expand Down Expand Up @@ -611,7 +615,12 @@ void ViewControllers::SongListController::UpdateDetails() {
if (success) {
std::vector<uint8_t> data = bytes;
DEBUG("Image size: {}", pretty_bytes(bytes.size()));
if (song->hash() != this->currentSong->hash()) {
auto currentSong = GetCurrentSong();
// Return if the song has changed somehow
if (currentSong == nullptr) {
return;
}
if (song->hash() != currentSong->hash()) {
return;
}
auto spriteArray = ArrayW(data);
Expand Down Expand Up @@ -675,12 +684,13 @@ void ViewControllers::SongListController::UpdateDetails() {
}

void ViewControllers::SongListController::FilterByUploader() {
if (!this->currentSong) {
auto currentSong = GetCurrentSong();
if (!currentSong) {
return;
}

fcInstance->FilterViewController->uploadersString = this->currentSong->uploaderName();
SetStringSettingValue(fcInstance->FilterViewController->uploadersStringControl, (std::string) this->currentSong->uploaderName());
fcInstance->FilterViewController->uploadersString = currentSong->uploaderName();
SetStringSettingValue(fcInstance->FilterViewController->uploadersStringControl, (std::string) currentSong->uploaderName());
fcInstance->FilterViewController->UpdateFilterSettings();
DEBUG("FilterByUploader");
}
Expand All @@ -707,10 +717,12 @@ void ViewControllers::SongListController::SortAndFilterSongs(FilterTypes::SortMo

void ViewControllers::SongListController::SetSelectedSong(SongDetailsCache::Song const* song) {
// TODO: Fill all fields, download image, activate buttons
if (currentSong != nullptr && currentSong->hash() == song->hash()) {
auto prevSong = GetCurrentSong();
if (prevSong != nullptr && song != nullptr && prevSong->hash() == song->hash()) {
return;
}
currentSong = song;

SetCurrentSong(song);

DEBUG("Updating details");
this->UpdateDetails();
Expand Down Expand Up @@ -762,6 +774,7 @@ void ViewControllers::SongListController::SearchDone() {
}
}

auto currentSong = GetCurrentSong();
// Reset song list table selection
if (!currentSong) {
SelectSong(songListTable(), 0);
Expand Down Expand Up @@ -816,13 +829,34 @@ void ViewControllers::SongListController::PlayerDataLoaded() {
}

void ViewControllers::SongListController::OnSongsLoaded(std::span<SongCore::SongLoader::CustomBeatmapLevel* const> songs) {
auto currentSong = GetCurrentSong();
if (currentSong == nullptr) {
return;
}

// Ensure it runs on the main thread
bool isMainThread = BSML::MainThreadScheduler::CurrentThreadIsMainThread();
if (!isMainThread) {
ERROR("Calling OnSongsLoaded not on the main thread, sending to main thread");
BSML::MainThreadScheduler::Schedule([this, songs] {
this->OnSongsLoaded(songs);
});
return;
}

auto song = currentSong;
auto beatmap = SongCore::API::Loading::GetLevelByHash(std::string(song->hash()));
bool loaded = beatmap != nullptr;

SetIsDownloaded(loaded);
}

SongDetailsCache::Song const* ViewControllers::SongListController::GetCurrentSong() {
std::shared_lock<std::shared_mutex> lock(_currentSongMutex);
return _currentSong;
}

void ViewControllers::SongListController::SetCurrentSong(SongDetailsCache::Song const* song) {
std::unique_lock<std::shared_mutex> lock(_currentSongMutex);
_currentSong = song;
}

0 comments on commit e5e0aab

Please sign in to comment.