Files
pico-launcher/arm9/source/romBrowser/RomBrowserController.cpp
2025-11-25 17:41:31 +01:00

210 lines
6.5 KiB
C++

#include "common.h"
#include <array>
#include "picoLoaderBootstrap.h"
#include "PicoLoaderProcess.h"
#include "FileType/ExtensionFileTypeProvider.h"
#include "FileType/FileType.h"
#include "SdFolderFactory.h"
#include "services/settings/IAppSettingsService.h"
#include "RomBrowserController.h"
RomBrowserController::RomBrowserController(
IAppSettingsService* appSettingsService, TaskQueueBase* ioTaskQueue,
TaskQueueBase* bgTaskQueue)
: _appSettingsService(appSettingsService)
, _ioTaskQueue(ioTaskQueue), _bgTaskQueue(bgTaskQueue)
, _fileTypeProvider(appSettingsService->GetAppSettings()) { }
void RomBrowserController::NavigateToPath(const TCHAR* name)
{
StringUtil::Copy(_navigatePath, name, sizeof(_navigatePath) / sizeof(_navigatePath[0]));
_stateMachine.Fire(RomBrowserStateTrigger::Navigate);
}
void RomBrowserController::LaunchFile(const FileInfo& fileInfo)
{
_launchFileInfo = FileInfo(fileInfo);
_stateMachine.Fire(RomBrowserStateTrigger::Launch);
}
void RomBrowserController::ShowGameInfo()
{
// Currently disabled, as the game info panel is not complete
// _stateMachine.Fire(RomBrowserStateTrigger::ShowGameInfo);
}
void RomBrowserController::HideGameInfo()
{
_stateMachine.Fire(RomBrowserStateTrigger::HideGameInfo);
}
void RomBrowserController::ShowDisplaySettings()
{
_stateMachine.Fire(RomBrowserStateTrigger::ShowDisplaySettings);
}
void RomBrowserController::HideDisplaySettings()
{
if (_saveSettingsPending)
{
_saveSettingsPending = false;
_ioTaskQueue->Enqueue([this] (const vu8& cancelRequested)
{
_appSettingsService->Save();
return TaskResult<void>::Completed();
});
}
_stateMachine.Fire(RomBrowserStateTrigger::HideDisplaySettings);
}
void RomBrowserController::SetRomBrowserDisplaySettings(
const RomBrowserDisplaySettings& romBrowserDisplaySettings)
{
_appSettingsService->GetAppSettings().romBrowserDisplaySettings = romBrowserDisplaySettings;
_saveSettingsPending = true;
_stateMachine.Fire(RomBrowserStateTrigger::ChangeDisplayMode);
}
void RomBrowserController::Update()
{
_stateMachine.Update();
if (_stateMachine.HasStateChanged())
{
HandleTrigger();
}
switch (_stateMachine.GetCurrentState())
{
case RomBrowserState::Start:
{
LOG_DEBUG("RomBrowserState::Start\n");
const auto& lastUsed = _appSettingsService->GetAppSettings().lastUsedFilePath;
if (strlen(lastUsed.GetString()) != 0)
{
NavigateToPath(lastUsed.GetString());
}
else
{
NavigateToPath("/");
}
break;
}
case RomBrowserState::LoadingFolder:
{
if (_navigateTask.GetTask().IsCompletedSuccessfully())
{
_navigateTask.Dispose();
_stateMachine.Fire(RomBrowserStateTrigger::FolderLoadDone);
}
break;
}
case RomBrowserState::Launching:
default:
{
break;
}
}
}
void RomBrowserController::HandleTrigger()
{
switch (_stateMachine.GetLastTrigger())
{
case RomBrowserStateTrigger::Navigate:
HandleNavigateTrigger();
break;
case RomBrowserStateTrigger::FolderLoadDone:
HandleFolderLoadDoneTrigger();
break;
case RomBrowserStateTrigger::Launch:
HandleLaunchTrigger();
break;
case RomBrowserStateTrigger::ChangeDisplayMode:
HandleChangeDisplayModeTrigger();
break;
default:
break;
}
}
void RomBrowserController::HandleNavigateTrigger()
{
LOG_DEBUG("RomBrowserStateTrigger::Navigate\n");
_navigateTask = _ioTaskQueue->Enqueue([this] (const vu8& cancelRequested)
{
if (!_coverRepository)
{
_coverRepository = std::make_unique<CoverRepository>();
_coverRepository->Initialize();
}
u64 startTick = gTickCounter.GetValue();
_navigateFileName = nullptr;
if (strcmp(_navigatePath, "/") != 0) // can't f_stat on root dir
{
FILINFO fileInfo;
if (f_stat(_navigatePath, &fileInfo) != FR_OK)
{
StringUtil::Copy(_navigatePath, "/", sizeof(_navigatePath) / sizeof(_navigatePath[0]));
}
else if (!(fileInfo.fattrib & AM_DIR))
{
_navigateFileName = strrchr(_navigatePath, '/') + 1;
_navigateFileName[-1] = 0;
}
}
f_chdir(_navigatePath);
SdFolderFactory sdFolderFactory { &_fileTypeProvider };
_newSdFolder = sdFolderFactory.CreateFromPath(".");
u64 endTick = gTickCounter.GetValue();
LOG_DEBUG("Loading files in folder took: %d us\n", (u32)TickCounter::TicksToMicroSeconds(endTick - startTick));
return TaskResult<void>::Completed();
});
}
void RomBrowserController::HandleFolderLoadDoneTrigger()
{
LOG_DEBUG("RomBrowserStateTrigger::FolderLoadDone\n");
_romBrowserViewModel.Reset();
_sdFolder = std::move(_newSdFolder);
_romBrowserViewModel = SharedPtr(new RomBrowserViewModel(this, _navigateFileName));
}
void RomBrowserController::HandleLaunchTrigger()
{
LOG_DEBUG("RomBrowserStateTrigger::Launch\n");
_ioTaskQueue->Enqueue([this] (const vu8& cancelRequested)
{
f_getcwd(_navigatePath, sizeof(_navigatePath) / sizeof(_navigatePath[0]));
int idx = strlcat(_navigatePath, "/", sizeof(_navigatePath));
if (_navigatePath[idx - 2] == '/')
_navigatePath[idx - 1] = 0;
strlcat(_navigatePath, _launchFileInfo.GetFileName(), sizeof(_navigatePath));
_appSettingsService->GetAppSettings().lastUsedFilePath = _navigatePath;
_appSettingsService->Save();
auto loadParams = pload_getLoadParams();
loadParams->savePath[0] = 0;
loadParams->arguments[0] = 0;
loadParams->argumentsLength = 0;
if (_launchFileInfo.GetFileType()->TrySetLaunchParameters(loadParams, _navigatePath))
{
gProcessManager.Goto<PicoLoaderProcess>();
}
else
{
LOG_FATAL("Failed to set launch parameters.\n");
}
return TaskResult<void>::Completed();
});
}
void RomBrowserController::HandleChangeDisplayModeTrigger()
{
LOG_DEBUG("RomBrowserStateTrigger::ChangeDisplayMode\n");
_romBrowserViewModel = SharedPtr(new RomBrowserViewModel(this));
}