undo authors changes on ctrl+z, prevent excessive nesting

This commit is contained in:
jacob1 2017-07-15 16:21:16 -04:00
parent 5ee10d14e4
commit 6efedcdd33
8 changed files with 91 additions and 43 deletions

View File

@ -97,12 +97,10 @@ public:
void MergeStampAuthorInfo(Json::Value linksToAdd);
void MergeAuthorInfo(Json::Value linksToAdd);
void OverwriteAuthorInfo(Json::Value overwrite) { authors = overwrite; }
Json::Value GetAuthorInfo() { return authors; }
void SaveAuthorInfo(Json::Value *saveInto);
void ClearAuthorInfo() { authors.clear(); }
bool IsAuthorsEmpty() { return authors.size() == 0; }
#if defined(DEBUG) || defined(SNAPSHOT)
std::string GetAuthorString() { return authors.toStyledString(); }
#endif
UpdateInfo GetUpdateInfo();

View File

@ -3,6 +3,7 @@
#include <sstream>
#include <cmath>
#include <vector>
#include <set>
#include <bzlib.h>
#include "Config.h"
#include "Format.h"
@ -1136,38 +1137,6 @@ fin:
free(partsSimIndex);
}
void GameSave::ConvertBsonToJson(bson_iterator *iter, Json::Value *j)
{
bson_iterator subiter;
bson_iterator_subiterator(iter, &subiter);
while (bson_iterator_next(&subiter))
{
std::string key = bson_iterator_key(&subiter);
if (bson_iterator_type(&subiter) == BSON_STRING)
(*j)[key] = bson_iterator_string(&subiter);
else if (bson_iterator_type(&subiter) == BSON_BOOL)
(*j)[key] = bson_iterator_bool(&subiter);
else if (bson_iterator_type(&subiter) == BSON_INT)
(*j)[key] = bson_iterator_int(&subiter);
else if (bson_iterator_type(&subiter) == BSON_LONG)
(*j)[key] = (Json::Value::Int64)bson_iterator_long(&subiter);
else if (bson_iterator_type(&subiter) == BSON_ARRAY)
{
bson_iterator arrayiter;
bson_iterator_subiterator(&subiter, &arrayiter);
while (bson_iterator_next(&arrayiter))
{
if (bson_iterator_type(&arrayiter) == BSON_OBJECT && !strcmp(bson_iterator_key(&arrayiter), "part"))
{
Json::Value tempPart;
ConvertBsonToJson(&arrayiter, &tempPart);
(*j)["links"].append(tempPart);
}
}
}
}
}
void GameSave::readPSv(char * data, int dataLength)
{
unsigned char * d = NULL, * c = (unsigned char *)data;
@ -2377,8 +2346,68 @@ fin:
return (char*)outputData;
}
void GameSave::ConvertBsonToJson(bson_iterator *iter, Json::Value *j)
{
bson_iterator subiter;
bson_iterator_subiterator(iter, &subiter);
while (bson_iterator_next(&subiter))
{
std::string key = bson_iterator_key(&subiter);
if (bson_iterator_type(&subiter) == BSON_STRING)
(*j)[key] = bson_iterator_string(&subiter);
else if (bson_iterator_type(&subiter) == BSON_BOOL)
(*j)[key] = bson_iterator_bool(&subiter);
else if (bson_iterator_type(&subiter) == BSON_INT)
(*j)[key] = bson_iterator_int(&subiter);
else if (bson_iterator_type(&subiter) == BSON_LONG)
(*j)[key] = (Json::Value::Int64)bson_iterator_long(&subiter);
else if (bson_iterator_type(&subiter) == BSON_ARRAY)
{
bson_iterator arrayiter;
bson_iterator_subiterator(&subiter, &arrayiter);
while (bson_iterator_next(&arrayiter))
{
if (bson_iterator_type(&arrayiter) == BSON_OBJECT && !strcmp(bson_iterator_key(&arrayiter), "part"))
{
Json::Value tempPart;
ConvertBsonToJson(&arrayiter, &tempPart);
(*j)["links"].append(tempPart);
}
else if (bson_iterator_type(&arrayiter) == BSON_INT && !strcmp(bson_iterator_key(&arrayiter), "saveID"))
{
(*j)["links"].append(bson_iterator_int(&arrayiter));
}
}
}
}
}
std::set<int> GetNestedSaveIDs(Json::Value j)
{
Json::Value::Members members = j.getMemberNames();
std::set<int> saveIDs = std::set<int>();
for (Json::Value::Members::iterator iter = members.begin(), end = members.end(); iter != end; ++iter)
{
std::string member = *iter;
if (member == "id")
saveIDs.insert(j[member].asInt());
else if (j[member].isArray())
{
for (Json::Value::ArrayIndex i = 0; i < j[member].size(); i++)
{
// only supports objects here because that is all we need
if (!j[member][i].isObject())
continue;
std::set<int> nestedSaveIDs = GetNestedSaveIDs(j[member][i]);
saveIDs.insert(nestedSaveIDs.begin(), nestedSaveIDs.end());
}
}
}
return saveIDs;
}
// converts a json object to bson
void GameSave::ConvertJsonToBson(bson *b, Json::Value j)
void GameSave::ConvertJsonToBson(bson *b, Json::Value j, int depth)
{
Json::Value::Members members = j.getMemberNames();
for (Json::Value::Members::iterator iter = members.begin(), end = members.end(); iter != end; ++iter)
@ -2395,14 +2424,27 @@ void GameSave::ConvertJsonToBson(bson *b, Json::Value j)
else if (j[member].isArray())
{
bson_append_start_array(b, member.c_str());
std::set<int> saveIDs = std::set<int>();
for (Json::Value::ArrayIndex i = 0; i < j[member].size(); i++)
{
// only supports objects here because that is all we need
if (!j[member][i].isObject())
continue;
bson_append_start_object(b, "part");
ConvertJsonToBson(b, j[member][i]);
bson_append_finish_object(b);
if (depth > 4)
{
std::set<int> nestedSaveIDs = GetNestedSaveIDs(j[member][i]);
saveIDs.insert(nestedSaveIDs.begin(), nestedSaveIDs.end());
}
else
{
bson_append_start_object(b, "part");
ConvertJsonToBson(b, j[member][i], depth+1);
bson_append_finish_object(b);
}
}
for (std::set<int>::iterator iter = saveIDs.begin(), end = saveIDs.end(); iter != end; ++iter)
{
bson_append_int(b, "saveID", *iter);
}
bson_append_finish_array(b);
}

View File

@ -116,7 +116,7 @@ private:
void readOPS(char * data, int dataLength);
void readPSv(char * data, int dataLength);
char * serialiseOPS(unsigned int & dataSize);
void ConvertJsonToBson(bson *b, Json::Value j);
void ConvertJsonToBson(bson *b, Json::Value j, int depth = 0);
void ConvertBsonToJson(bson_iterator *b, Json::Value *j);
};

