Sanitize GameSave/SaveInfo/SaveFile ownership

This commit is contained in:
Tamás Bálint Misius 2023-05-11 12:40:23 +02:00
parent 5c5354655c
commit 0f95ce82f8
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
45 changed files with 520 additions and 555 deletions

View File

@ -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<SaveFile>(openArg.value());
auto newSave = std::make_unique<GameSave>(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<int>();
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<GameSave>(std::move(saveData));
newSave->SetGameSave(std::move(newGameSave));
gameController->LoadSave(newSave);
delete newSave;
gameController->LoadSave(std::move(newSave));
}
catch (std::exception & e)
{

View File

@ -27,10 +27,10 @@ int main(int argc, char *argv[])
return 1;
}
GameSave * gameSave = NULL;
std::unique_ptr<GameSave> gameSave;
try
{
gameSave = new GameSave(fileData, false);
gameSave = std::make_unique<GameSave>(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;

View File

@ -495,10 +495,10 @@ void Client::MoveStampToFront(ByteString stampID)
}
}
SaveFile * Client::GetStamp(ByteString stampID)
std::unique_ptr<SaveFile> 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<GameSave> 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<SaveInfo> 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<SaveInfo>(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<SaveFile> Client::LoadSaveFile(ByteString filename)
{
ByteString err;
SaveFile *file = nullptr;
std::unique_ptr<SaveFile> file;
if (Platform::FileExists(filename))
{
file = new SaveFile(filename);
file = std::make_unique<SaveFile>(filename);
try
{
std::vector<char> data;
if (Platform::ReadFile(data, filename))
{
file->SetGameSave(new GameSave(std::move(data)));
file->SetGameSave(std::make_unique<GameSave>(std::move(data)));
}
else
{

View File

@ -114,9 +114,9 @@ public:
RequestStatus ExecVote(int saveID, int direction);
RequestStatus UploadSave(SaveInfo & save);
SaveFile * GetStamp(ByteString stampID);
std::unique_ptr<SaveFile> GetStamp(ByteString stampID);
void DeleteStamp(ByteString stampID);
ByteString AddStamp(GameSave * saveData);
ByteString AddStamp(std::unique_ptr<GameSave> saveData);
void RescanStamps();
const std::vector<ByteString> &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<SaveInfo> GetSave(int saveID, int saveDate);
std::unique_ptr<SaveFile> LoadSaveFile(ByteString filename);
RequestStatus DeleteSave(int saveID);
RequestStatus ReportSave(int saveID, String message);

View File

@ -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<char> data;
if (Platform::ReadFile(data, filename))
{
gameSave = new GameSave(std::move(data));
gameSave = std::make_unique<GameSave>(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<GameSave> 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<GameSave> 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;
}
}

View File

@ -1,27 +1,27 @@
#pragma once
#include "common/String.h"
#include <memory>
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<GameSave> TakeGameSave();
void SetGameSave(std::unique_ptr<GameSave> 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> gameSave;
ByteString filename;
String displayName;
String loadingError;

View File

@ -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<ByteString> 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<ByteString> 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<ByteString> tags)
this->tags=tagsSorted;
}
std::list<ByteString> SaveInfo::GetTags()
std::list<ByteString> 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<GameSave> SaveInfo::TakeGameSave()
{
delete gameSave;
gameSave = saveGame;
return std::move(gameSave);
}
void SaveInfo::SetGameSave(std::unique_ptr<GameSave> newGameSave)
{
gameSave = std::move(newGameSave);
}
std::unique_ptr<SaveInfo> SaveInfo::CloneInfo() const
{
auto clone = std::make_unique<SaveInfo>(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;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "common/String.h"
#include <list>
#include <memory>
#ifdef GetUserName
# undef GetUserName // dammit windows
@ -29,16 +30,12 @@ public:
bool Published;
std::list<ByteString> tags;
GameSave * gameSave;
SaveInfo(SaveInfo & save);
std::unique_ptr<GameSave> 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<ByteString> 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<ByteString> tags);
std::list<ByteString> GetTags();
std::list<ByteString> GetTags() const;
GameSave * GetGameSave();
void SetGameSave(GameSave * gameSave);
const GameSave *GetGameSave() const;
std::unique_ptr<GameSave> TakeGameSave();
void SetGameSave(std::unique_ptr<GameSave> newGameSave);
std::unique_ptr<SaveInfo> CloneInfo() const;
};

View File

@ -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,

View File

@ -24,7 +24,7 @@ class LoadFilesTask: public Task
{
ByteString directory;
ByteString search;
std::vector<SaveFile*> saveFiles;
std::vector<std::unique_ptr<SaveFile>> saveFiles;
void before() override
{
@ -44,20 +44,20 @@ class LoadFilesTask: public Task
notifyProgress(-1);
for(std::vector<ByteString>::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<SaveFile>(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<SaveFile*> GetSaveFiles()
std::vector<std::unique_ptr<SaveFile>> 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<SaveFile>(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,11 +257,12 @@ void FileBrowserActivity::OnTick(float dt)
if(loadFiles)
loadFiles->Poll();
while(files.size())
if (createButtons)
{
SaveFile * saveFile = files.back();
files.pop_back();
createButtons = false;
for (auto i = 0; i < int(files.size()); ++i)
{
auto &saveFile = files[i];
if(fileX == filesX)
{
fileX = 0;
@ -270,13 +274,13 @@ void FileBrowserActivity::OnTick(float dt)
buttonYOffset + buttonPadding + fileY*(buttonHeight+buttonPadding*2)
),
ui::Point(buttonWidth, buttonHeight),
saveFile);
saveFile.get());
saveButton->AddContextMenu(1);
saveButton->Tick(dt);
saveButton->SetActionCallback({
[this, saveButton] { SelectSave(saveButton->GetSaveFile()); },
[this, saveButton] { RenameSave(saveButton->GetSaveFile()); },
[this, saveButton] { DeleteSave(saveButton->GetSaveFile()); }
[this, i] { SelectSave(i); },
[this, i] { RenameSave(i); },
[this, i] { DeleteSave(i); }
});
progressBar->SetStatus("Rendering thumbnails");
@ -284,6 +288,7 @@ void FileBrowserActivity::OnTick(float dt)
componentsQueue.push_back(saveButton);
fileX++;
}
}
if(componentsQueue.size())
{
for(std::vector<ui::Component*>::iterator iter = componentsQueue.begin(), end = componentsQueue.end(); iter != end; ++iter)

View File

@ -26,7 +26,8 @@ class FileBrowserActivity: public TaskListener, public WindowActivity
OnSelected onSelected;
ui::ScrollPanel * itemList;
ui::Label * infoText;
std::vector<SaveFile*> files;
std::vector<std::unique_ptr<SaveFile>> files;
bool createButtons = false;
std::vector<ui::Component*> components;
std::vector<ui::Component*> 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;

View File

@ -238,7 +238,7 @@ std::pair<int, sign::Type> 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<GameSave>(*clip));
return true;
}
void GameController::LoadStamp(GameSave *stamp)
void GameController::LoadStamp(std::unique_ptr<GameSave> 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<SaveFile>("");
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<SaveFile> file)
{
gameModel->SetSaveFile(file, gameView->ShiftBehaviour());
gameModel->SetSaveFile(std::move(file), gameView->ShiftBehaviour());
}
void GameController::LoadSave(SaveInfo * save)
void GameController::LoadSave(std::unique_ptr<SaveInfo> 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<SaveFile> 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<SaveInfo>(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<SaveInfo>(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());
}
}

View File

@ -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<SaveFile> file);
void LoadSave(std::unique_ptr<SaveInfo> 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<GameSave> stamp);
void RemoveNotification(Notification * notification);

View File

@ -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<Menu*> 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<SaveInfo> 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<SaveInfo> 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<SaveFile> 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<SaveFile> 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<GameSave> 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<GameSave> 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<GameSave> 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)

View File

@ -44,8 +44,8 @@ private:
std::vector<Notification*> notifications;
//int clipboardSize;
//unsigned char * clipboardData;
GameSave * clipboard;
GameSave * placeSave;
std::unique_ptr<GameSave> clipboard;
std::unique_ptr<GameSave> placeSave;
std::deque<String> consoleLog;
std::vector<GameView*> observers;
std::vector<Tool*> toolList;
@ -62,8 +62,8 @@ private:
int activeMenu;
int currentBrush;
std::vector<std::unique_ptr<Brush>> brushList;
SaveInfo * currentSave;
SaveFile * currentFile;
std::unique_ptr<SaveInfo> currentSave;
std::unique_ptr<SaveFile> 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<SaveInfo> TakeSave();
const SaveFile *GetSaveFile() const;
std::unique_ptr<SaveFile> TakeSaveFile();
void SetSave(std::unique_ptr<SaveInfo> newSave, bool invertIncludePressure);
void SetSaveFile(std::unique_ptr<SaveFile> 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<GameSave> save);
void SetPlaceSave(std::unique_ptr<GameSave> save);
void Log(String message, bool printToFile);
std::deque<String> GetLog();
GameSave * GetClipboard();
GameSave * GetPlaceSave();
const GameSave *GetClipboard() const;
const GameSave *GetPlaceSave() const;
std::unique_ptr<GameSave> TakePlaceSave();
bool GetMouseClickRequired();
void SetMouseClickRequired(bool mouseClickRequired);
bool GetIncludePressure();

View File

@ -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;

View File

@ -78,8 +78,10 @@ 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
}

View File

@ -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)
{

View File

@ -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<VideoBuffer> 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();

View File

@ -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<void ()> 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<SaveFile> 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();
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "common/String.h"
#include <functional>
#include <memory>
class SaveFile;
class LocalBrowserView;
@ -13,14 +14,14 @@ public:
bool HasDone;
LocalBrowserController(std::function<void ()> onDone = nullptr);
LocalBrowserView * GetView() {return browserView;}
SaveFile * GetSave();
std::unique_ptr<SaveFile> 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);

View File

@ -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 <algorithm>
constexpr auto pageSize = 20;
LocalBrowserModel::LocalBrowserModel():
stamp(NULL),
currentPage(1),
stampToFront(1)
{
@ -16,9 +16,13 @@ LocalBrowserModel::LocalBrowserModel():
}
std::vector<SaveFile*> LocalBrowserModel::GetSavesList()
std::vector<SaveFile *> LocalBrowserModel::GetSavesList() // non-owning
{
return savesList;
std::vector<SaveFile *> 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<SaveFile> 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<SaveFile*> 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;
}

View File

@ -1,15 +1,16 @@
#pragma once
#include "common/String.h"
#include <vector>
#include <memory>
class SaveFile;
class LocalBrowserView;
class LocalBrowserModel {
std::vector<ByteString> selected;
SaveFile * stamp;
std::unique_ptr<SaveFile> stamp;
std::vector<ByteString> stampIDs;
std::vector<SaveFile*> savesList;
std::vector<std::unique_ptr<SaveFile>> savesList;
std::vector<LocalBrowserView*> observers;
int currentPage;
bool stampToFront;
@ -21,16 +22,16 @@ public:
int GetPageCount();
int GetPageNum() { return currentPage; }
void AddObserver(LocalBrowserView * observer);
std::vector<SaveFile *> GetSavesList();
std::vector<SaveFile *> GetSavesList(); // non-owning
void UpdateSavesList(int pageNumber);
void RescanStamps();
SaveFile * GetSave();
void SetSave(SaveFile * newStamp);
const SaveFile *GetSave();
std::unique_ptr<SaveFile> TakeSave();
void OpenSave(int index);
bool GetMoveToFront();
void SetMoveToFront(bool move);
std::vector<ByteString> GetSelected() { return selected; }
void ClearSelected() { selected.clear(); notifySelectedChanged(); }
void SelectSave(ByteString stampID);
void DeselectSave(ByteString stampID);
virtual ~LocalBrowserModel();
};

View File

@ -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<SaveFile*> 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,

View File

@ -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<SaveInfo> PreviewController::TakeSaveInfo()
{
return previewModel->TakeSaveInfo();
}
bool PreviewController::GetDoOpen()
{
return previewModel->GetDoOpen();

View File

@ -1,6 +1,7 @@
#pragma once
#include "client/ClientListener.h"
#include <functional>
#include <memory>
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<SaveInfo> TakeSaveInfo();
PreviewView * GetView() { return previewView; }
void Update();
void FavouriteSave();

View File

@ -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<SaveInfo> 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<GameSave>(*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<SaveInfo>(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<http::Request>(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)

View File

@ -16,7 +16,7 @@ class PreviewModel
bool doOpen;
bool canOpen;
std::vector<PreviewView*> observers;
SaveInfo * saveInfo;
std::unique_ptr<SaveInfo> saveInfo;
std::vector<char> * saveData;
std::vector<SaveComment*> * saveComments;
void notifySaveChanged();
@ -39,7 +39,8 @@ public:
PreviewModel();
~PreviewModel();
SaveInfo * GetSaveInfo();
const SaveInfo *GetSaveInfo() const;
std::unique_ptr<SaveInfo> TakeSaveInfo();
std::vector<SaveComment*> * GetComments();
bool GetCommentBoxEnabled();

View File

@ -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)
{

View File

@ -15,9 +15,9 @@
#include "Config.h"
LocalSaveActivity::LocalSaveActivity(SaveFile save, OnSaved onSaved_) :
LocalSaveActivity::LocalSaveActivity(std::unique_ptr<SaveFile> 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);
{
auto gameSave = save->TakeGameSave();
gameSave->authors = localSaveInfo;
auto [ fromNewerVersion, saveData ] = gameSave->Serialise();
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();
}

View File

@ -22,19 +22,19 @@ class ThumbnailRendererTask;
class LocalSaveActivity: public WindowActivity
{
using OnSaved = std::function<void (SaveFile *)>;
using OnSaved = std::function<void (std::unique_ptr<SaveFile>)>;
std::unique_ptr<PlaneAdapter<std::vector<pixel_rgba>>> saveToDiskImage = format::PixelsFromPNG(
std::vector<char>(save_local_png, save_local_png + save_local_png_size)
);
SaveFile save;
std::unique_ptr<SaveFile> save;
ThumbnailRendererTask *thumbnailRenderer;
std::unique_ptr<VideoBuffer> thumbnail;
ui::Textbox * filenameField;
OnSaved onSaved;
public:
LocalSaveActivity(SaveFile save, OnSaved onSaved = nullptr);
LocalSaveActivity(std::unique_ptr<SaveFile> newSave, OnSaved onSaved = nullptr);
void saveWrite(ByteString finalFilename);
void Save();
void OnDraw() override;

View File

@ -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<SaveInfo> 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<SaveInfo> 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:");

View File

@ -25,14 +25,14 @@ class Task;
class VideoBuffer;
class ServerSaveActivity: public WindowActivity, public TaskListener
{
using OnUploaded = std::function<void (SaveInfo &)>;
using OnUploaded = std::function<void (std::unique_ptr<SaveInfo>)>;
std::unique_ptr<PlaneAdapter<std::vector<pixel_rgba>>> saveToServerImage = format::PixelsFromPNG(
std::vector<char>(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<SaveInfo> newSave, OnUploaded onUploaded);
ServerSaveActivity(std::unique_ptr<SaveInfo> 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<VideoBuffer> thumbnail;
SaveInfo save;
std::unique_ptr<SaveInfo> save;
private:
OnUploaded onUploaded;
protected:

View File

@ -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<void ()> onDone_):
onDone = onDone_;
}
SaveInfo * SearchController::GetLoadedSave()
const SaveInfo *SearchController::GetLoadedSave() const
{
return searchModel->GetLoadedSave();
}
void SearchController::ReleaseLoadedSave()
std::unique_ptr<SaveInfo> 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);
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "common/String.h"
#include <functional>
#include <memory>
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<SaveInfo> TakeLoadedSave();
};

View File

@ -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 <thread>
#include <cmath>
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<SaveInfo *> SearchModel::EndSearchSaves()
std::vector<std::unique_ptr<SaveInfo>> SearchModel::EndSearchSaves()
{
std::vector<SaveInfo *> saveArray;
std::vector<std::unique_ptr<SaveInfo>> saveArray;
auto [ dataStatus, data ] = searchSaves->Finish();
searchSaves.reset();
auto &client = Client::Ref();
@ -88,10 +88,10 @@ std::vector<SaveInfo *> 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<SaveInfo>(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<SaveInfo> 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<SaveInfo*> SearchModel::GetSaveList()
std::unique_ptr<SaveInfo> SearchModel::TakeLoadedSave()
{
return saveList;
return std::move(loadedSave);
}
std::vector<SaveInfo *> SearchModel::GetSaveList() // non-owning
{
std::vector<SaveInfo *> nonOwningSaveList;
std::transform(saveList.begin(), saveList.end(), std::back_inserter(nonOwningSaveList), [](auto &ptr) {
return ptr.get();
});
return nonOwningSaveList;
}
std::vector<std::pair<ByteString, int> > SearchModel::GetTagList()
@ -360,11 +361,6 @@ void SearchModel::notifySelectedChanged()
}
}
SearchModel::~SearchModel()
{
delete loadedSave;
}
int SearchModel::GetPageCount()
{
if (!showOwn && !showFavourite && currentSort == "best" && lastQuery == "")

View File

@ -13,19 +13,19 @@ class SearchModel
private:
std::unique_ptr<http::Request> searchSaves;
void BeginSearchSaves(int start, int count, String query, ByteString sort, ByteString category);
std::vector<SaveInfo *> EndSearchSaves();
std::vector<std::unique_ptr<SaveInfo>> EndSearchSaves();
void BeginGetTags(int start, int count, String query);
std::vector<std::pair<ByteString, int>> EndGetTags();
std::unique_ptr<http::Request> getTags;
SaveInfo * loadedSave;
std::unique_ptr<SaveInfo> loadedSave;
ByteString currentSort;
String lastQuery;
String lastError;
std::vector<int> selected;
std::vector<SearchView*> observers;
std::vector<SaveInfo*> saveList;
std::vector<std::unique_ptr<SaveInfo>> saveList;
std::vector<std::pair<ByteString, int> > 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<SaveInfo*> GetSaveList();
std::vector<SaveInfo *> GetSaveList(); // non-owning
std::vector<std::pair<ByteString, int> > 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<SaveInfo> save);
const SaveInfo *GetLoadedSave() const;
std::unique_ptr<SaveInfo> TakeLoadedSave();
bool GetSavesLoaded() { return saveListLoaded; }
std::vector<int> GetSelected() { return selected; }
void ClearSelected() { selected.clear(); notifySelectedChanged(); }

View File

@ -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<SaveInfo*> saves = sender->GetSaveList();
auto saves = sender->GetSaveList();
//string messageOfTheDay = sender->GetMessageOfTheDay();
if(sender->GetShowFavourite())

View File

@ -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() {
}

View File

@ -6,15 +6,13 @@ class SaveInfo;
class TagsView;
class TagsModel {
SaveInfo * save;
SaveInfo *save = nullptr; // non-owning
std::vector<TagsView*> 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
};

View File

@ -1966,7 +1966,7 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l)
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
int i = -1;
int pushed = 1;
SaveFile * tempfile = NULL;
std::unique_ptr<SaveFile> 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());

View File

@ -20,7 +20,7 @@ void SaveRenderer::Flush(int begin, int end)
std::fill(ren->graphicscache + begin, ren->graphicscache + end, gcache_item());
}
std::unique_ptr<VideoBuffer> SaveRenderer::Render(GameSave * save, bool decorations, bool fire, Renderer *renderModeSource)
std::unique_ptr<VideoBuffer> SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource)
{
std::lock_guard<std::mutex> gx(renderMutex);

View File

@ -15,7 +15,7 @@ class SaveRenderer: public ExplicitSingleton<SaveRenderer> {
std::mutex renderMutex;
public:
SaveRenderer();
std::unique_ptr<VideoBuffer> Render(GameSave * save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr);
std::unique_ptr<VideoBuffer> Render(const GameSave *save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr);
void Flush(int begin, int end);
virtual ~SaveRenderer();
};

View File

@ -343,12 +343,12 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
return 0;
}
GameSave * Simulation::Save(bool includePressure)
std::unique_ptr<GameSave> 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<GameSave> 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<GameSave>(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)

View File

@ -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<GameSave> Save(bool includePressure);
std::unique_ptr<GameSave> Save(bool includePressure, int x1, int y1, int x2, int y2);
void SaveSimOptions(GameSave &gameSave);
SimulationSample GetSample(int x, int y);
std::unique_ptr<Snapshot> CreateSnapshot();