#include "common.h" #include #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::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->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::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(); } else { LOG_FATAL("Failed to set launch parameters.\n"); } return TaskResult::Completed(); }); } void RomBrowserController::HandleChangeDisplayModeTrigger() { LOG_DEBUG("RomBrowserStateTrigger::ChangeDisplayMode\n"); _romBrowserViewModel = SharedPtr(new RomBrowserViewModel(this)); }