From 2cd1f7bad3fce1612c2e271f055974f230e8f5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Wed, 14 Dec 2022 19:04:11 +0100 Subject: [PATCH] Fix local browser handling large amounts saves badly So instead of loading every save in sight and rendering the thumbnails for them too, SaveButtons will only do this when they are actually visible, and unload saves and thumbnails when they are not. Also remove the "Rendering thumbnails" progress bar, which did absolutely nothing. --- src/client/SaveFile.cpp | 43 ++++++++++++++++++--- src/client/SaveFile.h | 5 ++- src/client/ThumbnailRendererTask.cpp | 9 +++++ src/client/ThumbnailRendererTask.h | 4 ++ src/gui/filebrowser/FileBrowserActivity.cpp | 26 ++++--------- src/gui/interface/SaveButton.cpp | 10 ++++- 6 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/client/SaveFile.cpp b/src/client/SaveFile.cpp index 4e4702c73..ba4622638 100644 --- a/src/client/SaveFile.cpp +++ b/src/client/SaveFile.cpp @@ -1,30 +1,61 @@ #include "SaveFile.h" #include "GameSave.h" +#include "common/Platform.h" SaveFile::SaveFile(SaveFile & save): gameSave(NULL), filename(save.filename), displayName(save.displayName), - loadingError(save.loadingError) + loadingError(save.loadingError), + lazyLoad(save.lazyLoad) { if (save.gameSave) gameSave = new GameSave(*save.gameSave); } -SaveFile::SaveFile(ByteString filename): +SaveFile::SaveFile(ByteString filename, bool newLazyLoad): gameSave(NULL), filename(filename), displayName(filename.FromUtf8()), - loadingError("") + loadingError(""), + lazyLoad(newLazyLoad) { } GameSave * SaveFile::GetGameSave() { + if (!gameSave && !loadingError.size() && lazyLoad) + { + try + { + std::vector data; + if (Platform::ReadFile(data, filename)) + { + gameSave = new GameSave(std::move(data)); + } + else + { + loadingError = "cannot access file"; + } + } + catch(std::exception & e) + { + loadingError = ByteString(e.what()).FromUtf8(); + } + } return gameSave; } +void SaveFile::LazyUnload() +{ + if (lazyLoad && gameSave) + { + delete gameSave; + gameSave = nullptr; + } +} + void SaveFile::SetGameSave(GameSave * save) { gameSave = save; @@ -61,6 +92,8 @@ void SaveFile::SetLoadingError(String error) } SaveFile::~SaveFile() { - delete gameSave; + if (gameSave) + { + delete gameSave; + } } - diff --git a/src/client/SaveFile.h b/src/client/SaveFile.h index 32c804cea..b2b62362d 100644 --- a/src/client/SaveFile.h +++ b/src/client/SaveFile.h @@ -8,7 +8,7 @@ class GameSave; class SaveFile { public: SaveFile(SaveFile & save); - SaveFile(ByteString filename); + SaveFile(ByteString filename, bool newLazyLoad = false); GameSave * GetGameSave(); void SetGameSave(GameSave * save); @@ -19,12 +19,15 @@ public: String GetError(); void SetLoadingError(String error); + void LazyUnload(); + virtual ~SaveFile(); private: GameSave * gameSave; ByteString filename; String displayName; String loadingError; + bool lazyLoad; }; #endif /* SAVEFILE_H_ */ diff --git a/src/client/ThumbnailRendererTask.cpp b/src/client/ThumbnailRendererTask.cpp index 7999b9021..d0e629b72 100644 --- a/src/client/ThumbnailRendererTask.cpp +++ b/src/client/ThumbnailRendererTask.cpp @@ -6,6 +6,13 @@ #include "simulation/SaveRenderer.h" #include "client/GameSave.h" +int ThumbnailRendererTask::queueSize = 0; + +int ThumbnailRendererTask::QueueSize() +{ + return queueSize; +} + ThumbnailRendererTask::ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale, bool decorations, bool fire) : Save(new GameSave(*save)), Width(width), @@ -14,10 +21,12 @@ ThumbnailRendererTask::ThumbnailRendererTask(GameSave *save, int width, int heig Fire(fire), AutoRescale(autoRescale) { + queueSize += 1; } ThumbnailRendererTask::~ThumbnailRendererTask() { + queueSize -= 1; } bool ThumbnailRendererTask::doWork() diff --git a/src/client/ThumbnailRendererTask.h b/src/client/ThumbnailRendererTask.h index 21c0a845a..6a1b4989f 100644 --- a/src/client/ThumbnailRendererTask.h +++ b/src/client/ThumbnailRendererTask.h @@ -16,12 +16,16 @@ class ThumbnailRendererTask : public AbandonableTask bool AutoRescale; std::unique_ptr thumbnail; + static int queueSize; + public: ThumbnailRendererTask(GameSave *save, int width, int height, bool autoRescale = false, bool decorations = true, bool fire = true); virtual ~ThumbnailRendererTask(); virtual bool doWork() override; std::unique_ptr Finish(); + + static int QueueSize(); }; #endif // THUMBNAILRENDERER_H diff --git a/src/gui/filebrowser/FileBrowserActivity.cpp b/src/gui/filebrowser/FileBrowserActivity.cpp index b256e08b9..ff48170fa 100644 --- a/src/gui/filebrowser/FileBrowserActivity.cpp +++ b/src/gui/filebrowser/FileBrowserActivity.cpp @@ -43,24 +43,12 @@ class LoadFilesTask: public Task notifyProgress(-1); for(std::vector::iterator iter = files.begin(), end = files.end(); iter != end; ++iter) { - SaveFile * saveFile = new SaveFile(directory + *iter); - try - { - std::vector data; - if (!Platform::ReadFile(data, directory + *iter)) - continue; - GameSave * tempSave = new GameSave(std::move(data)); - saveFile->SetGameSave(tempSave); - saveFiles.push_back(saveFile); + SaveFile * saveFile = new SaveFile(directory + *iter, true); + saveFiles.push_back(saveFile); - ByteString filename = (*iter).SplitFromEndBy(PATH_SEP).After(); - filename = filename.SplitFromEndBy('.').Before(); - saveFile->SetDisplayName(filename.FromUtf8()); - } - catch(std::exception & e) - { - //:( - } + ByteString filename = (*iter).SplitFromEndBy(PATH_SEP).After(); + filename = filename.SplitFromEndBy('.').Before(); + saveFile->SetDisplayName(filename.FromUtf8()); } return true; } @@ -266,7 +254,7 @@ void FileBrowserActivity::OnTick(float dt) if(loadFiles) loadFiles->Poll(); - if(files.size()) + while(files.size()) { SaveFile * saveFile = files.back(); files.pop_back(); @@ -296,7 +284,7 @@ void FileBrowserActivity::OnTick(float dt) componentsQueue.push_back(saveButton); fileX++; } - else if(componentsQueue.size()) + if(componentsQueue.size()) { for(std::vector::iterator iter = componentsQueue.begin(), end = componentsQueue.end(); iter != end; ++iter) { diff --git a/src/gui/interface/SaveButton.cpp b/src/gui/interface/SaveButton.cpp index 4ff680f35..7cc06f791 100644 --- a/src/gui/interface/SaveButton.cpp +++ b/src/gui/interface/SaveButton.cpp @@ -126,7 +126,7 @@ void SaveButton::Tick(float dt) { if (!thumbnail) { - if (!triedThumbnail) + if (!triedThumbnail && wantsDraw && ThumbnailRendererTask::QueueSize() < 10) { float scaleFactor = (Size.Y-25)/((float)YRES); ui::Point thumbBoxSize = ui::Point(int(XRES*scaleFactor), int(YRES*scaleFactor)); @@ -170,6 +170,14 @@ void SaveButton::Tick(float dt) thumbSize = ui::Point(thumbnail->Width, thumbnail->Height); } } + if (!wantsDraw && !thumbnailRenderer) + { + file->LazyUnload(); + thumbnail.reset(); + thumbSize = { 0, 0 }; + triedThumbnail = false; + } + wantsDraw = false; } void SaveButton::Draw(const Point& screenPos)