View File

@ -242,11 +242,14 @@ void GameController::HistoryRestore()
if (historyPosition == history.size())
{
Snapshot * newSnap = gameModel->GetSimulation()->CreateSnapshot();
if (newSnap)
newSnap->Authors = Client::Ref().GetAuthorInfo();
delete gameModel->GetRedoHistory();
gameModel->SetRedoHistory(newSnap);
}
Snapshot * snap = history[newHistoryPosition];
gameModel->GetSimulation()->Restore(*snap);
Client::Ref().OverwriteAuthorInfo(snap->Authors);
gameModel->SetHistory(history);
gameModel->SetHistoryPosition(newHistoryPosition);
}
@ -258,6 +261,7 @@ void GameController::HistorySnapshot()
Snapshot * newSnap = gameModel->GetSimulation()->CreateSnapshot();
if (newSnap)
{
newSnap->Authors = Client::Ref().GetAuthorInfo();
while (historyPosition < history.size())
{
Snapshot * snap = history.back();
@ -295,6 +299,7 @@ void GameController::HistoryForward()
if (!snap)
return;
gameModel->GetSimulation()->Restore(*snap);
Client::Ref().OverwriteAuthorInfo(snap->Authors);
gameModel->SetHistoryPosition(newHistoryPosition);
}

View File

@ -659,7 +659,7 @@ void GameModel::SetSave(SaveInfo * newSave)
saveData->authors["username"] = newSave->userName;
saveData->authors["title"] = newSave->name;
saveData->authors["description"] = newSave->Description;
saveData->authors["published"] = newSave->Published;
saveData->authors["published"] = (int)newSave->Published;
saveData->authors["date"] = newSave->updatedDate;
}
// This save was probably just created, and we didn't know the ID when creating it

View File

@ -1492,7 +1492,7 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
case 'a':
if (ctrl)
{
std::string authorString = Client::Ref().GetAuthorString();
std::string authorString = Client::Ref().GetAuthorInfo().toStyledString();
new InformationMessage("Save authorship info", authorString, true);
}
break;

View File

@ -266,7 +266,7 @@ void ServerSaveActivity::AddAuthorInfo()
serverSaveInfo["username"] = Client::Ref().GetAuthUser().Username;
serverSaveInfo["title"] = save.GetName();
serverSaveInfo["description"] = save.GetDescription();
serverSaveInfo["published"] = save.GetPublished();
serverSaveInfo["published"] = (int)save.GetPublished();
serverSaveInfo["date"] = (Json::Value::UInt64)time(NULL);
Client::Ref().SaveAuthorInfo(&serverSaveInfo);
save.GetGameSave()->authors = serverSaveInfo;

View File

@ -3,6 +3,7 @@
#include <vector>
#include "Particle.h"
#include "json/json.h"
class Snapshot
{
@ -30,6 +31,8 @@ public:
std::vector<int> WirelessData;
std::vector<playerst> stickmen;
std::vector<sign> signs;
Json::Value Authors;
Snapshot() :
AirPressure(),