Serialization works in new version
This commit is contained in:
parent
6b3ce01e94
commit
79f7135746
23 changed files with 186 additions and 56 deletions
|
|
@ -46,6 +46,7 @@ set(sources "src/main.cpp"
|
|||
"src/World.cpp"
|
||||
"src/FileHelpers.cpp"
|
||||
"src/BookmarkManager.cpp"
|
||||
"src/VersionConstants.cpp"
|
||||
"src/ResourceDisplay/ResourceDisplay.cpp"
|
||||
"src/ResourceDisplay/SvgResourceDisplay.cpp"
|
||||
"src/ResourceDisplay/ImageResourceDisplay.cpp"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ template <class T> std::weak_ptr<T> make_weak_ptr(std::shared_ptr<T> ptr) { retu
|
|||
#define RELIABLE_COMMAND_CHANNEL "reliableCommand"
|
||||
#define UNRELIABLE_COMMAND_CHANNEL "unreliableCommand"
|
||||
#define RESOURCE_COMMAND_CHANNEL "resourceCommand"
|
||||
#define MAIN_NETLIBRARY_CHANNEL "main00003" // NOTE: Change this value whenever netcode is incompatible with the previous version
|
||||
#define MAIN_NETLIBRARY_CHANNEL "main00004" // NOTE: Change this value whenever netcode is incompatible with the previous version
|
||||
|
||||
typedef uint8_t MessageCommandType;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,18 @@ std::string version_numbers_to_version_str(const VersionNumber& versionNum) {
|
|||
return std::to_string(versionNum.major) + "." + std::to_string(versionNum.minor) + "." + std::to_string(versionNum.patch);
|
||||
}
|
||||
|
||||
bool operator<=(const VersionNumber& a, const VersionNumber& b) {
|
||||
return !(a > b);
|
||||
}
|
||||
|
||||
bool operator<(const VersionNumber& a, const VersionNumber& b) {
|
||||
return !(a >= b);
|
||||
}
|
||||
|
||||
bool operator>=(const VersionNumber& a, const VersionNumber& b) {
|
||||
return (a > b) || (a == b);
|
||||
}
|
||||
|
||||
bool operator>(const VersionNumber& a, const VersionNumber& b) {
|
||||
return (a.major > b.major) || (a.major == b.major && (a.minor > b.minor || (a.minor == b.minor && a.patch > b.patch)));
|
||||
}
|
||||
|
|
@ -13,6 +25,10 @@ bool operator==(const VersionNumber& a, const VersionNumber& b) {
|
|||
return a.major == b.major && a.minor == b.minor && a.patch == b.patch;
|
||||
}
|
||||
|
||||
bool operator!=(const VersionNumber& a, const VersionNumber& b) {
|
||||
return a.major != b.major || a.minor != b.minor || a.patch != b.patch;
|
||||
}
|
||||
|
||||
std::optional<VersionNumber> version_str_to_version_numbers(const std::string& versionStr) {
|
||||
try {
|
||||
std::vector<std::string> splitStrings = split_string_by_token(versionStr, ".");
|
||||
|
|
|
|||
|
|
@ -10,5 +10,9 @@ struct VersionNumber {
|
|||
|
||||
std::optional<VersionNumber> version_str_to_version_numbers(const std::string& versionStr);
|
||||
std::string version_numbers_to_version_str(const VersionNumber& versionNum);
|
||||
bool operator<=(const VersionNumber& a, const VersionNumber& b);
|
||||
bool operator<(const VersionNumber& a, const VersionNumber& b);
|
||||
bool operator>(const VersionNumber& a, const VersionNumber& b);
|
||||
bool operator>=(const VersionNumber& a, const VersionNumber& b);
|
||||
bool operator==(const VersionNumber& a, const VersionNumber& b);
|
||||
bool operator!=(const VersionNumber& a, const VersionNumber& b);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ void DrawBrushStroke::load(cereal::PortableBinaryInputArchive& a) {
|
|||
a(d->points, d->color, d->hasRoundCaps);
|
||||
}
|
||||
|
||||
void DrawBrushStroke::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(d->points, d->color, d->hasRoundCaps);
|
||||
}
|
||||
|
||||
void DrawBrushStroke::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
a(d->points, d->color, d->hasRoundCaps);
|
||||
}
|
||||
|
||||
DrawComponentType DrawBrushStroke::get_type() const {
|
||||
return DRAWCOMPONENT_BRUSHSTROKE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ class DrawBrushStroke : public DrawComponent {
|
|||
virtual DrawComponentType get_type() const override;
|
||||
virtual void save(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load(cereal::PortableBinaryInputArchive& a) override;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override;
|
||||
|
||||
struct Data {
|
||||
std::vector<DrawBrushStrokePoint> points;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../CoordSpaceHelper.hpp"
|
||||
#include "../Server/MainServer.hpp"
|
||||
#include "../CollabList.hpp"
|
||||
#include <Helpers/VersionNumber.hpp>
|
||||
|
||||
#ifndef IS_SERVER
|
||||
#include "../DrawData.hpp"
|
||||
|
|
@ -43,6 +44,8 @@ class DrawComponent {
|
|||
static std::shared_ptr<DrawComponent> allocate_comp_type(DrawComponentType type);
|
||||
virtual void save(cereal::PortableBinaryOutputArchive& a) const = 0;
|
||||
virtual void load(cereal::PortableBinaryInputArchive& a) = 0;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const = 0;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) = 0;
|
||||
virtual DrawComponentType get_type() const = 0;
|
||||
virtual void get_used_resources(std::unordered_set<ServerClientID>& v) const;
|
||||
virtual void remap_resource_ids(std::unordered_map<ServerClientID, ServerClientID>& newIDs);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,14 @@ void DrawEllipse::load(cereal::PortableBinaryInputArchive& a) {
|
|||
a(d.strokeColor, d.fillColor, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode);
|
||||
}
|
||||
|
||||
void DrawEllipse::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(d.strokeColor, d.fillColor, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode);
|
||||
}
|
||||
|
||||
void DrawEllipse::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
a(d.strokeColor, d.fillColor, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode);
|
||||
}
|
||||
|
||||
#ifndef IS_SERVER
|
||||
std::shared_ptr<DrawComponent> DrawEllipse::copy() const {
|
||||
auto a = std::make_shared<DrawEllipse>();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ class DrawEllipse : public DrawComponent {
|
|||
public:
|
||||
virtual void save(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load(cereal::PortableBinaryInputArchive& a) override;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override;
|
||||
virtual DrawComponentType get_type() const override;
|
||||
|
||||
// User input data
|
||||
|
|
|
|||
|
|
@ -24,6 +24,14 @@ void DrawImage::load(cereal::PortableBinaryInputArchive& a) {
|
|||
a(d.p1, d.p2, d.imageID);
|
||||
}
|
||||
|
||||
void DrawImage::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(d.p1, d.p2, d.imageID);
|
||||
}
|
||||
|
||||
void DrawImage::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
a(d.p1, d.p2, d.imageID);
|
||||
}
|
||||
|
||||
void DrawImage::get_used_resources(std::unordered_set<ServerClientID>& v) const {
|
||||
v.emplace(d.imageID);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ class DrawImage : public DrawComponent {
|
|||
public:
|
||||
virtual void save(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load(cereal::PortableBinaryInputArchive& a) override;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override;
|
||||
virtual DrawComponentType get_type() const override;
|
||||
virtual void get_used_resources(std::unordered_set<ServerClientID>& v) const override;
|
||||
virtual void remap_resource_ids(std::unordered_map<ServerClientID, ServerClientID>& newIDs) override;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,14 @@ void DrawRectangle::load(cereal::PortableBinaryInputArchive& a) {
|
|||
a(d.strokeColor, d.fillColor, d.cornerRadius, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode);
|
||||
}
|
||||
|
||||
void DrawRectangle::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(d.strokeColor, d.fillColor, d.cornerRadius, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode);
|
||||
}
|
||||
|
||||
void DrawRectangle::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
a(d.strokeColor, d.fillColor, d.cornerRadius, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode);
|
||||
}
|
||||
|
||||
#ifndef IS_SERVER
|
||||
std::shared_ptr<DrawComponent> DrawRectangle::copy() const {
|
||||
auto a = std::make_shared<DrawRectangle>();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ class DrawRectangle : public DrawComponent {
|
|||
public:
|
||||
virtual void save(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load(cereal::PortableBinaryInputArchive& a) override;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override;
|
||||
virtual DrawComponentType get_type() const override;
|
||||
|
||||
// User input data
|
||||
|
|
|
|||
|
|
@ -37,6 +37,29 @@ void DrawTextBox::load(cereal::PortableBinaryInputArchive& a) {
|
|||
textBox->set_rich_text_data(richText);
|
||||
}
|
||||
|
||||
void DrawTextBox::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(d.p1, d.p2, textBox->get_rich_text_data());
|
||||
}
|
||||
|
||||
void DrawTextBox::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
if(version < VersionNumber(0, 3, 0)) {
|
||||
bool editing; // Unused
|
||||
Vector4f textColor;
|
||||
float textSize;
|
||||
RichText::TextBox::Cursor cursor; // Unused, Equivalent to old cursor structure, just paragraph index and text index flipped
|
||||
std::string currentText;
|
||||
a(editing, d.p1, d.p2, textColor, textSize, cursor, currentText);
|
||||
textBox->insert({0, 0}, currentText);
|
||||
textBox->set_text_style_modifier_between({0, 0}, textBox->move(RichText::TextBox::Movement::END, {0, 0}), std::make_shared<ColorTextStyleModifier>(textColor));
|
||||
textBox->set_text_style_modifier_between({0, 0}, textBox->move(RichText::TextBox::Movement::END, {0, 0}), std::make_shared<SizeTextStyleModifier>(textSize));
|
||||
}
|
||||
else {
|
||||
TextData richText;
|
||||
a(d.p1, d.p2, richText);
|
||||
textBox->set_rich_text_data(richText);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IS_SERVER
|
||||
std::shared_ptr<DrawComponent> DrawTextBox::copy() const {
|
||||
auto a = std::make_shared<DrawTextBox>();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ class DrawTextBox : public DrawComponent {
|
|||
virtual DrawComponentType get_type() const override;
|
||||
virtual void save(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load(cereal::PortableBinaryInputArchive& a) override;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override;
|
||||
|
||||
// User input data
|
||||
struct Data {
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ void DrawingProgram::parallel_loop_all_components(std::function<void(const std::
|
|||
parallel_loop_container(components.client_list(), func);
|
||||
}
|
||||
|
||||
std::unordered_set<ServerClientID> DrawingProgram::get_used_resources() {
|
||||
std::unordered_set<ServerClientID> DrawingProgram::get_used_resources() const {
|
||||
std::unordered_set<ServerClientID> toRet;
|
||||
for(auto& c : components.client_list())
|
||||
c->obj->get_used_resources(toRet);
|
||||
|
|
@ -559,6 +559,23 @@ void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a)
|
|||
compCache.test_rebuild(components.client_list(), true);
|
||||
}
|
||||
|
||||
void DrawingProgram::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
uint64_t compCount;
|
||||
a(compCount);
|
||||
for(uint64_t i = 0; i < compCount; i++) {
|
||||
DrawComponentType t;
|
||||
a(t);
|
||||
auto newComp = DrawComponent::allocate_comp_type(t);
|
||||
a(newComp->id, newComp->coords);
|
||||
newComp->load_file(a, version);
|
||||
components.init_emplace_back(newComp);
|
||||
}
|
||||
parallel_loop_all_components([&](const auto& c){
|
||||
c->obj->commit_update(*this, false);
|
||||
});
|
||||
compCache.test_rebuild(components.client_list(), true);
|
||||
}
|
||||
|
||||
void DrawingProgram::client_erase_set(std::unordered_set<CollabListType::ObjectInfoPtr> erasedComponents) {
|
||||
std::unordered_set<ServerClientID> idsToErase;
|
||||
for(auto& c : erasedComponents)
|
||||
|
|
@ -687,11 +704,12 @@ void DrawingProgram::draw_drag_circle(SkCanvas* canvas, const Vector2f& sPos, co
|
|||
canvas->drawCircle(sPos.x(), sPos.y(), constantRadius, paintOutline);
|
||||
}
|
||||
|
||||
void DrawingProgram::write_to_file(cereal::PortableBinaryOutputArchive& a) {
|
||||
void DrawingProgram::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
auto& cList = components.client_list();
|
||||
a((uint64_t)cList.size());
|
||||
for(size_t i = 0; i < cList.size(); i++) {
|
||||
a(cList[i]->obj->get_type(), cList[i]->obj->id, cList[i]->obj->coords, *cList[i]->obj);
|
||||
a(cList[i]->obj->get_type(), cList[i]->obj->id, cList[i]->obj->coords);
|
||||
cList[i]->obj->save_file(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@ class DrawingProgram {
|
|||
void update();
|
||||
void scale_up(const WorldScalar& scaleUpAmount);
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData);
|
||||
|
||||
void initialize_draw_data(cereal::PortableBinaryInputArchive& a);
|
||||
std::unordered_set<ServerClientID> get_used_resources();
|
||||
void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version);
|
||||
|
||||
std::unordered_set<ServerClientID> get_used_resources() const;
|
||||
ClientPortionID get_max_id(ServerPortionID serverID);
|
||||
void write_to_file(cereal::PortableBinaryOutputArchive& a);
|
||||
void save_file(cereal::PortableBinaryOutputArchive& a) const;
|
||||
World& world;
|
||||
|
||||
bool prevent_undo_or_redo();
|
||||
|
|
|
|||
|
|
@ -48,14 +48,5 @@ enum ClientCommands : MessageCommandType {
|
|||
CLIENT_CANVAS_SCALE
|
||||
};
|
||||
|
||||
// NOTE: Do not change savefile header length
|
||||
#define SAVEFILE_HEADER_LEN 12
|
||||
// NOTE: Change these values whenever savefile is incompatible with previous version
|
||||
#define SAVEFILE_HEADER "INFPNT000003"
|
||||
#define SAVEFILE_HEADER_V2 "INFPNT000002"
|
||||
#define SAVEFILE_HEADER_V1 "INFPNT000001"
|
||||
// Version header
|
||||
#define VERSION_STRING "0.3.0"
|
||||
|
||||
// Arbitrary value. Higher scale up values lead to less scale up events (which can cause stuttering), but leads to larger numbers overall, which can cause a tiny bit of lag and increased memory usage
|
||||
#define CANVAS_SCALE_UP_STEP WorldScalar("100000000000000000000000000000000000000000000000000")
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "GUIStuff/Elements/Element.hpp"
|
||||
#include "GUIStuff/GUIManager.hpp"
|
||||
#include "InputManager.hpp"
|
||||
#include "VersionConstants.hpp"
|
||||
#include "World.hpp"
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
#include <algorithm>
|
||||
|
|
@ -193,7 +194,7 @@ void Toolbar::load_licenses() {
|
|||
std::sort(thirdPartyLicenses.begin(), thirdPartyLicenses.end(), [](const auto& a1, const auto& a2) {
|
||||
return std::lexicographical_compare(a1.first.begin(), a1.first.end(), a2.first.begin(), a2.first.end());
|
||||
});
|
||||
ownLicenseText = "InfiniPaint v" + std::string(VERSION_STRING);
|
||||
ownLicenseText = "InfiniPaint v" + VersionConstants::CURRENT_VERSION_STRING;
|
||||
ownLicenseText +=
|
||||
R"(
|
||||
|
||||
|
|
@ -583,7 +584,7 @@ void Toolbar::update_notification_check() {
|
|||
case FileDownloader::DownloadData::Status::SUCCESS: {
|
||||
updateCheckerData.updateCheckDone = true;
|
||||
std::optional<VersionNumber> newVersion = version_str_to_version_numbers(updateCheckerData.versionFile->str);
|
||||
std::optional<VersionNumber> currentVersion = version_str_to_version_numbers(VERSION_STRING);
|
||||
std::optional<VersionNumber> currentVersion = VersionConstants::CURRENT_VERSION_NUMBER;
|
||||
if(newVersion.has_value() && currentVersion.has_value()) {
|
||||
VersionNumber& newV = newVersion.value();
|
||||
VersionNumber& currentV = currentVersion.value();
|
||||
|
|
|
|||
20
src/VersionConstants.cpp
Normal file
20
src/VersionConstants.cpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "VersionConstants.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace VersionConstants {
|
||||
|
||||
VersionNumber header_to_version_number(const std::string& header) {
|
||||
static std::unordered_map<std::string, VersionNumber> m;
|
||||
if(m.empty()) {
|
||||
m["INFPNT000001"] = VersionNumber(0, 0, 1);
|
||||
m["INFPNT000002"] = VersionNumber(0, 1, 0);
|
||||
m["INFPNT000003"] = VersionNumber(0, 2, 0);
|
||||
m["INFPNT000004"] = VersionNumber(0, 3, 0);
|
||||
}
|
||||
auto it = m.find(header);
|
||||
if(it == m.end())
|
||||
throw std::runtime_error("[VersionConstants::header_to_version_number] Header " + header + " is invalid");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
}
|
||||
16
src/VersionConstants.hpp
Normal file
16
src/VersionConstants.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
#include <Helpers/VersionNumber.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace VersionConstants {
|
||||
// Map OLDEST version that is compatible with the filetype with a specific header
|
||||
// This means that, to check for file version, you can do these two checks:
|
||||
// Check if older than a certain version: if(fileVersion < NEWEST VERSION YOU SHOULDNT RUN THE IF STATEMENT ON)
|
||||
// Check if newer/equal to a certain version: if(fileVersion >= OLDEST VERSION YOU SHOULD RUN THE IF STATEMENT ON)
|
||||
VersionNumber header_to_version_number(const std::string& header);
|
||||
|
||||
constexpr int SAVEFILE_HEADER_LEN = 12; // DO NOT CHANGE THIS HEADER LENGTH
|
||||
const std::string CURRENT_SAVEFILE_HEADER = "INFPNT000004"; // Change whenever the save file is incompatible with the previous version
|
||||
const std::string CURRENT_VERSION_STRING = "0.3.0";
|
||||
constexpr VersionNumber CURRENT_VERSION_NUMBER(0, 3, 0);
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include "MainProgram.hpp"
|
||||
#include "SharedTypes.hpp"
|
||||
#include "Toolbar.hpp"
|
||||
#include "VersionConstants.hpp"
|
||||
#include "WorldGrid.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include <fstream>
|
||||
|
|
@ -273,14 +274,13 @@ void World::save_to_file(const std::filesystem::path& fileName) {
|
|||
filePath = force_extension_on_path(fileName, FILE_EXTENSION);
|
||||
|
||||
std::stringstream f;
|
||||
f.write(SAVEFILE_HEADER, SAVEFILE_HEADER_LEN);
|
||||
f.write(VersionConstants::CURRENT_SAVEFILE_HEADER.c_str(), VersionConstants::SAVEFILE_HEADER_LEN);
|
||||
|
||||
{
|
||||
std::stringstream fWorldDataToCompress;
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive a(fWorldDataToCompress);
|
||||
SaveLoadFileOp op{.world = this, .versionStr = SAVEFILE_HEADER};
|
||||
a(op);
|
||||
save_file(a);
|
||||
}
|
||||
|
||||
std::vector<char> compressedData(ZSTD_compressBound(fWorldDataToCompress.view().size()));
|
||||
|
|
@ -321,30 +321,26 @@ void World::load_from_file(const std::filesystem::path& fileName, std::string_vi
|
|||
buffer = byteDataFromFile;
|
||||
}
|
||||
|
||||
if(buffer.size() < SAVEFILE_HEADER_LEN)
|
||||
if(buffer.size() < VersionConstants::SAVEFILE_HEADER_LEN)
|
||||
throw std::runtime_error("[World::load_from_file] File is not an InfiniPaint canvas (File too small)");
|
||||
|
||||
std::string_view fileHeader = buffer.substr(0, SAVEFILE_HEADER_LEN);
|
||||
std::string_view fileHeader = buffer.substr(0, VersionConstants::SAVEFILE_HEADER_LEN);
|
||||
VersionNumber fileVersion = VersionConstants::header_to_version_number(std::string(fileHeader));
|
||||
std::string_view uncompressedDataView;
|
||||
std::vector<char> uncompressedDataVector;
|
||||
|
||||
if(fileHeader == SAVEFILE_HEADER || fileHeader == SAVEFILE_HEADER_V2) {
|
||||
uncompressedDataVector.resize(ZSTD_getFrameContentSize(buffer.data() + SAVEFILE_HEADER_LEN, buffer.size() - SAVEFILE_HEADER_LEN));
|
||||
size_t trueUncompressedSize = ZSTD_decompress(uncompressedDataVector.data(), uncompressedDataVector.size(), buffer.data() + SAVEFILE_HEADER_LEN, buffer.size() - SAVEFILE_HEADER_LEN);
|
||||
if(fileVersion < VersionNumber(0, 1, 0))
|
||||
uncompressedDataView = std::string_view(buffer.data() + VersionConstants::SAVEFILE_HEADER_LEN, buffer.size() - VersionConstants::SAVEFILE_HEADER_LEN);
|
||||
else {
|
||||
uncompressedDataVector.resize(ZSTD_getFrameContentSize(buffer.data() + VersionConstants::SAVEFILE_HEADER_LEN, buffer.size() - VersionConstants::SAVEFILE_HEADER_LEN));
|
||||
size_t trueUncompressedSize = ZSTD_decompress(uncompressedDataVector.data(), uncompressedDataVector.size(), buffer.data() + VersionConstants::SAVEFILE_HEADER_LEN, buffer.size() - VersionConstants::SAVEFILE_HEADER_LEN);
|
||||
uncompressedDataView = std::string_view(uncompressedDataVector.data(), trueUncompressedSize);
|
||||
}
|
||||
else if(fileHeader == SAVEFILE_HEADER_V1)
|
||||
uncompressedDataView = std::string_view(buffer.data() + SAVEFILE_HEADER_LEN, buffer.size() - SAVEFILE_HEADER_LEN);
|
||||
else
|
||||
throw std::runtime_error("[World::load_from_file] File is not an InfiniPaint canvas (Wrong header)");
|
||||
|
||||
|
||||
|
||||
ByteMemStream f((char*)uncompressedDataView.data(), uncompressedDataView.size());
|
||||
|
||||
cereal::PortableBinaryInputArchive a(f);
|
||||
SaveLoadFileOp op{.world = this, .versionStr = std::string(fileHeader)};
|
||||
a(op);
|
||||
load_file(a, fileVersion);
|
||||
nextClientID = get_max_id(ownID);
|
||||
|
||||
Logger::get().log("USERINFO", "File loaded");
|
||||
|
|
@ -355,34 +351,34 @@ ClientPortionID World::get_max_id(ServerPortionID serverID) {
|
|||
return std::max(std::max(rMan.get_max_id(serverID), drawProg.get_max_id(serverID)), gridMan.get_max_id(serverID));
|
||||
}
|
||||
|
||||
void World::SaveLoadFileOp::save(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(world->drawData.cam.c, world->main.window.size.cast<float>().eval());
|
||||
a(convert_vec3<Vector3f>(world->canvasTheme.backColor));
|
||||
world->drawProg.write_to_file(a);
|
||||
a(world->bMan);
|
||||
a(world->gridMan);
|
||||
world->rMan.save_strip_unused_resources(a, world->drawProg.get_used_resources());
|
||||
void World::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(drawData.cam.c, main.window.size.cast<float>().eval());
|
||||
a(convert_vec3<Vector3f>(canvasTheme.backColor));
|
||||
drawProg.save_file(a);
|
||||
a(bMan);
|
||||
a(gridMan);
|
||||
rMan.save_strip_unused_resources(a, drawProg.get_used_resources());
|
||||
}
|
||||
|
||||
void World::SaveLoadFileOp::load(cereal::PortableBinaryInputArchive& a) {
|
||||
void World::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
CoordSpaceHelper coordsToJumpTo;
|
||||
Vector2f windowSizeToJumpTo;
|
||||
a(coordsToJumpTo, windowSizeToJumpTo);
|
||||
|
||||
if(versionStr == SAVEFILE_HEADER_V1)
|
||||
world->set_canvas_background_color(DEFAULT_CANVAS_BACKGROUND_COLOR);
|
||||
if(version < VersionNumber(0, 1, 0))
|
||||
set_canvas_background_color(DEFAULT_CANVAS_BACKGROUND_COLOR);
|
||||
else {
|
||||
Vector3f canvasBackColor;
|
||||
a(canvasBackColor);
|
||||
world->set_canvas_background_color(canvasBackColor);
|
||||
set_canvas_background_color(canvasBackColor);
|
||||
}
|
||||
|
||||
world->drawData.cam.smooth_move_to(*world, coordsToJumpTo, windowSizeToJumpTo, true);
|
||||
world->drawProg.initialize_draw_data(a);
|
||||
a(world->bMan);
|
||||
if(versionStr == SAVEFILE_HEADER)
|
||||
a(world->gridMan);
|
||||
a(world->rMan);
|
||||
drawData.cam.smooth_move_to(*this, coordsToJumpTo, windowSizeToJumpTo, true);
|
||||
drawProg.load_file(a, version);
|
||||
a(bMan);
|
||||
if(version >= VersionNumber(0, 2, 0))
|
||||
a(gridMan);
|
||||
a(rMan);
|
||||
}
|
||||
|
||||
WorldScalar World::calculate_zoom_from_uniform_zoom(WorldScalar uniformZoom, WorldVec oldWindowSize) {
|
||||
|
|
|
|||
|
|
@ -34,12 +34,8 @@ class World {
|
|||
|
||||
World(MainProgram& initMain, OpenWorldInfo& worldInfo);
|
||||
|
||||
struct SaveLoadFileOp {
|
||||
World* world;
|
||||
std::string versionStr;
|
||||
void save(cereal::PortableBinaryOutputArchive& a) const;
|
||||
void load(cereal::PortableBinaryInputArchive& a);
|
||||
};
|
||||
void save_file(cereal::PortableBinaryOutputArchive& a) const;
|
||||
void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version);
|
||||
|
||||
MainProgram& main;
|
||||
DrawData drawData;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue