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)