diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index 858102b4b..e720f0e88 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -415,11 +415,10 @@ int main(int argc, char * argv[]) } else { - SaveFile * newFile = new SaveFile(openArg.value()); - GameSave * newSave = new GameSave(std::move(gameSaveData)); - newFile->SetGameSave(newSave); - gameController->LoadSaveFile(newFile); - delete newFile; + auto newFile = std::make_unique(openArg.value()); + auto newSave = std::make_unique(std::move(gameSaveData)); + newFile->SetGameSave(std::move(newSave)); + gameController->LoadSaveFile(std::move(newFile)); } } @@ -463,17 +462,16 @@ int main(int argc, char * argv[]) } int saveId = saveIdPart.ToNumber(); - SaveInfo * newSave = Client::Ref().GetSave(saveId, 0); + auto newSave = Client::Ref().GetSave(saveId, 0); if (!newSave) throw std::runtime_error("Could not load save info"); auto saveData = Client::Ref().GetSaveData(saveId, 0); if (!saveData.size()) throw std::runtime_error(("Could not load save\n" + Client::Ref().GetLastError()).ToUtf8()); - GameSave * newGameSave = new GameSave(std::move(saveData)); - newSave->SetGameSave(newGameSave); + auto newGameSave = std::make_unique(std::move(saveData)); + newSave->SetGameSave(std::move(newGameSave)); - gameController->LoadSave(newSave); - delete newSave; + gameController->LoadSave(std::move(newSave)); } catch (std::exception & e) { diff --git a/src/PowderToyRenderer.cpp b/src/PowderToyRenderer.cpp index b1159b25f..fc7747d49 100644 --- a/src/PowderToyRenderer.cpp +++ b/src/PowderToyRenderer.cpp @@ -27,10 +27,10 @@ int main(int argc, char *argv[]) return 1; } - GameSave * gameSave = NULL; + std::unique_ptr gameSave; try { - gameSave = new GameSave(fileData, false); + gameSave = std::make_unique(fileData, false); } catch (ParseException &e) { @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) if (gameSave) { - sim->Load(gameSave, true); + sim->Load(gameSave.get(), true); //Render save ren->decorations_enable = true; diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 90c5cbf7f..80c4f0782 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -495,10 +495,10 @@ void Client::MoveStampToFront(ByteString stampID) } } -SaveFile * Client::GetStamp(ByteString stampID) +std::unique_ptr Client::GetStamp(ByteString stampID) { ByteString stampFile = ByteString(ByteString::Build(STAMPS_DIR, PATH_SEP_CHAR, stampID, ".stm")); - SaveFile *saveFile = LoadSaveFile(stampFile); + auto saveFile = LoadSaveFile(stampFile); if (!saveFile) saveFile = LoadSaveFile(stampID); else @@ -517,7 +517,7 @@ void Client::DeleteStamp(ByteString stampID) } } -ByteString Client::AddStamp(GameSave * saveData) +ByteString Client::AddStamp(std::unique_ptr saveData) { auto now = (uint64_t)time(NULL); if (lastStampTime != now) @@ -854,7 +854,7 @@ RequestStatus Client::PublishSave(int saveID) return ret; } -SaveInfo * Client::GetSave(int saveID, int saveDate) +std::unique_ptr Client::GetSave(int saveID, int saveDate) { lastError = ""; ByteStringBuilder urlStream; @@ -902,7 +902,7 @@ SaveInfo * Client::GetSave(int saveID, int saveDate) for (Json::UInt j = 0; j < tagsArray.size(); j++) tempTags.push_back(tagsArray[j].asString()); - SaveInfo * tempSave = new SaveInfo(tempID, tempCreatedDate, tempUpdatedDate, tempScoreUp, + auto tempSave = std::make_unique(tempID, tempCreatedDate, tempUpdatedDate, tempScoreUp, tempScoreDown, tempMyScore, tempUsername, tempName, tempDescription, tempPublished, tempTags); tempSave->Comments = tempComments; @@ -914,29 +914,29 @@ SaveInfo * Client::GetSave(int saveID, int saveDate) catch (std::exception & e) { lastError = "Could not read response: " + ByteString(e.what()).FromUtf8(); - return NULL; + return nullptr; } } else { lastError = http::StatusText(dataStatus); } - return NULL; + return nullptr; } -SaveFile * Client::LoadSaveFile(ByteString filename) +std::unique_ptr Client::LoadSaveFile(ByteString filename) { ByteString err; - SaveFile *file = nullptr; + std::unique_ptr file; if (Platform::FileExists(filename)) { - file = new SaveFile(filename); + file = std::make_unique(filename); try { std::vector data; if (Platform::ReadFile(data, filename)) { - file->SetGameSave(new GameSave(std::move(data))); + file->SetGameSave(std::make_unique(std::move(data))); } else { diff --git a/src/client/Client.h b/src/client/Client.h index 6690dd9fb..1cfa53abe 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -114,9 +114,9 @@ public: RequestStatus ExecVote(int saveID, int direction); RequestStatus UploadSave(SaveInfo & save); - SaveFile * GetStamp(ByteString stampID); + std::unique_ptr GetStamp(ByteString stampID); void DeleteStamp(ByteString stampID); - ByteString AddStamp(GameSave * saveData); + ByteString AddStamp(std::unique_ptr saveData); void RescanStamps(); const std::vector &GetStamps() const; void MoveStampToFront(ByteString stampID); @@ -127,8 +127,8 @@ public: LoginStatus Login(ByteString username, ByteString password, User & user); - SaveInfo * GetSave(int saveID, int saveDate); - SaveFile * LoadSaveFile(ByteString filename); + std::unique_ptr GetSave(int saveID, int saveDate); + std::unique_ptr LoadSaveFile(ByteString filename); RequestStatus DeleteSave(int saveID); RequestStatus ReportSave(int saveID, String message); diff --git a/src/client/SaveFile.cpp b/src/client/SaveFile.cpp index fb9db8bbf..c2ed54fed 100644 --- a/src/client/SaveFile.cpp +++ b/src/client/SaveFile.cpp @@ -2,19 +2,7 @@ #include "GameSave.h" #include "common/platform/Platform.h" -SaveFile::SaveFile(SaveFile & save): - gameSave(NULL), - filename(save.filename), - displayName(save.displayName), - loadingError(save.loadingError), - lazyLoad(save.lazyLoad) -{ - if (save.gameSave) - gameSave = new GameSave(*save.gameSave); -} - SaveFile::SaveFile(ByteString filename, bool newLazyLoad): - gameSave(NULL), filename(filename), displayName(filename.FromUtf8()), loadingError(""), @@ -23,7 +11,7 @@ SaveFile::SaveFile(ByteString filename, bool newLazyLoad): } -GameSave * SaveFile::GetGameSave() +const GameSave *SaveFile::LazyGetGameSave() // non-owning { if (!gameSave && !loadingError.size() && lazyLoad) { @@ -32,7 +20,7 @@ GameSave * SaveFile::GetGameSave() std::vector data; if (Platform::ReadFile(data, filename)) { - gameSave = new GameSave(std::move(data)); + gameSave = std::make_unique(std::move(data)); } else { @@ -44,24 +32,33 @@ GameSave * SaveFile::GetGameSave() loadingError = ByteString(e.what()).FromUtf8(); } } - return gameSave; + return gameSave.get(); +} + +const GameSave *SaveFile::GetGameSave() const +{ + return gameSave.get(); +} + +std::unique_ptr SaveFile::TakeGameSave() +{ + return std::move(gameSave); } void SaveFile::LazyUnload() { - if (lazyLoad && gameSave) + if (lazyLoad) { - delete gameSave; - gameSave = nullptr; + gameSave.reset(); } } -void SaveFile::SetGameSave(GameSave * save) +void SaveFile::SetGameSave(std::unique_ptr newGameSave) { - gameSave = save; + gameSave = std::move(newGameSave); } -ByteString SaveFile::GetName() +const ByteString &SaveFile::GetName() const { return filename; } @@ -71,7 +68,7 @@ void SaveFile::SetFileName(ByteString fileName) this->filename = fileName; } -String SaveFile::GetDisplayName() +const String &SaveFile::GetDisplayName() const { return displayName; } @@ -81,7 +78,7 @@ void SaveFile::SetDisplayName(String displayName) this->displayName = displayName; } -String SaveFile::GetError() +const String &SaveFile::GetError() const { return loadingError; } @@ -90,10 +87,3 @@ void SaveFile::SetLoadingError(String error) { loadingError = error; } - -SaveFile::~SaveFile() { - if (gameSave) - { - delete gameSave; - } -} diff --git a/src/client/SaveFile.h b/src/client/SaveFile.h index 1db065a42..b09ba143c 100644 --- a/src/client/SaveFile.h +++ b/src/client/SaveFile.h @@ -1,27 +1,27 @@ #pragma once #include "common/String.h" +#include class GameSave; class SaveFile { public: - SaveFile(SaveFile & save); SaveFile(ByteString filename, bool newLazyLoad = false); - GameSave * GetGameSave(); - void SetGameSave(GameSave * save); - String GetDisplayName(); + const GameSave *LazyGetGameSave(); + const GameSave *GetGameSave() const; + std::unique_ptr TakeGameSave(); + void SetGameSave(std::unique_ptr newSameSave); + const String &GetDisplayName() const; void SetDisplayName(String displayName); - ByteString GetName(); + const ByteString &GetName() const; void SetFileName(ByteString fileName); - String GetError(); + const String &GetError() const; void SetLoadingError(String error); void LazyUnload(); - - virtual ~SaveFile(); private: - GameSave * gameSave; + std::unique_ptr gameSave; ByteString filename; String displayName; String loadingError; diff --git a/src/client/SaveInfo.cpp b/src/client/SaveInfo.cpp index bfa9fb439..f9d84dd75 100644 --- a/src/client/SaveInfo.cpp +++ b/src/client/SaveInfo.cpp @@ -1,30 +1,6 @@ #include "SaveInfo.h" #include "GameSave.h" -SaveInfo::SaveInfo(SaveInfo & save): - id(save.id), - createdDate(save.createdDate), - updatedDate(save.updatedDate), - votesUp(save.votesUp), - votesDown(save.votesDown), - vote(save.vote), - Favourite(false), - Comments(save.Comments), - Views(save.Views), - Version(save.Version), - userName(save.userName), - name(save.name), - Description(save.Description), - Published(save.Published), - gameSave(NULL) -{ - std::list tagsSorted = save.tags; - tagsSorted.sort(); - tags = tagsSorted; - if (save.gameSave) - gameSave = new GameSave(*save.gameSave); -} - SaveInfo::SaveInfo(int _id, int _createdDate, int _updatedDate, int _votesUp, int _votesDown, ByteString _userName, String _name): id(_id), createdDate(_createdDate), @@ -39,9 +15,7 @@ SaveInfo::SaveInfo(int _id, int _createdDate, int _updatedDate, int _votesUp, in userName(_userName), name(_name), Description(""), - Published(false), - tags(), - gameSave(NULL) + Published(false) { } @@ -60,23 +34,13 @@ SaveInfo::SaveInfo(int _id, int _createdDate, int _updatedDate, int _votesUp, in userName(_userName), name(_name), Description(description_), - Published(published_), - tags(), - gameSave(NULL) + Published(published_) { std::list tagsSorted = tags_; tagsSorted.sort(); tags=tagsSorted; } -SaveInfo::~SaveInfo() -{ - if(gameSave) - { - delete gameSave; - } -} - void SaveInfo::SetName(String name) { this->name = name; @@ -99,7 +63,7 @@ void SaveInfo::SetPublished(bool published) { Published = published; } -bool SaveInfo::GetPublished() +bool SaveInfo::GetPublished() const { return Published; } @@ -108,7 +72,7 @@ void SaveInfo::SetVote(int vote) { this->vote = vote; } -int SaveInfo::GetVote() +int SaveInfo::GetVote() const { return vote; } @@ -118,7 +82,7 @@ void SaveInfo::SetUserName(ByteString userName) this->userName = userName; } -ByteString SaveInfo::GetUserName() +const ByteString &SaveInfo::GetUserName() const { return userName; } @@ -127,7 +91,7 @@ void SaveInfo::SetID(int id) { this->id = id; } -int SaveInfo::GetID() +int SaveInfo::GetID() const { return id; } @@ -136,7 +100,7 @@ void SaveInfo::SetVotesUp(int votesUp) { this->votesUp = votesUp; } -int SaveInfo::GetVotesUp() +int SaveInfo::GetVotesUp() const { return votesUp; } @@ -145,7 +109,7 @@ void SaveInfo::SetVotesDown(int votesDown) { this->votesDown = votesDown; } -int SaveInfo::GetVotesDown() +int SaveInfo::GetVotesDown() const { return votesDown; } @@ -154,7 +118,7 @@ void SaveInfo::SetVersion(int version) { this->Version = version; } -int SaveInfo::GetVersion() +int SaveInfo::GetVersion() const { return Version; } @@ -166,18 +130,33 @@ void SaveInfo::SetTags(std::list tags) this->tags=tagsSorted; } -std::list SaveInfo::GetTags() +std::list SaveInfo::GetTags() const { return tags; } -GameSave * SaveInfo::GetGameSave() +const GameSave *SaveInfo::GetGameSave() const { - return gameSave; + return gameSave.get(); } -void SaveInfo::SetGameSave(GameSave * saveGame) +std::unique_ptr SaveInfo::TakeGameSave() { - delete gameSave; - gameSave = saveGame; + return std::move(gameSave); +} + +void SaveInfo::SetGameSave(std::unique_ptr newGameSave) +{ + gameSave = std::move(newGameSave); +} + +std::unique_ptr SaveInfo::CloneInfo() const +{ + auto clone = std::make_unique(id, createdDate, updatedDate, votesUp, votesDown, vote, userName, name, Description, Published, tags); + clone->Favourite = false; + clone->Comments = Comments; + clone->Views = Views; + clone->Version = Version; + clone->tags.sort(); + return clone; } diff --git a/src/client/SaveInfo.h b/src/client/SaveInfo.h index 103348107..2c5167382 100644 --- a/src/client/SaveInfo.h +++ b/src/client/SaveInfo.h @@ -1,6 +1,7 @@ #pragma once #include "common/String.h" #include +#include #ifdef GetUserName # undef GetUserName // dammit windows @@ -29,16 +30,12 @@ public: bool Published; std::list tags; - GameSave * gameSave; - - SaveInfo(SaveInfo & save); + std::unique_ptr gameSave; SaveInfo(int _id, int _createdDate, int _updatedDate, int _votesUp, int _votesDown, ByteString _userName, String _name); SaveInfo(int _id, int _createdDate, int _updatedDate, int _votesUp, int _votesDown, int _vote, ByteString _userName, String _name, String description_, bool published_, std::list tags); - ~SaveInfo(); - void SetName(String name); String GetName(); @@ -46,29 +43,32 @@ public: String GetDescription(); void SetPublished(bool published); - bool GetPublished(); + bool GetPublished() const; void SetUserName(ByteString userName); - ByteString GetUserName(); + const ByteString &GetUserName() const; void SetID(int id); - int GetID(); + int GetID() const; void SetVote(int vote); - int GetVote(); + int GetVote() const; void SetVotesUp(int votesUp); - int GetVotesUp(); + int GetVotesUp() const; void SetVotesDown(int votesDown); - int GetVotesDown(); + int GetVotesDown() const; void SetVersion(int version); - int GetVersion(); + int GetVersion() const; void SetTags(std::list tags); - std::list GetTags(); + std::list GetTags() const; - GameSave * GetGameSave(); - void SetGameSave(GameSave * gameSave); + const GameSave *GetGameSave() const; + std::unique_ptr TakeGameSave(); + void SetGameSave(std::unique_ptr newGameSave); + + std::unique_ptr CloneInfo() const; }; diff --git a/src/common/Vec2.h b/src/common/Vec2.h index f15892c52..d438d11fa 100644 --- a/src/common/Vec2.h +++ b/src/common/Vec2.h @@ -343,7 +343,7 @@ public: constexpr explicit operator bool() const { - return BottomRight.X >= TopLeft.X || BottomRight.Y >= TopLeft.Y; + return BottomRight.X >= TopLeft.X && BottomRight.Y >= TopLeft.Y; } // Return the smallest rectangle that contains both input rectangles, diff --git a/src/gui/filebrowser/FileBrowserActivity.cpp b/src/gui/filebrowser/FileBrowserActivity.cpp index 5a8bf4572..668e811e1 100644 --- a/src/gui/filebrowser/FileBrowserActivity.cpp +++ b/src/gui/filebrowser/FileBrowserActivity.cpp @@ -24,7 +24,7 @@ class LoadFilesTask: public Task { ByteString directory; ByteString search; - std::vector saveFiles; + std::vector> saveFiles; void before() override { @@ -44,20 +44,20 @@ 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, true); - saveFiles.push_back(saveFile); + auto saveFile = std::make_unique(directory + *iter, true); ByteString filename = (*iter).SplitFromEndBy(PATH_SEP_CHAR).After(); filename = filename.SplitFromEndBy('.').Before(); saveFile->SetDisplayName(filename.FromUtf8()); + saveFiles.push_back(std::move(saveFile)); } return true; } public: - std::vector GetSaveFiles() + std::vector> TakeSaveFiles() { - return saveFiles; + return std::move(saveFiles); } LoadFilesTask(ByteString directory, ByteString search): @@ -128,15 +128,20 @@ void FileBrowserActivity::DoSearch(ByteString search) } } -void FileBrowserActivity::SelectSave(SaveFile * file) +void FileBrowserActivity::SelectSave(int index) { if (onSelected) - onSelected(std::unique_ptr(new SaveFile(*file))); + { + auto file = std::move(files[index]); + files.clear(); + onSelected(std::move(file)); + } Exit(); } -void FileBrowserActivity::DeleteSave(SaveFile * file) +void FileBrowserActivity::DeleteSave(int index) { + auto &file = files[index]; String deleteMessage = "Are you sure you want to delete " + file->GetDisplayName() + ".cps?"; if (ConfirmPrompt::Blocking("Delete Save", deleteMessage)) { @@ -145,8 +150,9 @@ void FileBrowserActivity::DeleteSave(SaveFile * file) } } -void FileBrowserActivity::RenameSave(SaveFile * file) +void FileBrowserActivity::RenameSave(int index) { + auto &file = files[index]; ByteString newName = TextPrompt::Blocking("Rename", "Change save name", file->GetDisplayName(), "", 0).ToUtf8(); if (newName.length()) { @@ -168,10 +174,6 @@ void FileBrowserActivity::cleanup() } componentsQueue.clear(); - for (auto file : files) - { - delete file; - } files.clear(); } @@ -199,7 +201,8 @@ void FileBrowserActivity::NotifyDone(Task * task) { fileX = 0; fileY = 0; - files = ((LoadFilesTask*)task)->GetSaveFiles(); + files = ((LoadFilesTask*)task)->TakeSaveFiles(); + createButtons = true; totalFiles = files.size(); delete loadFiles; loadFiles = NULL; @@ -254,35 +257,37 @@ void FileBrowserActivity::OnTick(float dt) if(loadFiles) loadFiles->Poll(); - while(files.size()) + if (createButtons) { - SaveFile * saveFile = files.back(); - files.pop_back(); - - if(fileX == filesX) + createButtons = false; + for (auto i = 0; i < int(files.size()); ++i) { - fileX = 0; - fileY++; - } - ui::SaveButton * saveButton = new ui::SaveButton( - ui::Point( - buttonXOffset + buttonPadding + fileX*(buttonWidth+buttonPadding*2), - buttonYOffset + buttonPadding + fileY*(buttonHeight+buttonPadding*2) - ), - ui::Point(buttonWidth, buttonHeight), - saveFile); - saveButton->AddContextMenu(1); - saveButton->Tick(dt); - saveButton->SetActionCallback({ - [this, saveButton] { SelectSave(saveButton->GetSaveFile()); }, - [this, saveButton] { RenameSave(saveButton->GetSaveFile()); }, - [this, saveButton] { DeleteSave(saveButton->GetSaveFile()); } - }); + auto &saveFile = files[i]; + if(fileX == filesX) + { + fileX = 0; + fileY++; + } + ui::SaveButton * saveButton = new ui::SaveButton( + ui::Point( + buttonXOffset + buttonPadding + fileX*(buttonWidth+buttonPadding*2), + buttonYOffset + buttonPadding + fileY*(buttonHeight+buttonPadding*2) + ), + ui::Point(buttonWidth, buttonHeight), + saveFile.get()); + saveButton->AddContextMenu(1); + saveButton->Tick(dt); + saveButton->SetActionCallback({ + [this, i] { SelectSave(i); }, + [this, i] { RenameSave(i); }, + [this, i] { DeleteSave(i); } + }); - progressBar->SetStatus("Rendering thumbnails"); - progressBar->SetProgress(totalFiles ? (totalFiles - files.size()) * 100 / totalFiles : 0); - componentsQueue.push_back(saveButton); - fileX++; + progressBar->SetStatus("Rendering thumbnails"); + progressBar->SetProgress(totalFiles ? (totalFiles - files.size()) * 100 / totalFiles : 0); + componentsQueue.push_back(saveButton); + fileX++; + } } if(componentsQueue.size()) { diff --git a/src/gui/filebrowser/FileBrowserActivity.h b/src/gui/filebrowser/FileBrowserActivity.h index 603fbf413..7f34b7acb 100644 --- a/src/gui/filebrowser/FileBrowserActivity.h +++ b/src/gui/filebrowser/FileBrowserActivity.h @@ -26,7 +26,8 @@ class FileBrowserActivity: public TaskListener, public WindowActivity OnSelected onSelected; ui::ScrollPanel * itemList; ui::Label * infoText; - std::vector files; + std::vector> files; + bool createButtons = false; std::vector components; std::vector componentsQueue; ByteString directory; @@ -51,9 +52,9 @@ public: void OnTryExit(ExitMethod method) override; void OnMouseDown(int x, int y, unsigned button) override; void loadDirectory(ByteString directory, ByteString search); - void SelectSave(SaveFile * file); - void DeleteSave(SaveFile * file); - void RenameSave(SaveFile * file); + void SelectSave(int index); + void DeleteSave(int index); + void RenameSave(int index); void DoSearch(ByteString search); void NotifyDone(Task * task) override; diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index 6f5142a04..189d80860 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -238,7 +238,7 @@ std::pair GameController::GetSignSplit(int signID) void GameController::PlaceSave(ui::Point position) { - GameSave *placeSave = gameModel->GetPlaceSave(); + auto *placeSave = gameModel->GetPlaceSave(); if (placeSave) { HistorySnapshot(); @@ -408,33 +408,35 @@ void GameController::DrawPoints(int toolSelection, ui::Point oldPos, ui::Point n bool GameController::LoadClipboard() { - GameSave *clip = gameModel->GetClipboard(); + auto *clip = gameModel->GetClipboard(); if (!clip) return false; - gameModel->SetPlaceSave(clip); + gameModel->SetPlaceSave(std::make_unique(*clip)); return true; } -void GameController::LoadStamp(GameSave *stamp) +void GameController::LoadStamp(std::unique_ptr stamp) { - gameModel->SetPlaceSave(stamp); + gameModel->SetPlaceSave(std::move(stamp)); } void GameController::TranslateSave(ui::Point point) { vector2d translate = v2d_new(float(point.X), float(point.Y)); - vector2d translated = gameModel->GetPlaceSave()->Translate(translate); + auto save = gameModel->TakePlaceSave(); + vector2d translated = save->Translate(translate); ui::Point currentPlaceSaveOffset = gameView->GetPlaceSaveOffset(); // resets placeSaveOffset to 0, which is why we back it up first - gameModel->SetPlaceSave(gameModel->GetPlaceSave()); + gameModel->SetPlaceSave(std::move(save)); gameView->SetPlaceSaveOffset(ui::Point(int(translated.x), int(translated.y)) + currentPlaceSaveOffset); } void GameController::TransformSave(matrix2d transform) { vector2d translate = v2d_zero; - gameModel->GetPlaceSave()->Transform(transform, translate); - gameModel->SetPlaceSave(gameModel->GetPlaceSave()); + auto save = gameModel->TakePlaceSave(); + save->Transform(transform, translate); + gameModel->SetPlaceSave(std::move(save)); } void GameController::ToolClick(int toolSelection, ui::Point point) @@ -449,12 +451,11 @@ void GameController::ToolClick(int toolSelection, ui::Point point) ByteString GameController::StampRegion(ui::Point point1, ui::Point point2) { - GameSave * newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), point1.X, point1.Y, point2.X, point2.Y); + auto newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), point1.X, point1.Y, point2.X, point2.Y); if(newSave) { newSave->paused = gameModel->GetPaused(); - ByteString stampName = Client::Ref().AddStamp(newSave); - delete newSave; + ByteString stampName = Client::Ref().AddStamp(std::move(newSave)); if (stampName.length() == 0) new ErrorMessage("Could not create stamp", "Error serializing save file"); return stampName; @@ -468,7 +469,7 @@ ByteString GameController::StampRegion(ui::Point point1, ui::Point point2) void GameController::CopyRegion(ui::Point point1, ui::Point point2) { - GameSave * newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), point1.X, point1.Y, point2.X, point2.Y); + auto newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), point1.X, point1.Y, point2.X, point2.Y); if(newSave) { Json::Value clipboardInfo; @@ -479,7 +480,7 @@ void GameController::CopyRegion(ui::Point point1, ui::Point point2) newSave->authors = clipboardInfo; newSave->paused = gameModel->GetPaused(); - gameModel->SetClipboard(newSave); + gameModel->SetClipboard(std::move(newSave)); } } @@ -1133,8 +1134,7 @@ void GameController::OpenSearch(String searchText) try { HistorySnapshot(); - gameModel->SetSave(search->GetLoadedSave(), gameView->ShiftBehaviour()); - search->ReleaseLoadedSave(); + gameModel->SetSave(search->TakeLoadedSave(), gameView->ShiftBehaviour()); } catch(GameModelException & ex) { @@ -1150,7 +1150,7 @@ void GameController::OpenSearch(String searchText) void GameController::OpenLocalSaveWindow(bool asCurrent) { Simulation * sim = gameModel->GetSimulation(); - GameSave * gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); + auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); if(!gameSave) { new ErrorMessage("Error", "Unable to build save."); @@ -1159,18 +1159,18 @@ void GameController::OpenLocalSaveWindow(bool asCurrent) { gameSave->paused = gameModel->GetPaused(); - SaveFile tempSave(""); + auto tempSave = std::make_unique(""); if (gameModel->GetSaveFile()) { - tempSave.SetFileName(gameModel->GetSaveFile()->GetName()); - tempSave.SetDisplayName(gameModel->GetSaveFile()->GetDisplayName()); + tempSave->SetFileName(gameModel->GetSaveFile()->GetName()); + tempSave->SetDisplayName(gameModel->GetSaveFile()->GetDisplayName()); } - tempSave.SetGameSave(gameSave); + tempSave->SetGameSave(std::move(gameSave)); if (!asCurrent || !gameModel->GetSaveFile()) { - new LocalSaveActivity(tempSave, [this](SaveFile *file) { - gameModel->SetSaveFile(file, gameView->ShiftBehaviour()); + new LocalSaveActivity(std::move(tempSave), [this](auto file) { + gameModel->SetSaveFile(std::move(file), gameView->ShiftBehaviour()); }); } else if (gameModel->GetSaveFile()) @@ -1183,9 +1183,9 @@ void GameController::OpenLocalSaveWindow(bool asCurrent) Client::Ref().SaveAuthorInfo(&localSaveInfo); gameSave->authors = localSaveInfo; - gameModel->SetSaveFile(&tempSave, gameView->ShiftBehaviour()); Platform::MakeDirectory(LOCAL_SAVE_DIR); auto [ fromNewerVersion, saveData ] = gameSave->Serialise(); + gameModel->SetSaveFile(std::move(tempSave), gameView->ShiftBehaviour()); (void)fromNewerVersion; if (saveData.size() == 0) new ErrorMessage("Error", "Unable to serialize game data."); @@ -1197,15 +1197,15 @@ void GameController::OpenLocalSaveWindow(bool asCurrent) } } -void GameController::LoadSaveFile(SaveFile * file) +void GameController::LoadSaveFile(std::unique_ptr file) { - gameModel->SetSaveFile(file, gameView->ShiftBehaviour()); + gameModel->SetSaveFile(std::move(file), gameView->ShiftBehaviour()); } -void GameController::LoadSave(SaveInfo * save) +void GameController::LoadSave(std::unique_ptr save) { - gameModel->SetSave(save, gameView->ShiftBehaviour()); + gameModel->SetSave(std::move(save), gameView->ShiftBehaviour()); } void GameController::OpenSaveDone() @@ -1215,7 +1215,7 @@ void GameController::OpenSaveDone() try { HistorySnapshot(); - LoadSave(activePreview->GetSaveInfo()); + LoadSave(activePreview->TakeSaveInfo()); } catch(GameModelException & ex) { @@ -1241,9 +1241,9 @@ void GameController::OpenSavePreview() void GameController::OpenLocalBrowse() { - new FileBrowserActivity(ByteString::Build(LOCAL_SAVE_DIR, PATH_SEP_CHAR), [this](std::unique_ptr file) { + new FileBrowserActivity(ByteString::Build(LOCAL_SAVE_DIR, PATH_SEP_CHAR), [this](auto file) { HistorySnapshot(); - LoadSaveFile(file.get()); + LoadSaveFile(std::move(file)); }); } @@ -1313,14 +1313,14 @@ void GameController::OpenTags() void GameController::OpenStamps() { localBrowser = new LocalBrowserController([this] { - SaveFile *file = localBrowser->GetSave(); + auto file = localBrowser->TakeSave(); if (file) { if (file->GetError().length()) new ErrorMessage("Error loading stamp", file->GetError()); else if (localBrowser->GetMoveToFront()) Client::Ref().MoveStampToFront(file->GetDisplayName().ToUtf8()); - LoadStamp(file->GetGameSave()); + LoadStamp(file->TakeGameSave()); } }); ui::Engine::Ref().ShowWindow(localBrowser->GetView()); @@ -1361,7 +1361,7 @@ void GameController::OpenSaveWindow() if(gameModel->GetUser().UserID) { Simulation * sim = gameModel->GetSimulation(); - GameSave * gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); + auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); if(!gameSave) { new ErrorMessage("Error", "Unable to build save."); @@ -1372,22 +1372,22 @@ void GameController::OpenSaveWindow() if(gameModel->GetSave()) { - SaveInfo tempSave(*gameModel->GetSave()); - tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, [this](SaveInfo &save) { - save.SetVote(1); - save.SetVotesUp(1); - LoadSave(&save); + auto tempSave = gameModel->GetSave()->CloneInfo(); + tempSave->SetGameSave(std::move(gameSave)); + new ServerSaveActivity(std::move(tempSave), [this](auto save) { + save->SetVote(1); + save->SetVotesUp(1); + LoadSave(std::move(save)); }); } else { - SaveInfo tempSave(0, 0, 0, 0, 0, gameModel->GetUser().Username, ""); - tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, [this](SaveInfo &save) { - save.SetVote(1); - save.SetVotesUp(1); - LoadSave(&save); + auto tempSave = std::make_unique(0, 0, 0, 0, 0, gameModel->GetUser().Username, ""); + tempSave->SetGameSave(std::move(gameSave)); + new ServerSaveActivity(std::move(tempSave), [this](auto save) { + save->SetVote(1); + save->SetVotesUp(1); + LoadSave(std::move(save)); }); } } @@ -1403,7 +1403,7 @@ void GameController::SaveAsCurrent() if(gameModel->GetSave() && gameModel->GetUser().UserID && gameModel->GetUser().Username == gameModel->GetSave()->GetUserName()) { Simulation * sim = gameModel->GetSimulation(); - GameSave * gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); + auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); if(!gameSave) { new ErrorMessage("Error", "Unable to build save."); @@ -1414,15 +1414,15 @@ void GameController::SaveAsCurrent() if(gameModel->GetSave()) { - SaveInfo tempSave(*gameModel->GetSave()); - tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, true, [this](SaveInfo &save) { LoadSave(&save); }); + auto tempSave = gameModel->GetSave()->CloneInfo(); + tempSave->SetGameSave(std::move(gameSave)); + new ServerSaveActivity(std::move(tempSave), true, [this](auto save) { LoadSave(std::move(save)); }); } else { - SaveInfo tempSave(0, 0, 0, 0, 0, gameModel->GetUser().Username, ""); - tempSave.SetGameSave(gameSave); - new ServerSaveActivity(tempSave, true, [this](SaveInfo &save) { LoadSave(&save); }); + auto tempSave = std::make_unique(0, 0, 0, 0, 0, gameModel->GetUser().Username, ""); + tempSave->SetGameSave(std::move(gameSave)); + new ServerSaveActivity(std::move(tempSave), true, [this](auto save) { LoadSave(std::move(save)); }); } } } @@ -1497,12 +1497,12 @@ void GameController::ReloadSim() if(gameModel->GetSave() && gameModel->GetSave()->GetGameSave()) { HistorySnapshot(); - gameModel->SetSave(gameModel->GetSave(), gameView->ShiftBehaviour()); + gameModel->SetSave(gameModel->TakeSave(), gameView->ShiftBehaviour()); } else if(gameModel->GetSaveFile() && gameModel->GetSaveFile()->GetGameSave()) { HistorySnapshot(); - gameModel->SetSaveFile(gameModel->GetSaveFile(), gameView->ShiftBehaviour()); + gameModel->SetSaveFile(gameModel->TakeSaveFile(), gameView->ShiftBehaviour()); } } diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h index 7d2769920..04753eaeb 100644 --- a/src/gui/game/GameController.h +++ b/src/gui/game/GameController.h @@ -127,8 +127,8 @@ public: void SetActiveColourPreset(int preset); void SetColour(ui::Colour colour); void SetToolStrength(float value); - void LoadSaveFile(SaveFile * file); - void LoadSave(SaveInfo * save); + void LoadSaveFile(std::unique_ptr file); + void LoadSave(std::unique_ptr save); void OpenSearch(String searchText); void OpenLogin(); void OpenProfile(); @@ -175,7 +175,7 @@ public: void ToggleNewtonianGravity(); bool LoadClipboard(); - void LoadStamp(GameSave *stamp); + void LoadStamp(std::unique_ptr stamp); void RemoveNotification(Notification * notification); diff --git a/src/gui/game/GameModel.cpp b/src/gui/game/GameModel.cpp index 2d0f89e30..facc4151b 100644 --- a/src/gui/game/GameModel.cpp +++ b/src/gui/game/GameModel.cpp @@ -41,12 +41,8 @@ HistoryEntry::~HistoryEntry() } GameModel::GameModel(): - clipboard(NULL), - placeSave(NULL), activeMenu(-1), currentBrush(0), - currentSave(NULL), - currentFile(NULL), currentUser(0, ""), toolStrength(1.0f), historyPosition(0), @@ -187,10 +183,6 @@ GameModel::~GameModel() } delete sim; delete ren; - delete placeSave; - delete clipboard; - delete currentSave; - delete currentFile; //if(activeTools) // delete[] activeTools; } @@ -929,60 +921,58 @@ std::vector GameModel::GetMenuList() return menuList; } -SaveInfo * GameModel::GetSave() +SaveInfo *GameModel::GetSave() // non-owning { - return currentSave; + return currentSave.get(); } -void GameModel::SaveToSimParameters(const GameSave *saveData) +std::unique_ptr GameModel::TakeSave() { - SetPaused(saveData->paused | GetPaused()); - sim->gravityMode = saveData->gravityMode; - sim->customGravityX = saveData->customGravityX; - sim->customGravityY = saveData->customGravityY; - sim->air->airMode = saveData->airMode; - sim->air->ambientAirTemp = saveData->ambientAirTemp; - sim->edgeMode = saveData->edgeMode; - sim->legacy_enable = saveData->legacyEnable; - sim->water_equal_test = saveData->waterEEnabled; - sim->aheat_enable = saveData->aheatEnable; - if (saveData->gravityEnable && !sim->grav->IsEnabled()) + // we don't notify listeners because we'll get a new save soon anyway + return std::move(currentSave); +} + +void GameModel::SaveToSimParameters(const GameSave &saveData) +{ + SetPaused(saveData.paused | GetPaused()); + sim->gravityMode = saveData.gravityMode; + sim->customGravityX = saveData.customGravityX; + sim->customGravityY = saveData.customGravityY; + sim->air->airMode = saveData.airMode; + sim->air->ambientAirTemp = saveData.ambientAirTemp; + sim->edgeMode = saveData.edgeMode; + sim->legacy_enable = saveData.legacyEnable; + sim->water_equal_test = saveData.waterEEnabled; + sim->aheat_enable = saveData.aheatEnable; + if (saveData.gravityEnable && !sim->grav->IsEnabled()) { sim->grav->start_grav_async(); } - else if (!saveData->gravityEnable && sim->grav->IsEnabled()) + else if (!saveData.gravityEnable && sim->grav->IsEnabled()) { sim->grav->stop_grav_async(); } - sim->frameCount = saveData->frameCount; - if (saveData->hasRngState) + sim->frameCount = saveData.frameCount; + if (saveData.hasRngState) { - sim->rng.state(saveData->rngState); + sim->rng.state(saveData.rngState); } else { sim->rng = RNG(); } - sim->ensureDeterminism = saveData->ensureDeterminism; + sim->ensureDeterminism = saveData.ensureDeterminism; } -void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure) +void GameModel::SetSave(std::unique_ptr newSave, bool invertIncludePressure) { - if(currentSave != newSave) - { - delete currentSave; - if(newSave == NULL) - currentSave = NULL; - else - currentSave = new SaveInfo(*newSave); - } - delete currentFile; - currentFile = NULL; + currentSave = std::move(newSave); + currentFile.reset(); - if (newSave && newSave->GetGameSave()) + if (currentSave && currentSave->GetGameSave()) { - GameSave *saveData = newSave->GetGameSave(); - SaveToSimParameters(saveData); + auto *saveData = currentSave->GetGameSave(); + SaveToSimParameters(*saveData); sim->clear_sim(); ren->ClearAccumulation(); if (!sim->Load(saveData, !invertIncludePressure)) @@ -991,19 +981,23 @@ void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure) // Add in the correct info if (saveData->authors.size() == 0) { - saveData->authors["type"] = "save"; - saveData->authors["id"] = newSave->id; - saveData->authors["username"] = newSave->userName; - saveData->authors["title"] = newSave->name.ToUtf8(); - saveData->authors["description"] = newSave->Description.ToUtf8(); - saveData->authors["published"] = (int)newSave->Published; - saveData->authors["date"] = newSave->updatedDate; + auto gameSave = currentSave->TakeGameSave(); + gameSave->authors["type"] = "save"; + gameSave->authors["id"] = currentSave->id; + gameSave->authors["username"] = currentSave->userName; + gameSave->authors["title"] = currentSave->name.ToUtf8(); + gameSave->authors["description"] = currentSave->Description.ToUtf8(); + gameSave->authors["published"] = (int)currentSave->Published; + gameSave->authors["date"] = currentSave->updatedDate; + currentSave->SetGameSave(std::move(gameSave)); } // This save was probably just created, and we didn't know the ID when creating it // Update with the proper ID else if (saveData->authors.get("id", -1) == 0 || saveData->authors.get("id", -1) == -1) { - saveData->authors["id"] = newSave->id; + auto gameSave = currentSave->TakeGameSave(); + gameSave->authors["id"] = currentSave->id; + currentSave->SetGameSave(std::move(gameSave)); } Client::Ref().OverwriteAuthorInfo(saveData->authors); } @@ -1012,28 +1006,26 @@ void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure) UpdateQuickOptions(); } -SaveFile * GameModel::GetSaveFile() +const SaveFile *GameModel::GetSaveFile() const { - return currentFile; + return currentFile.get(); } -void GameModel::SetSaveFile(SaveFile * newSave, bool invertIncludePressure) +std::unique_ptr GameModel::TakeSaveFile() { - if(currentFile != newSave) - { - delete currentFile; - if(newSave == NULL) - currentFile = NULL; - else - currentFile = new SaveFile(*newSave); - } - delete currentSave; - currentSave = NULL; + // we don't notify listeners because we'll get a new save soon anyway + return std::move(currentFile); +} - if (newSave && newSave->GetGameSave()) +void GameModel::SetSaveFile(std::unique_ptr newSave, bool invertIncludePressure) +{ + currentFile = std::move(newSave); + currentSave.reset(); + + if (currentFile && currentFile->GetGameSave()) { - GameSave *saveData = newSave->GetGameSave(); - SaveToSimParameters(saveData); + auto *saveData = currentFile->GetGameSave(); + SaveToSimParameters(*saveData); sim->clear_sim(); ren->ClearAccumulation(); if (!sim->Load(saveData, !invertIncludePressure)) @@ -1342,33 +1334,31 @@ void GameModel::ClearSimulation() UpdateQuickOptions(); } -void GameModel::SetPlaceSave(GameSave * save) +void GameModel::SetPlaceSave(std::unique_ptr save) { - if (save != placeSave) - { - delete placeSave; - if (save) - placeSave = new GameSave(*save); - else - placeSave = NULL; - } + placeSave = std::move(save); notifyPlaceSaveChanged(); } -void GameModel::SetClipboard(GameSave * save) +void GameModel::SetClipboard(std::unique_ptr save) { - delete clipboard; - clipboard = save; + clipboard = std::move(save); } -GameSave * GameModel::GetClipboard() +const GameSave *GameModel::GetClipboard() const { - return clipboard; + return clipboard.get(); } -GameSave * GameModel::GetPlaceSave() +const GameSave *GameModel::GetPlaceSave() const { - return placeSave; + return placeSave.get(); +} + +std::unique_ptr GameModel::TakePlaceSave() +{ + // we don't notify listeners because we'll get a new save soon anyway + return std::move(placeSave); } void GameModel::Log(String message, bool printToFile) diff --git a/src/gui/game/GameModel.h b/src/gui/game/GameModel.h index 726d39b9b..d5b49598b 100644 --- a/src/gui/game/GameModel.h +++ b/src/gui/game/GameModel.h @@ -44,8 +44,8 @@ private: std::vector notifications; //int clipboardSize; //unsigned char * clipboardData; - GameSave * clipboard; - GameSave * placeSave; + std::unique_ptr clipboard; + std::unique_ptr placeSave; std::deque consoleLog; std::vector observers; std::vector toolList; @@ -62,8 +62,8 @@ private: int activeMenu; int currentBrush; std::vector> brushList; - SaveInfo * currentSave; - SaveFile * currentFile; + std::unique_ptr currentSave; + std::unique_ptr currentFile; Tool * lastTool; Tool ** activeTools; Tool * decoToolset[4]; @@ -115,7 +115,7 @@ private: void notifyQuickOptionsChanged(); void notifyLastToolChanged(); - void SaveToSimParameters(const GameSave *saveData); + void SaveToSimParameters(const GameSave &saveData); public: GameModel(); @@ -184,10 +184,12 @@ public: void SetBrushID(int i); void SetVote(int direction); - SaveInfo * GetSave(); - SaveFile * GetSaveFile(); - void SetSave(SaveInfo * newSave, bool invertIncludePressure); - void SetSaveFile(SaveFile * newSave, bool invertIncludePressure); + SaveInfo *GetSave(); // non-owning + std::unique_ptr TakeSave(); + const SaveFile *GetSaveFile() const; + std::unique_ptr TakeSaveFile(); + void SetSave(std::unique_ptr newSave, bool invertIncludePressure); + void SetSaveFile(std::unique_ptr newSave, bool invertIncludePressure); void AddObserver(GameView * observer); void SetPaused(bool pauseState); @@ -223,12 +225,13 @@ public: ui::Point AdjustZoomCoords(ui::Point position); void SetZoomWindowPosition(ui::Point position); ui::Point GetZoomWindowPosition(); - void SetClipboard(GameSave * save); - void SetPlaceSave(GameSave * save); + void SetClipboard(std::unique_ptr save); + void SetPlaceSave(std::unique_ptr save); void Log(String message, bool printToFile); std::deque GetLog(); - GameSave * GetClipboard(); - GameSave * GetPlaceSave(); + const GameSave *GetClipboard() const; + const GameSave *GetPlaceSave() const; + std::unique_ptr TakePlaceSave(); bool GetMouseClickRequired(); void SetMouseClickRequired(bool mouseClickRequired); bool GetIncludePressure(); diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index 948eb6588..da9ca1caa 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -17,6 +17,7 @@ #include "client/SaveInfo.h" #include "client/SaveFile.h" #include "client/Client.h" +#include "client/GameSave.h" #include "common/platform/Platform.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" @@ -1542,11 +1543,10 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, auto &stampIDs = Client::Ref().GetStamps(); if (stampIDs.size()) { - SaveFile *saveFile = Client::Ref().GetStamp(stampIDs[0]); + auto saveFile = Client::Ref().GetStamp(stampIDs[0]); if (!saveFile || !saveFile->GetGameSave()) break; - c->LoadStamp(saveFile->GetGameSave()); - delete saveFile; + c->LoadStamp(saveFile->TakeGameSave()); selectPoint1 = selectPoint2 = mousePosition; isMouseDown = false; break; @@ -1641,7 +1641,7 @@ void GameView::OnFileDrop(ByteString filename) return; } - SaveFile *saveFile = Client::Ref().LoadSaveFile(filename); + auto saveFile = Client::Ref().LoadSaveFile(filename); if (!saveFile) return; if (saveFile->GetError().length()) @@ -1649,8 +1649,7 @@ void GameView::OnFileDrop(ByteString filename) new ErrorMessage("Error loading save", "Dropped save file could not be loaded: " + saveFile->GetError()); return; } - c->LoadSaveFile(saveFile); - delete saveFile; + c->LoadSaveFile(std::move(saveFile)); // hide the info text if it's not already hidden introText = 0; diff --git a/src/gui/interface/Panel.cpp b/src/gui/interface/Panel.cpp index 71d51e994..8bfdc395b 100644 --- a/src/gui/interface/Panel.cpp +++ b/src/gui/interface/Panel.cpp @@ -78,7 +78,9 @@ void Panel::Draw(const Point& screenPos) auto rect = RectSized(child->Position + ViewportPosition, child->Size); //check if the component is in the screen, draw if it is if (rect & Size.OriginRect()) + { child->Draw(screenPos + rect.TopLeft); + } } GetGraphics()->SwapClipRect(clip); // apply old cliprect diff --git a/src/gui/interface/SaveButton.cpp b/src/gui/interface/SaveButton.cpp index 7a5a73150..cf4cd6e0f 100644 --- a/src/gui/interface/SaveButton.cpp +++ b/src/gui/interface/SaveButton.cpp @@ -18,8 +18,6 @@ namespace ui { SaveButton::SaveButton(Point position, Point size) : Component(position, size), - file(nullptr), - save(nullptr), wantsDraw(false), triedThumbnail(false), isMouseInsideAuthor(false), @@ -33,9 +31,9 @@ SaveButton::SaveButton(Point position, Point size) : { } -SaveButton::SaveButton(Point position, Point size, SaveInfo * save_) : SaveButton(position, size) +SaveButton::SaveButton(Point position, Point size, SaveInfo *newSave /* non-owning */) : SaveButton(position, size) { - save = save_; + save = newSave; if(save) { name = save->name; @@ -94,9 +92,9 @@ SaveButton::SaveButton(Point position, Point size, SaveInfo * save_) : SaveButto } } -SaveButton::SaveButton(Point position, Point size, SaveFile * file_) : SaveButton(position, size) +SaveButton::SaveButton(Point position, Point size, SaveFile *newFile /* non-owning */) : SaveButton(position, size) { - file = file_; + file = newFile; if(file) { name = file->GetDisplayName(); @@ -115,8 +113,6 @@ SaveButton::~SaveButton() { thumbnailRenderer->Abandon(); } - delete save; - delete file; } void SaveButton::Tick(float dt) @@ -198,7 +194,7 @@ void SaveButton::Draw(const Point& screenPos) auto space = Size - Vec2{ 0, 21 }; g->BlendImage(tex->Data(), 255, RectSized(screenPos + ((save && save->id) ? ((space - thumbBoxSize) / 2 - Vec2{ 3, 0 }) : (space - thumbSize) / 2), tex->Size())); } - else if (file && !file->GetGameSave()) + else if (file && !file->LazyGetGameSave()) g->BlendText(screenPos + Vec2{ (Size.X-(Graphics::TextSize("Error loading save").X - 1))/2, (Size.Y-28)/2 }, "Error loading save", 0xB4B4B4_rgb .WithAlpha(255)); if(save) { diff --git a/src/gui/interface/SaveButton.h b/src/gui/interface/SaveButton.h index b3b04a4cc..9b95db19d 100644 --- a/src/gui/interface/SaveButton.h +++ b/src/gui/interface/SaveButton.h @@ -15,8 +15,8 @@ namespace ui { class SaveButton : public Component { - SaveFile * file; - SaveInfo * save; + SaveFile *file = nullptr; // non-owning + SaveInfo *save = nullptr; // non-owning std::unique_ptr thumbnail; ui::Point thumbSize = ui::Point(0, 0); String name; @@ -43,8 +43,8 @@ class SaveButton : public Component SaveButton(Point position, Point size); public: - SaveButton(Point position, Point size, SaveInfo * save); - SaveButton(Point position, Point size, SaveFile * file); + SaveButton(Point position, Point size, SaveInfo *newSave /* non-owning */); + SaveButton(Point position, Point size, SaveFile *newFile /* non-owning */); virtual ~SaveButton(); void OnMouseClick(int x, int y, unsigned int button) override; @@ -67,8 +67,8 @@ public: bool GetSelectable() { return selectable; } void SetShowVotes(bool showVotes_) { showVotes = showVotes_; } - SaveInfo * GetSave() { return save; } - SaveFile * GetSaveFile() { return file; } + const SaveInfo *GetSave() const { return save; } + const SaveFile *GetSaveFile() const { return file; } inline bool GetState() { return state; } void DoAction(); void DoAltAction(); diff --git a/src/gui/localbrowser/LocalBrowserController.cpp b/src/gui/localbrowser/LocalBrowserController.cpp index d19510c92..79674d58c 100644 --- a/src/gui/localbrowser/LocalBrowserController.cpp +++ b/src/gui/localbrowser/LocalBrowserController.cpp @@ -4,6 +4,8 @@ #include "LocalBrowserView.h" #include "client/Client.h" +#include "client/GameSave.h" +#include "client/SaveFile.h" #include "gui/dialogues/ConfirmPrompt.h" #include "tasks/TaskWindow.h" #include "tasks/Task.h" @@ -25,14 +27,14 @@ LocalBrowserController::LocalBrowserController(std::function onDone_): browserModel->UpdateSavesList(1); } -void LocalBrowserController::OpenSave(SaveFile * save) +void LocalBrowserController::OpenSave(int index) { - browserModel->SetSave(save); + browserModel->OpenSave(index); } -SaveFile * LocalBrowserController::GetSave() +std::unique_ptr LocalBrowserController::TakeSave() { - return browserModel->GetSave(); + return browserModel->TakeSave(); } void LocalBrowserController::RemoveSelected() @@ -105,7 +107,7 @@ void LocalBrowserController::SetPageRelative(int offset) void LocalBrowserController::Update() { - if(browserModel->GetSave()) + if (browserModel->GetSave()) { Exit(); } diff --git a/src/gui/localbrowser/LocalBrowserController.h b/src/gui/localbrowser/LocalBrowserController.h index 01a9d06f1..f6de05a6a 100644 --- a/src/gui/localbrowser/LocalBrowserController.h +++ b/src/gui/localbrowser/LocalBrowserController.h @@ -1,6 +1,7 @@ #pragma once #include "common/String.h" #include +#include class SaveFile; class LocalBrowserView; @@ -13,14 +14,14 @@ public: bool HasDone; LocalBrowserController(std::function onDone = nullptr); LocalBrowserView * GetView() {return browserView;} - SaveFile * GetSave(); + std::unique_ptr TakeSave(); void RemoveSelected(); void removeSelectedC(); void ClearSelection(); void Selected(ByteString stampID, bool selected); void RescanStamps(); void RefreshSavesList(); - void OpenSave(SaveFile * stamp); + void OpenSave(int index); bool GetMoveToFront(); void SetMoveToFront(bool move); void SetPage(int page); diff --git a/src/gui/localbrowser/LocalBrowserModel.cpp b/src/gui/localbrowser/LocalBrowserModel.cpp index 6aa32d7b2..627a0d33a 100644 --- a/src/gui/localbrowser/LocalBrowserModel.cpp +++ b/src/gui/localbrowser/LocalBrowserModel.cpp @@ -2,13 +2,13 @@ #include "LocalBrowserView.h" #include "client/Client.h" #include "client/SaveFile.h" +#include "client/GameSave.h" #include "common/tpt-minmax.h" #include constexpr auto pageSize = 20; LocalBrowserModel::LocalBrowserModel(): - stamp(NULL), currentPage(1), stampToFront(1) { @@ -16,9 +16,13 @@ LocalBrowserModel::LocalBrowserModel(): } -std::vector LocalBrowserModel::GetSavesList() +std::vector LocalBrowserModel::GetSavesList() // non-owning { - return savesList; + std::vector nonOwningSaveList; + std::transform(savesList.begin(), savesList.end(), std::back_inserter(nonOwningSaveList), [](auto &ptr) { + return ptr.get(); + }); + return nonOwningSaveList; } void LocalBrowserModel::AddObserver(LocalBrowserView * observer) @@ -45,15 +49,20 @@ void LocalBrowserModel::notifyPageChanged() } } -SaveFile * LocalBrowserModel::GetSave() +const SaveFile *LocalBrowserModel::GetSave() { - return stamp; + return stamp.get(); } -void LocalBrowserModel::SetSave(SaveFile * newStamp) +std::unique_ptr LocalBrowserModel::TakeSave() { - delete stamp; - stamp = new SaveFile(*newStamp); + return std::move(stamp); +} + +void LocalBrowserModel::OpenSave(int index) +{ + stamp = std::move(savesList[index]); + savesList.clear(); } bool LocalBrowserModel::GetMoveToFront() @@ -68,25 +77,19 @@ void LocalBrowserModel::SetMoveToFront(bool move) void LocalBrowserModel::UpdateSavesList(int pageNumber) { - std::vector tempSavesList = savesList; savesList.clear(); currentPage = pageNumber; notifyPageChanged(); notifySavesListChanged(); - //notifyStampsListChanged(); - /*for(int i = 0; i < tempSavesList.size(); i++) - { - delete tempSavesList[i]; - }*/ stampIDs = Client::Ref().GetStamps(); auto size = int(stampIDs.size()); for (int i = (currentPage - 1) * pageSize; i < size && i < currentPage * pageSize; i++) { - SaveFile * tempSave = Client::Ref().GetStamp(stampIDs[i]); + auto tempSave = Client::Ref().GetStamp(stampIDs[i]); if (tempSave) { - savesList.push_back(tempSave); + savesList.push_back(std::move(tempSave)); } } notifySavesListChanged(); @@ -131,8 +134,3 @@ void LocalBrowserModel::notifySelectedChanged() cObserver->NotifySelectedChanged(this); } } - -LocalBrowserModel::~LocalBrowserModel() { - delete stamp; -} - diff --git a/src/gui/localbrowser/LocalBrowserModel.h b/src/gui/localbrowser/LocalBrowserModel.h index 61d951d34..7dd9ae0d4 100644 --- a/src/gui/localbrowser/LocalBrowserModel.h +++ b/src/gui/localbrowser/LocalBrowserModel.h @@ -1,15 +1,16 @@ #pragma once #include "common/String.h" #include +#include class SaveFile; class LocalBrowserView; class LocalBrowserModel { std::vector selected; - SaveFile * stamp; + std::unique_ptr stamp; std::vector stampIDs; - std::vector savesList; + std::vector> savesList; std::vector observers; int currentPage; bool stampToFront; @@ -21,16 +22,16 @@ public: int GetPageCount(); int GetPageNum() { return currentPage; } void AddObserver(LocalBrowserView * observer); - std::vector GetSavesList(); + std::vector GetSavesList(); // non-owning void UpdateSavesList(int pageNumber); void RescanStamps(); - SaveFile * GetSave(); - void SetSave(SaveFile * newStamp); + const SaveFile *GetSave(); + std::unique_ptr TakeSave(); + void OpenSave(int index); bool GetMoveToFront(); void SetMoveToFront(bool move); std::vector GetSelected() { return selected; } void ClearSelected() { selected.clear(); notifySelectedChanged(); } void SelectSave(ByteString stampID); void DeselectSave(ByteString stampID); - virtual ~LocalBrowserModel(); }; diff --git a/src/gui/localbrowser/LocalBrowserView.cpp b/src/gui/localbrowser/LocalBrowserView.cpp index cb8d73b6d..99b181b07 100644 --- a/src/gui/localbrowser/LocalBrowserView.cpp +++ b/src/gui/localbrowser/LocalBrowserView.cpp @@ -118,7 +118,7 @@ void LocalBrowserView::NotifySavesListChanged(LocalBrowserModel * sender) int buttonWidth, buttonHeight, saveX = 0, saveY = 0, savesX = 5, savesY = 4, buttonPadding = 2; int buttonAreaWidth, buttonAreaHeight, buttonXOffset, buttonYOffset; - std::vector saves = sender->GetSavesList(); + auto saves = sender->GetSavesList(); // non-owning for (size_t i = 0; i < stampButtons.size(); i++) { RemoveComponent(stampButtons[i]); @@ -131,7 +131,7 @@ void LocalBrowserView::NotifySavesListChanged(LocalBrowserModel * sender) buttonAreaHeight = Size.Y - buttonYOffset - 18; buttonWidth = (buttonAreaWidth/savesX) - buttonPadding*2; buttonHeight = (buttonAreaHeight/savesY) - buttonPadding*2; - for (size_t i = 0; i < saves.size(); i++) + for (auto i = 0; i < int(saves.size()); i++) { if(saveX == savesX) { @@ -150,9 +150,9 @@ void LocalBrowserView::NotifySavesListChanged(LocalBrowserModel * sender) saves[i]); saveButton->SetSelectable(true); saveButton->SetActionCallback({ - [this, saveButton] { + [this, saveButton, i] { if (saveButton->GetSaveFile()) - c->OpenSave(saveButton->GetSaveFile()); + c->OpenSave(i); }, nullptr, nullptr, diff --git a/src/gui/preview/PreviewController.cpp b/src/gui/preview/PreviewController.cpp index 063a94c32..7f43d30ea 100644 --- a/src/gui/preview/PreviewController.cpp +++ b/src/gui/preview/PreviewController.cpp @@ -5,6 +5,7 @@ #include "PreviewView.h" #include "client/Client.h" #include "client/SaveInfo.h" +#include "client/GameSave.h" #include "common/platform/Platform.h" #include "gui/dialogues/ErrorMessage.h" #include "gui/dialogues/InformationMessage.h" @@ -84,11 +85,16 @@ void PreviewController::NotifyAuthUserChanged(Client * sender) previewModel->SetCommentBoxEnabled(sender->GetAuthUser().UserID); } -SaveInfo * PreviewController::GetSaveInfo() +const SaveInfo *PreviewController::GetSaveInfo() const { return previewModel->GetSaveInfo(); } +std::unique_ptr PreviewController::TakeSaveInfo() +{ + return previewModel->TakeSaveInfo(); +} + bool PreviewController::GetDoOpen() { return previewModel->GetDoOpen(); diff --git a/src/gui/preview/PreviewController.h b/src/gui/preview/PreviewController.h index 4831d9cfb..a6c0fd69d 100644 --- a/src/gui/preview/PreviewController.h +++ b/src/gui/preview/PreviewController.h @@ -1,6 +1,7 @@ #pragma once #include "client/ClientListener.h" #include +#include class SaveInfo; class LoginController; @@ -24,7 +25,8 @@ public: void Report(String message); void ShowLogin(); bool GetDoOpen(); - SaveInfo * GetSaveInfo(); + const SaveInfo *GetSaveInfo() const; + std::unique_ptr TakeSaveInfo(); PreviewView * GetView() { return previewView; } void Update(); void FavouriteSave(); diff --git a/src/gui/preview/PreviewModel.cpp b/src/gui/preview/PreviewModel.cpp index d4c0065f9..b2cc81ca4 100644 --- a/src/gui/preview/PreviewModel.cpp +++ b/src/gui/preview/PreviewModel.cpp @@ -15,7 +15,6 @@ PreviewModel::PreviewModel(): doOpen(false), canOpen(true), - saveInfo(NULL), saveData(NULL), saveComments(NULL), commentBoxEnabled(false), @@ -27,7 +26,6 @@ PreviewModel::PreviewModel(): PreviewModel::~PreviewModel() { - delete saveInfo; delete saveData; ClearComments(); } @@ -65,11 +63,7 @@ void PreviewModel::UpdateSave(int saveID, int saveDate) this->saveID = saveID; this->saveDate = saveDate; - if (saveInfo) - { - delete saveInfo; - saveInfo = NULL; - } + saveInfo.reset(); if (saveData) { delete saveData; @@ -120,9 +114,14 @@ bool PreviewModel::GetCanOpen() return canOpen; } -SaveInfo * PreviewModel::GetSaveInfo() +const SaveInfo *PreviewModel::GetSaveInfo() const { - return saveInfo; + return saveInfo.get(); +} + +std::unique_ptr PreviewModel::TakeSaveInfo() +{ + return std::move(saveInfo); } int PreviewModel::GetCommentsPageNum() @@ -173,10 +172,10 @@ void PreviewModel::OnSaveReady() commentsTotal = saveInfo->Comments; try { - GameSave *gameSave = new GameSave(*saveData); + auto gameSave = std::make_unique(*saveData); if (gameSave->fromNewerVersion) new ErrorMessage("This save is from a newer version", "Please update TPT in game or at https://powdertoy.co.uk"); - saveInfo->SetGameSave(gameSave); + saveInfo->SetGameSave(std::move(gameSave)); } catch(ParseException &e) { @@ -204,7 +203,7 @@ void PreviewModel::ClearComments() bool PreviewModel::ParseSaveInfo(ByteString &saveInfoResponse) { - delete saveInfo; + saveInfo.reset(); try // how does this differ from Client::GetSave? { @@ -232,13 +231,13 @@ bool PreviewModel::ParseSaveInfo(ByteString &saveInfoResponse) for (Json::UInt j = 0; j < tagsArray.size(); j++) tempTags.push_back(tagsArray[j].asString()); - saveInfo = new SaveInfo(tempID, tempCreatedDate, tempUpdatedDate, tempScoreUp, + auto newSaveInfo = std::make_unique(tempID, tempCreatedDate, tempUpdatedDate, tempScoreUp, tempScoreDown, tempMyScore, tempUsername, tempName, tempDescription, tempPublished, tempTags); - saveInfo->Comments = tempComments; - saveInfo->Favourite = tempFavourite; - saveInfo->Views = tempViews; - saveInfo->Version = tempVersion; + newSaveInfo->Comments = tempComments; + newSaveInfo->Favourite = tempFavourite; + newSaveInfo->Views = tempViews; + newSaveInfo->Version = tempVersion; // This is a workaround for a bug on the TPT server where the wrong 404 save is returned // Redownload the .cps file for a fixed version of the 404 save @@ -249,13 +248,13 @@ bool PreviewModel::ParseSaveInfo(ByteString &saveInfoResponse) saveDataDownload = std::make_unique(ByteString::Build(STATICSCHEME, STATICSERVER, "/2157797.cps")); saveDataDownload->Start(); } - return true; + saveInfo = std::move(newSaveInfo); } catch (std::exception &e) { - saveInfo = NULL; return false; } + return true; } bool PreviewModel::ParseComments(ByteString &commentsResponse) diff --git a/src/gui/preview/PreviewModel.h b/src/gui/preview/PreviewModel.h index 58acc2b2d..709afa366 100644 --- a/src/gui/preview/PreviewModel.h +++ b/src/gui/preview/PreviewModel.h @@ -16,7 +16,7 @@ class PreviewModel bool doOpen; bool canOpen; std::vector observers; - SaveInfo * saveInfo; + std::unique_ptr saveInfo; std::vector * saveData; std::vector * saveComments; void notifySaveChanged(); @@ -39,7 +39,8 @@ public: PreviewModel(); ~PreviewModel(); - SaveInfo * GetSaveInfo(); + const SaveInfo *GetSaveInfo() const; + std::unique_ptr TakeSaveInfo(); std::vector * GetComments(); bool GetCommentBoxEnabled(); diff --git a/src/gui/preview/PreviewView.cpp b/src/gui/preview/PreviewView.cpp index 07d606340..a1923164c 100644 --- a/src/gui/preview/PreviewView.cpp +++ b/src/gui/preview/PreviewView.cpp @@ -415,7 +415,7 @@ void PreviewView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ct void PreviewView::NotifySaveChanged(PreviewModel * sender) { - SaveInfo * save = sender->GetSaveInfo(); + auto *save = sender->GetSaveInfo(); savePreview = nullptr; if(save) { diff --git a/src/gui/save/LocalSaveActivity.cpp b/src/gui/save/LocalSaveActivity.cpp index 603861ec9..46ece246e 100644 --- a/src/gui/save/LocalSaveActivity.cpp +++ b/src/gui/save/LocalSaveActivity.cpp @@ -15,9 +15,9 @@ #include "Config.h" -LocalSaveActivity::LocalSaveActivity(SaveFile save, OnSaved onSaved_) : +LocalSaveActivity::LocalSaveActivity(std::unique_ptr newSave, OnSaved onSaved_) : WindowActivity(ui::Point(-1, -1), ui::Point(220, 200)), - save(save), + save(std::move(newSave)), thumbnailRenderer(nullptr), onSaved(onSaved_) { @@ -27,7 +27,7 @@ LocalSaveActivity::LocalSaveActivity(SaveFile save, OnSaved onSaved_) : titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; AddComponent(titleLabel); - filenameField = new ui::Textbox(ui::Point(8, 25), ui::Point(Size.X-16, 16), save.GetDisplayName(), "[filename]"); + filenameField = new ui::Textbox(ui::Point(8, 25), ui::Point(Size.X-16, 16), save->GetDisplayName(), "[filename]"); filenameField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; filenameField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; AddComponent(filenameField); @@ -53,9 +53,9 @@ LocalSaveActivity::LocalSaveActivity(SaveFile save, OnSaved onSaved_) : AddComponent(okayButton); SetOkayButton(okayButton); - if(save.GetGameSave()) + if(save->GetGameSave()) { - thumbnailRenderer = new ThumbnailRendererTask(*save.GetGameSave(), Size - Vec2(16, 16), true, false); + thumbnailRenderer = new ThumbnailRendererTask(*save->GetGameSave(), Size - Vec2(16, 16), true, false); thumbnailRenderer->Start(); } } @@ -82,8 +82,8 @@ void LocalSaveActivity::Save() else if (filenameField->GetText().length()) { ByteString finalFilename = ByteString::Build(LOCAL_SAVE_DIR, PATH_SEP_CHAR, filenameField->GetText().ToUtf8(), ".cps"); - save.SetDisplayName(filenameField->GetText()); - save.SetFileName(finalFilename); + save->SetDisplayName(filenameField->GetText()); + save->SetFileName(finalFilename); if (Platform::FileExists(finalFilename)) { new ConfirmPrompt("Overwrite file", "Are you sure you wish to overwrite\n"+finalFilename.FromUtf8(), { [this, finalFilename] { @@ -104,15 +104,18 @@ void LocalSaveActivity::Save() void LocalSaveActivity::saveWrite(ByteString finalFilename) { Platform::MakeDirectory(LOCAL_SAVE_DIR); - GameSave *gameSave = save.GetGameSave(); Json::Value localSaveInfo; localSaveInfo["type"] = "localsave"; localSaveInfo["username"] = Client::Ref().GetAuthUser().Username; localSaveInfo["title"] = finalFilename; localSaveInfo["date"] = (Json::Value::UInt64)time(NULL); Client::Ref().SaveAuthorInfo(&localSaveInfo); - gameSave->authors = localSaveInfo; - auto [ fromNewerVersion, saveData ] = gameSave->Serialise(); + { + auto gameSave = save->TakeGameSave(); + gameSave->authors = localSaveInfo; + save->SetGameSave(std::move(gameSave)); + } + auto [ fromNewerVersion, saveData ] = save->GetGameSave()->Serialise(); (void)fromNewerVersion; if (saveData.size() == 0) new ErrorMessage("Error", "Unable to serialize game data."); @@ -122,7 +125,7 @@ void LocalSaveActivity::saveWrite(ByteString finalFilename) { if (onSaved) { - onSaved(&save); + onSaved(std::move(save)); } Exit(); } diff --git a/src/gui/save/LocalSaveActivity.h b/src/gui/save/LocalSaveActivity.h index cb8688de4..8c8b06f65 100644 --- a/src/gui/save/LocalSaveActivity.h +++ b/src/gui/save/LocalSaveActivity.h @@ -22,19 +22,19 @@ class ThumbnailRendererTask; class LocalSaveActivity: public WindowActivity { - using OnSaved = std::function; + using OnSaved = std::function)>; std::unique_ptr>> saveToDiskImage = format::PixelsFromPNG( std::vector(save_local_png, save_local_png + save_local_png_size) ); - SaveFile save; + std::unique_ptr save; ThumbnailRendererTask *thumbnailRenderer; std::unique_ptr thumbnail; ui::Textbox * filenameField; OnSaved onSaved; public: - LocalSaveActivity(SaveFile save, OnSaved onSaved = nullptr); + LocalSaveActivity(std::unique_ptr newSave, OnSaved onSaved = nullptr); void saveWrite(ByteString finalFilename); void Save(); void OnDraw() override; diff --git a/src/gui/save/ServerSaveActivity.cpp b/src/gui/save/ServerSaveActivity.cpp index e44c9186f..c3dab8d99 100644 --- a/src/gui/save/ServerSaveActivity.cpp +++ b/src/gui/save/ServerSaveActivity.cpp @@ -21,7 +21,7 @@ class SaveUploadTask: public Task { - SaveInfo save; + SaveInfo &save; void before() override { @@ -40,22 +40,17 @@ class SaveUploadTask: public Task } public: - SaveInfo GetSave() - { - return save; - } - - SaveUploadTask(SaveInfo save): - save(save) + SaveUploadTask(SaveInfo &newSave): + save(newSave) { } }; -ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) : +ServerSaveActivity::ServerSaveActivity(std::unique_ptr newSave, OnUploaded onUploaded_) : WindowActivity(ui::Point(-1, -1), ui::Point(440, 200)), thumbnailRenderer(nullptr), - save(save), + save(std::move(newSave)), onUploaded(onUploaded_), saveUploadTask(NULL) { @@ -64,7 +59,7 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) : titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; AddComponent(titleLabel); - CheckName(save.GetName()); //set titleLabel text + CheckName(save->GetName()); //set titleLabel text ui::Label * previewLabel = new ui::Label(ui::Point((Size.X/2)+4, 5), ui::Point((Size.X/2)-8, 16), "Preview:"); previewLabel->SetTextColour(style::Colour::InformationTitle); @@ -72,14 +67,14 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) : previewLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; AddComponent(previewLabel); - nameField = new ui::Textbox(ui::Point(8, 25), ui::Point((Size.X/2)-16, 16), save.GetName(), "[save name]"); + nameField = new ui::Textbox(ui::Point(8, 25), ui::Point((Size.X/2)-16, 16), save->GetName(), "[save name]"); nameField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; nameField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; nameField->SetActionCallback({ [this] { CheckName(nameField->GetText()); } }); AddComponent(nameField); FocusComponent(nameField); - descriptionField = new ui::Textbox(ui::Point(8, 65), ui::Point((Size.X/2)-16, Size.Y-(65+16+4)), save.GetDescription(), "[save description]"); + descriptionField = new ui::Textbox(ui::Point(8, 65), ui::Point((Size.X/2)-16, Size.Y-(65+16+4)), save->GetDescription(), "[save description]"); descriptionField->SetMultiline(true); descriptionField->SetLimit(254); descriptionField->Appearance.VerticalAlign = ui::Appearance::AlignTop; @@ -87,7 +82,7 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) : AddComponent(descriptionField); publishedCheckbox = new ui::Checkbox(ui::Point(8, 45), ui::Point((Size.X/2)-80, 16), "Publish", ""); - if(Client::Ref().GetAuthUser().Username != save.GetUserName()) + if(Client::Ref().GetAuthUser().Username != save->GetUserName()) { //Save is not owned by the user, disable by default publishedCheckbox->SetChecked(false); @@ -95,12 +90,12 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) : else { //Save belongs to the current user, use published state already set - publishedCheckbox->SetChecked(save.GetPublished()); + publishedCheckbox->SetChecked(save->GetPublished()); } AddComponent(publishedCheckbox); pausedCheckbox = new ui::Checkbox(ui::Point(160, 45), ui::Point(55, 16), "Paused", ""); - pausedCheckbox->SetChecked(save.GetGameSave()->paused); + pausedCheckbox->SetChecked(save->GetGameSave()->paused); AddComponent(pausedCheckbox); ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point((Size.X/2)-75, 16), "Cancel"); @@ -141,17 +136,17 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, OnUploaded onUploaded_) : } }); AddComponent(RulesButton); - if (save.GetGameSave()) + if (save->GetGameSave()) { - thumbnailRenderer = new ThumbnailRendererTask(*save.GetGameSave(), Size / 2 - Vec2(16, 16), false, true); + thumbnailRenderer = new ThumbnailRendererTask(*save->GetGameSave(), Size / 2 - Vec2(16, 16), false, true); thumbnailRenderer->Start(); } } -ServerSaveActivity::ServerSaveActivity(SaveInfo save, bool saveNow, OnUploaded onUploaded_) : +ServerSaveActivity::ServerSaveActivity(std::unique_ptr newSave, bool saveNow, OnUploaded onUploaded_) : WindowActivity(ui::Point(-1, -1), ui::Point(200, 50)), thumbnailRenderer(nullptr), - save(save), + save(std::move(newSave)), onUploaded(onUploaded_), saveUploadTask(NULL) { @@ -163,7 +158,7 @@ ServerSaveActivity::ServerSaveActivity(SaveInfo save, bool saveNow, OnUploaded o AddAuthorInfo(); - saveUploadTask = new SaveUploadTask(this->save); + saveUploadTask = new SaveUploadTask(*this->save); saveUploadTask->AddTaskListener(this); saveUploadTask->Start(); } @@ -179,7 +174,7 @@ void ServerSaveActivity::NotifyDone(Task * task) { if (onUploaded) { - onUploaded(save); + onUploaded(std::move(save)); } Exit(); } @@ -189,9 +184,9 @@ void ServerSaveActivity::Save() { if(nameField->GetText().length()) { - if(Client::Ref().GetAuthUser().Username != save.GetUserName() && publishedCheckbox->GetChecked()) + if(Client::Ref().GetAuthUser().Username != save->GetUserName() && publishedCheckbox->GetChecked()) { - new ConfirmPrompt("Publish", "This save was created by " + save.GetUserName().FromUtf8() + ", you're about to publish this under your own name; If you haven't been given permission by the author to do so, please uncheck the publish box, otherwise continue", { [this] { + new ConfirmPrompt("Publish", "This save was created by " + save->GetUserName().FromUtf8() + ", you're about to publish this under your own name; If you haven't been given permission by the author to do so, please uncheck the publish box, otherwise continue", { [this] { Exit(); saveUpload(); } }); @@ -212,34 +207,42 @@ void ServerSaveActivity::AddAuthorInfo() { Json::Value serverSaveInfo; serverSaveInfo["type"] = "save"; - serverSaveInfo["id"] = save.GetID(); + serverSaveInfo["id"] = save->GetID(); serverSaveInfo["username"] = Client::Ref().GetAuthUser().Username; - serverSaveInfo["title"] = save.GetName().ToUtf8(); - serverSaveInfo["description"] = save.GetDescription().ToUtf8(); - serverSaveInfo["published"] = (int)save.GetPublished(); + serverSaveInfo["title"] = save->GetName().ToUtf8(); + serverSaveInfo["description"] = save->GetDescription().ToUtf8(); + serverSaveInfo["published"] = (int)save->GetPublished(); serverSaveInfo["date"] = (Json::Value::UInt64)time(NULL); Client::Ref().SaveAuthorInfo(&serverSaveInfo); - save.GetGameSave()->authors = serverSaveInfo; + { + auto gameSave = save->TakeGameSave(); + gameSave->authors = serverSaveInfo; + save->SetGameSave(std::move(gameSave)); + } } void ServerSaveActivity::saveUpload() { - save.SetName(nameField->GetText()); - save.SetDescription(descriptionField->GetText()); - save.SetPublished(publishedCheckbox->GetChecked()); - save.SetUserName(Client::Ref().GetAuthUser().Username); - save.SetID(0); - save.GetGameSave()->paused = pausedCheckbox->GetChecked(); + save->SetName(nameField->GetText()); + save->SetDescription(descriptionField->GetText()); + save->SetPublished(publishedCheckbox->GetChecked()); + save->SetUserName(Client::Ref().GetAuthUser().Username); + save->SetID(0); + { + auto gameSave = save->TakeGameSave(); + gameSave->paused = pausedCheckbox->GetChecked(); + save->SetGameSave(std::move(gameSave)); + } AddAuthorInfo(); - if(Client::Ref().UploadSave(save) != RequestOkay) + if(Client::Ref().UploadSave(*save) != RequestOkay) { new ErrorMessage("Error", "Upload failed with error:\n"+Client::Ref().GetLastError()); } else if (onUploaded) { - new SaveIDMessage(save.GetID()); - onUploaded(save); + new SaveIDMessage(save->GetID()); + onUploaded(std::move(save)); } } @@ -343,7 +346,7 @@ void ServerSaveActivity::ShowRules() void ServerSaveActivity::CheckName(String newname) { - if (newname.length() && newname == save.GetName() && save.GetUserName() == Client::Ref().GetAuthUser().Username) + if (newname.length() && newname == save->GetName() && save->GetUserName() == Client::Ref().GetAuthUser().Username) titleLabel->SetText("Modify simulation properties:"); else titleLabel->SetText("Upload new simulation:"); diff --git a/src/gui/save/ServerSaveActivity.h b/src/gui/save/ServerSaveActivity.h index 944b05811..833cf3122 100644 --- a/src/gui/save/ServerSaveActivity.h +++ b/src/gui/save/ServerSaveActivity.h @@ -25,14 +25,14 @@ class Task; class VideoBuffer; class ServerSaveActivity: public WindowActivity, public TaskListener { - using OnUploaded = std::function; + using OnUploaded = std::function)>; std::unique_ptr>> saveToServerImage = format::PixelsFromPNG( std::vector(save_online_png, save_online_png + save_online_png_size) ); public: - ServerSaveActivity(SaveInfo save, OnUploaded onUploaded); - ServerSaveActivity(SaveInfo save, bool saveNow, OnUploaded onUploaded); + ServerSaveActivity(std::unique_ptr newSave, OnUploaded onUploaded); + ServerSaveActivity(std::unique_ptr newSave, bool saveNow, OnUploaded onUploaded); void saveUpload(); void Save(); virtual void Exit() override; @@ -47,7 +47,7 @@ protected: void NotifyDone(Task * task) override; ThumbnailRendererTask *thumbnailRenderer; std::unique_ptr thumbnail; - SaveInfo save; + std::unique_ptr save; private: OnUploaded onUploaded; protected: diff --git a/src/gui/search/SearchController.cpp b/src/gui/search/SearchController.cpp index ffb96007a..0e732a558 100644 --- a/src/gui/search/SearchController.cpp +++ b/src/gui/search/SearchController.cpp @@ -5,6 +5,8 @@ #include "SearchView.h" #include "client/Client.h" +#include "client/SaveInfo.h" +#include "client/GameSave.h" #include "common/platform/Platform.h" #include "common/tpt-minmax.h" #include "graphics/Graphics.h" @@ -34,14 +36,14 @@ SearchController::SearchController(std::function onDone_): onDone = onDone_; } -SaveInfo * SearchController::GetLoadedSave() +const SaveInfo *SearchController::GetLoadedSave() const { return searchModel->GetLoadedSave(); } -void SearchController::ReleaseLoadedSave() +std::unique_ptr SearchController::TakeLoadedSave() { - searchModel->SetLoadedSave(NULL); + return searchModel->TakeLoadedSave(); } void SearchController::Update() @@ -194,11 +196,11 @@ void SearchController::OpenSaveDone() { if (activePreview->GetDoOpen() && activePreview->GetSaveInfo()) { - searchModel->SetLoadedSave(activePreview->GetSaveInfo()); + searchModel->SetLoadedSave(activePreview->TakeSaveInfo()); } else { - searchModel->SetLoadedSave(NULL); + searchModel->SetLoadedSave(nullptr); } } diff --git a/src/gui/search/SearchController.h b/src/gui/search/SearchController.h index e110bba6a..78cbb297d 100644 --- a/src/gui/search/SearchController.h +++ b/src/gui/search/SearchController.h @@ -1,6 +1,7 @@ #pragma once #include "common/String.h" #include +#include class SaveInfo; class PreviewController; @@ -48,6 +49,6 @@ public: void RemoveSelected(); void UnpublishSelected(bool publish); void FavouriteSelected(); - void ReleaseLoadedSave(); - SaveInfo * GetLoadedSave(); + const SaveInfo *GetLoadedSave() const; + std::unique_ptr TakeLoadedSave(); }; diff --git a/src/gui/search/SearchModel.cpp b/src/gui/search/SearchModel.cpp index af0b4f35d..9f7f2a8d8 100644 --- a/src/gui/search/SearchModel.cpp +++ b/src/gui/search/SearchModel.cpp @@ -2,13 +2,13 @@ #include "SearchView.h" #include "Format.h" #include "client/SaveInfo.h" +#include "client/GameSave.h" #include "client/Client.h" #include "common/tpt-minmax.h" #include #include SearchModel::SearchModel(): - loadedSave(NULL), currentSort("best"), currentPage(1), resultCount(0), @@ -60,9 +60,9 @@ void SearchModel::BeginSearchSaves(int start, int count, String query, ByteStrin searchSaves->Start(); } -std::vector SearchModel::EndSearchSaves() +std::vector> SearchModel::EndSearchSaves() { - std::vector saveArray; + std::vector> saveArray; auto [ dataStatus, data ] = searchSaves->Finish(); searchSaves.reset(); auto &client = Client::Ref(); @@ -88,10 +88,10 @@ std::vector SearchModel::EndSearchSaves() String tempName = ByteString(savesArray[j]["Name"].asString()).FromUtf8(); int tempVersion = savesArray[j]["Version"].asInt(); bool tempPublished = savesArray[j]["Published"].asBool(); - SaveInfo * tempSaveInfo = new SaveInfo(tempID, tempCreatedDate, tempUpdatedDate, tempScoreUp, tempScoreDown, tempUsername, tempName); + auto tempSaveInfo = std::make_unique(tempID, tempCreatedDate, tempUpdatedDate, tempScoreUp, tempScoreDown, tempUsername, tempName); tempSaveInfo->Version = tempVersion; tempSaveInfo->SetPublished(tempPublished); - saveArray.push_back(tempSaveInfo); + saveArray.push_back(std::move(tempSaveInfo)); } } catch (std::exception &e) @@ -193,27 +193,28 @@ bool SearchModel::UpdateSaveList(int pageNumber, String query) return false; } -void SearchModel::SetLoadedSave(SaveInfo * save) +void SearchModel::SetLoadedSave(std::unique_ptr save) { - if(loadedSave != save && loadedSave) - delete loadedSave; - if(save) - { - loadedSave = new SaveInfo(*save); - } - else - { - loadedSave = NULL; - } + loadedSave = std::move(save); } -SaveInfo * SearchModel::GetLoadedSave(){ - return loadedSave; +const SaveInfo *SearchModel::GetLoadedSave() const +{ + return loadedSave.get(); } -std::vector SearchModel::GetSaveList() +std::unique_ptr SearchModel::TakeLoadedSave() { - return saveList; + return std::move(loadedSave); +} + +std::vector SearchModel::GetSaveList() // non-owning +{ + std::vector nonOwningSaveList; + std::transform(saveList.begin(), saveList.end(), std::back_inserter(nonOwningSaveList), [](auto &ptr) { + return ptr.get(); + }); + return nonOwningSaveList; } std::vector > SearchModel::GetTagList() @@ -360,11 +361,6 @@ void SearchModel::notifySelectedChanged() } } -SearchModel::~SearchModel() -{ - delete loadedSave; -} - int SearchModel::GetPageCount() { if (!showOwn && !showFavourite && currentSort == "best" && lastQuery == "") diff --git a/src/gui/search/SearchModel.h b/src/gui/search/SearchModel.h index 8786f5c95..ef440b46b 100644 --- a/src/gui/search/SearchModel.h +++ b/src/gui/search/SearchModel.h @@ -13,19 +13,19 @@ class SearchModel private: std::unique_ptr searchSaves; void BeginSearchSaves(int start, int count, String query, ByteString sort, ByteString category); - std::vector EndSearchSaves(); + std::vector> EndSearchSaves(); void BeginGetTags(int start, int count, String query); std::vector> EndGetTags(); std::unique_ptr getTags; - SaveInfo * loadedSave; + std::unique_ptr loadedSave; ByteString currentSort; String lastQuery; String lastError; std::vector selected; std::vector observers; - std::vector saveList; + std::vector> saveList; std::vector > tagList; int currentPage; int resultCount; @@ -44,13 +44,12 @@ private: bool saveListLoaded = false; public: SearchModel(); - ~SearchModel(); void SetShowTags(bool show); bool GetShowTags(); void AddObserver(SearchView * observer); bool UpdateSaveList(int pageNumber, String query); - std::vector GetSaveList(); + std::vector GetSaveList(); // non-owning std::vector > GetTagList(); String GetLastError() { return lastError; } int GetPageCount(); @@ -62,8 +61,9 @@ public: bool GetShowOwn() { return showOwn; } void SetShowFavourite(bool show) { if(show!=showFavourite && !searchSaves) { showFavourite = show; } notifyShowFavouriteChanged(); } bool GetShowFavourite() { return showFavourite; } - void SetLoadedSave(SaveInfo * save); - SaveInfo * GetLoadedSave(); + void SetLoadedSave(std::unique_ptr save); + const SaveInfo *GetLoadedSave() const; + std::unique_ptr TakeLoadedSave(); bool GetSavesLoaded() { return saveListLoaded; } std::vector GetSelected() { return selected; } void ClearSelected() { selected.clear(); notifySelectedChanged(); } diff --git a/src/gui/search/SearchView.cpp b/src/gui/search/SearchView.cpp index 95f3237a1..df9a739cf 100644 --- a/src/gui/search/SearchView.cpp +++ b/src/gui/search/SearchView.cpp @@ -456,7 +456,7 @@ void SearchView::NotifySaveListChanged(SearchModel * sender) int buttonWidth, buttonHeight, saveX = 0, saveY = 0, savesX = 5, savesY = 4, buttonPadding = 1; int buttonAreaWidth, buttonAreaHeight, buttonXOffset, buttonYOffset; - std::vector saves = sender->GetSaveList(); + auto saves = sender->GetSaveList(); //string messageOfTheDay = sender->GetMessageOfTheDay(); if(sender->GetShowFavourite()) diff --git a/src/gui/tags/TagsModel.cpp b/src/gui/tags/TagsModel.cpp index 76bc586c6..d320ea460 100644 --- a/src/gui/tags/TagsModel.cpp +++ b/src/gui/tags/TagsModel.cpp @@ -6,19 +6,13 @@ #include "client/Client.h" #include "client/SaveInfo.h" -TagsModel::TagsModel(): - save(NULL) +void TagsModel::SetSave(SaveInfo *newSave /* non-owning */) { - -} - -void TagsModel::SetSave(SaveInfo * save) -{ - this->save = save; + this->save = newSave; notifyTagsChanged(); } -SaveInfo * TagsModel::GetSave() +SaveInfo *TagsModel::GetSave() // non-owning { return save; } @@ -72,7 +66,3 @@ void TagsModel::notifyTagsChanged() observers[i]->NotifyTagsChanged(this); } } - -TagsModel::~TagsModel() { -} - diff --git a/src/gui/tags/TagsModel.h b/src/gui/tags/TagsModel.h index e9855a5d7..a69d31ec1 100644 --- a/src/gui/tags/TagsModel.h +++ b/src/gui/tags/TagsModel.h @@ -6,15 +6,13 @@ class SaveInfo; class TagsView; class TagsModel { - SaveInfo * save; + SaveInfo *save = nullptr; // non-owning std::vector observers; void notifyTagsChanged(); public: - TagsModel(); void AddObserver(TagsView * observer); - void SetSave(SaveInfo * save); + void SetSave(SaveInfo *newSave /* non-owning */); void RemoveTag(ByteString tag); void AddTag(ByteString tag); - SaveInfo * GetSave(); - virtual ~TagsModel(); + SaveInfo *GetSave(); // non-owning }; diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index 23299cdc6..cde923fd8 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -1966,7 +1966,7 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l) auto *luacon_ci = static_cast(commandInterface); int i = -1; int pushed = 1; - SaveFile * tempfile = NULL; + std::unique_ptr tempfile; int x = luaL_optint(l,2,0); int y = luaL_optint(l,3,0); auto &client = Client::Ref(); @@ -1993,8 +1993,10 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l) if (tempfile->GetGameSave()->authors.size()) { - tempfile->GetGameSave()->authors["type"] = "luastamp"; - client.MergeStampAuthorInfo(tempfile->GetGameSave()->authors); + auto gameSave = tempfile->TakeGameSave(); + gameSave->authors["type"] = "luastamp"; + client.MergeStampAuthorInfo(gameSave->authors); + tempfile->SetGameSave(std::move(gameSave)); } } else @@ -2003,7 +2005,6 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l) lua_pushnil(l); tpt_lua_pushString(l, luacon_ci->GetLastError()); } - delete tempfile; } else { @@ -2060,7 +2061,7 @@ int LuaScriptInterface::simulation_reloadSave(lua_State * l) int LuaScriptInterface::simulation_getSaveID(lua_State *l) { - SaveInfo *tempSave = luacon_model->GetSave(); + auto *tempSave = luacon_model->GetSave(); if (tempSave) { lua_pushinteger(l, tempSave->GetID()); diff --git a/src/simulation/SaveRenderer.cpp b/src/simulation/SaveRenderer.cpp index 092b5cb4b..9127fdcb8 100644 --- a/src/simulation/SaveRenderer.cpp +++ b/src/simulation/SaveRenderer.cpp @@ -20,7 +20,7 @@ void SaveRenderer::Flush(int begin, int end) std::fill(ren->graphicscache + begin, ren->graphicscache + end, gcache_item()); } -std::unique_ptr SaveRenderer::Render(GameSave * save, bool decorations, bool fire, Renderer *renderModeSource) +std::unique_ptr SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource) { std::lock_guard gx(renderMutex); diff --git a/src/simulation/SaveRenderer.h b/src/simulation/SaveRenderer.h index 42cc9d588..9dc3b6bcd 100644 --- a/src/simulation/SaveRenderer.h +++ b/src/simulation/SaveRenderer.h @@ -15,7 +15,7 @@ class SaveRenderer: public ExplicitSingleton { std::mutex renderMutex; public: SaveRenderer(); - std::unique_ptr Render(GameSave * save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr); + std::unique_ptr Render(const GameSave *save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr); void Flush(int begin, int end); virtual ~SaveRenderer(); }; diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 7065e77dd..e6d5cdc14 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -343,12 +343,12 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu return 0; } -GameSave * Simulation::Save(bool includePressure) +std::unique_ptr Simulation::Save(bool includePressure) { return Save(includePressure, 0, 0, XRES-1, YRES-1); } -GameSave * Simulation::Save(bool includePressure, int fullX, int fullY, int fullX2, int fullY2) +std::unique_ptr Simulation::Save(bool includePressure, int fullX, int fullY, int fullX2, int fullY2) { int blockX, blockY, blockX2, blockY2, blockW, blockH; //Normalise incoming coords @@ -376,7 +376,7 @@ GameSave * Simulation::Save(bool includePressure, int fullX, int fullY, int full blockW = blockX2-blockX; blockH = blockY2-blockY; - GameSave * newSave = new GameSave(blockW, blockH); + auto newSave = std::make_unique(blockW, blockH); auto &possiblyCarriesType = Particle::PossiblyCarriesType(); auto &properties = Particle::GetProperties(); newSave->frameCount = frameCount; @@ -507,25 +507,23 @@ GameSave * Simulation::Save(bool includePressure, int fullX, int fullY, int full newSave->stkm.fanFigh.push_back(i); } - SaveSimOptions(newSave); + SaveSimOptions(*newSave); newSave->pmapbits = PMAPBITS; return newSave; } -void Simulation::SaveSimOptions(GameSave * gameSave) +void Simulation::SaveSimOptions(GameSave &gameSave) { - if (!gameSave) - return; - gameSave->gravityMode = gravityMode; - gameSave->customGravityX = customGravityX; - gameSave->customGravityY = customGravityY; - gameSave->airMode = air->airMode; - gameSave->ambientAirTemp = air->ambientAirTemp; - gameSave->edgeMode = edgeMode; - gameSave->legacyEnable = legacy_enable; - gameSave->waterEEnabled = water_equal_test; - gameSave->gravityEnable = grav->IsEnabled(); - gameSave->aheatEnable = aheat_enable; + gameSave.gravityMode = gravityMode; + gameSave.customGravityX = customGravityX; + gameSave.customGravityY = customGravityY; + gameSave.airMode = air->airMode; + gameSave.ambientAirTemp = air->ambientAirTemp; + gameSave.edgeMode = edgeMode; + gameSave.legacyEnable = legacy_enable; + gameSave.waterEEnabled = water_equal_test; + gameSave.gravityEnable = grav->IsEnabled(); + gameSave.aheatEnable = aheat_enable; } bool Simulation::FloodFillPmapCheck(int x, int y, int type) diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 4bdfee02a..f7b5b1f3a 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -123,9 +123,9 @@ public: int Load(const GameSave * save, bool includePressure); int Load(const GameSave * save, bool includePressure, int x, int y); - GameSave * Save(bool includePressure); - GameSave * Save(bool includePressure, int x1, int y1, int x2, int y2); - void SaveSimOptions(GameSave * gameSave); + std::unique_ptr Save(bool includePressure); + std::unique_ptr Save(bool includePressure, int x1, int y1, int x2, int y2); + void SaveSimOptions(GameSave &gameSave); SimulationSample GetSample(int x, int y); std::unique_ptr CreateSnapshot();