From 2cc26367541de1e3f1f3cc798cf96c517ac1f2d7 Mon Sep 17 00:00:00 2001 From: mnelenpridumivat Date: Thu, 12 Dec 2024 17:31:01 +0300 Subject: [PATCH] Fix engine classes serialization --- src/xrCore/Save/MemoryBuffer.cpp | 4 +- src/xrCore/Save/MemoryBuffer.h | 16 +- src/xrCore/Save/SaveChunk.cpp | 7 +- src/xrCore/Save/SaveManager.cpp | 116 +++++++++++- src/xrCore/Save/SaveManager.h | 61 +++++++ src/xrCore/Save/SaveObject.cpp | 6 + src/xrCore/Save/SaveObject.h | 3 + src/xrCore/Save/SaveVariables.cpp | 187 ++++++++++++++++++++ src/xrCore/Save/SaveVariables.h | 19 ++ src/xrGame/GameObject.cpp | 2 +- src/xrGame/alife_storage_manager.cpp | 12 +- src/xrGame/script_binder.cpp | 5 +- src/xrGame/script_binder.h | 4 +- src/xrScripts/exports/SaveSystem_script.cpp | 6 - 14 files changed, 420 insertions(+), 28 deletions(-) diff --git a/src/xrCore/Save/MemoryBuffer.cpp b/src/xrCore/Save/MemoryBuffer.cpp index 4079309e38..a2055fe9c0 100644 --- a/src/xrCore/Save/MemoryBuffer.cpp +++ b/src/xrCore/Save/MemoryBuffer.cpp @@ -13,9 +13,9 @@ bool CMemoryChunk::Write(const void* data, size_t size) if (!CanWrite(size)) { return false; } - memcpy(this->data, data, size); + memcpy(this->data + count, data, size); count += size; - return false; + return true; } CMemoryBuffer::CMemoryBuffer() diff --git a/src/xrCore/Save/MemoryBuffer.h b/src/xrCore/Save/MemoryBuffer.h index 6d74d64be1..15ebdb9a01 100644 --- a/src/xrCore/Save/MemoryBuffer.h +++ b/src/xrCore/Save/MemoryBuffer.h @@ -27,7 +27,7 @@ class CReservedMemory class CMemoryChunk { public: - static constexpr size_t ChunkSize = 16 * 1024; + static constexpr size_t ChunkSize = 2 * 1024; private: BYTE data[ChunkSize]; @@ -51,6 +51,12 @@ class CMemoryChunk return Write(data, sizeof(T)); } + template<> + bool Write(IWriter* data) { + data->w((BYTE*)&this->data, count); + return false; + } + }; class CMemoryBuffer @@ -85,4 +91,12 @@ class CMemoryBuffer Write(data.c_str(), data.size()); return true; } + + template<> + bool Write(IWriter* data) { + for (const auto& elem : Chunks) { + elem->Write(data); + } + return true; + } }; \ No newline at end of file diff --git a/src/xrCore/Save/SaveChunk.cpp b/src/xrCore/Save/SaveChunk.cpp index c986179643..bedeeb8068 100644 --- a/src/xrCore/Save/SaveChunk.cpp +++ b/src/xrCore/Save/SaveChunk.cpp @@ -16,12 +16,7 @@ CSaveChunk::~CSaveChunk() void CSaveChunk::Write(CMemoryBuffer& Buffer) { Buffer.Write((u8)ESaveVariableType::t_chunkStart); - if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseStringOptimization)) { - Buffer.Write(_chunkName); - } - else { - Buffer.Write(_chunkName); - } + CSaveManager::GetInstance().ConditionalWriteString(_chunkName, Buffer); for (const auto& elem : _subchunks) { elem.second->Write(Buffer); } diff --git a/src/xrCore/Save/SaveManager.cpp b/src/xrCore/Save/SaveManager.cpp index c39f19672d..9fe2d84fe9 100644 --- a/src/xrCore/Save/SaveManager.cpp +++ b/src/xrCore/Save/SaveManager.cpp @@ -4,9 +4,9 @@ CSaveManager::CSaveManager() { - SetFlag(ESaveManagerFlagsGeneral::EUseStringOptimization, false); - SetFlag(ESaveManagerFlagsGeneral::EUseIntOptimization, false); - SetFlag(ESaveManagerFlagsGeneral::EUseBoolOptimization, false); + SetFlag(ESaveManagerFlagsGeneral::EUseStringOptimization, true); + SetFlag(ESaveManagerFlagsGeneral::EUseIntOptimization, true); + SetFlag(ESaveManagerFlagsGeneral::EUseBoolOptimization, true); SetFlag(ESaveManagerFlagsGeneral::EHasExtraControlFlags, false); } @@ -43,6 +43,10 @@ CSaveObjectSave* CSaveManager::BeginSave() void CSaveManager::WriteSavedData(const string_path& to_file) { SaveWriter = FS.w_open(to_file); + Buffers.Init(); + StringsHashesMap = xr_make_unique>>(); + BoolQueue = xr_make_unique>(); + CompileData(); WriteHeader(); if (TestFlag(ESaveManagerFlagsGeneral::EUseStringOptimization)) { @@ -52,23 +56,123 @@ void CSaveManager::WriteSavedData(const string_path& to_file) { WriteBools(); } + WriteData(); + StringsHashesMap.reset(); + BoolQueue.reset(); + Buffers.Clear(); + FS.w_close(SaveWriter); +} + +void CSaveManager::ConditionalWriteString(shared_str Value, CMemoryBuffer& buffer) +{ + if (TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseStringOptimization)) { + auto StringKey = crc32(Value.c_str(), Value.size()); + u32 StringVecID = 0; + auto it = StringsHashesMap->find(StringKey); + if (it == StringsHashesMap->end()) { + StringsHashesMap->emplace(StringKey, RStringVec{ Value }); + } + else { + bool Contains = false; + for (u32 i = 0; i < it->second.size(); ++i) { + if (Value == it->second[i]) { + Contains = true; + StringVecID = i; + break; + } + } + if (!Contains) { + StringVecID = it->second.size(); + it->second.emplace_back(Value); + } + } + u64 StringRefID = ((u64)StringKey << 32) | StringVecID; + buffer.Write(StringRefID); + } + else { + buffer.Write(Value); + } +} + +void CSaveManager::ConditionalWriteBool(bool& Value, CMemoryBuffer& buffer) +{ + if (TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseBoolOptimization)) + { + BoolQueue->push(&Value); + ++BoolsNum; + } + else { + buffer.Write(Value); + } } void CSaveManager::WriteHeader() { - SaveWriter->w_u8(ControlFlagsDefault.flags); + Buffers.BufferHeader->Write(ESaveVariableType::t_chunk); + Buffers.BufferHeader->Write(ControlFlagsDefault.flags); + Buffers.BufferHeader->Write(SaveWriter); } void CSaveManager::WriteStrings() { + Buffers.BufferStrings->Write(ESaveVariableType::t_chunk); + Buffers.BufferStrings->Write(StringsHashesMap->size()); + Buffers.BufferStrings->Write(ESaveVariableType::t_array); + for (const auto& elem : *StringsHashesMap.get()) { + Buffers.BufferStrings->Write(elem.first); + Buffers.BufferStrings->Write(ESaveVariableType::t_array); + Buffers.BufferStrings->Write(elem.second.size()); + for (const auto& elem2 : elem.second) { + Buffers.BufferStrings->Write(elem2); + } + } + Buffers.BufferStrings->Write(SaveWriter); } void CSaveManager::WriteBools() { + Buffers.BufferBools->Write(ESaveVariableType::t_chunk); + Buffers.BufferBools->Write(BoolsNum); + Flags8 Flags; + u8 WrittenFlags = 0; + while (!BoolQueue->empty()) { + auto Ptr = BoolQueue->front(); + Flags.set(1 << WrittenFlags, Ptr); + ++WrittenFlags; + if (WrittenFlags == 8) { + Buffers.BufferBools->Write(Flags.get()); + WrittenFlags = 0; + Flags.zero(); + } + BoolQueue->pop(); + } + if (WrittenFlags != 8) { + Buffers.BufferBools->Write(Flags.get()); + } + Buffers.BufferBools->Write(SaveWriter); } void CSaveManager::WriteData() { - CMemoryBuffer buffer; - SaveData->Write(buffer); + Buffers.BufferGeneral->Write(SaveWriter); +} + +void CSaveManager::CompileData() +{ + SaveData->Write(Buffers.BufferGeneral); +} + +inline void CSaveManager::SMemoryBuffers::Init() { + VERIFY(!(BufferHeader || BufferStrings || BufferBools || BufferGeneral)); + BufferHeader = new CMemoryBuffer(); + BufferStrings = new CMemoryBuffer(); + BufferBools = new CMemoryBuffer(); + BufferGeneral = new CMemoryBuffer(); +} + +inline void CSaveManager::SMemoryBuffers::Clear() { + xr_delete(BufferHeader); + xr_delete(BufferStrings); + xr_delete(BufferBools); + xr_delete(BufferGeneral); } diff --git a/src/xrCore/Save/SaveManager.h b/src/xrCore/Save/SaveManager.h index 37a11f6dfe..84bbed80fd 100644 --- a/src/xrCore/Save/SaveManager.h +++ b/src/xrCore/Save/SaveManager.h @@ -1,12 +1,68 @@ #pragma once #include "SaveObject.h" +/* +New save file structure: + +1) Header chunk: settings of the save +1.1) Firstly - chunk mark +1.2) Some flags +1.3) EUseStringOptimization flag - gather all strings in different chunk and replace their occurence with u64 (u32 string hash + u32 index for collisions) ++ Shrink save memory because writes similar strings once +- Need more time to process +1.4) EUseIntOptimization flag - attempt to write all integers with fewer amount of bytes. For example, if u64 has value of 200, then it'll be writen as u8, but still will be read as u64 ++ Shrink save memory because uses less bytes for each integer +- Need more time to process +1.5) EUseBoolOptimization flag - write all bools in different chunk, representing each bool as individual bit instead of byte. All bool values from general chunk would be romeved and will be restores during read. ++ Shrink save memory because uses only one bit per bool instead od byte per bool +- Strongly depends on order of writing bools in memory, could be broken if somehow order of bools in memory would be changed +1.6) EHasExtraControlFlags flag - reserved for showing if additional settings chunk present + +2) (Optional) Additional header chunk - write your required settings data. Please, left a single flag if where would be other additional header chunks futher + +3) (Optional) String chunk - write compressed strings +3.1) Firstly - chunk mark +3.2) Write map "string hash - string container" as array +3.3) Write each string container as array of strings + +4) (Optional) Bools chunk - write compressed bools +4.1) Firstly - chunk mark +4.2) Amount of u8, containing data. +4.3) Sequence of u8, each bit represents each bool at corresponding position + +5) General chunk - chunk with serialized data +5.1) Serialized tree. Saved recursevly. +5.2) Firstly - chunk mark +5.3) After that, chunk name +5.4) Then, subchunks (start from point 5.2) +5.5) Variables in this chunk +5.6) Chunk end mark +*/ + class XRCORE_API CSaveManager { CSaveManager(); CSaveObjectSave* SaveData = nullptr; IWriter* SaveWriter = nullptr; + xr_unique_ptr>> StringsHashesMap; + xr_unique_ptr> BoolQueue; + u64 BoolsNum = 0; + +public: + struct SMemoryBuffers { + CMemoryBuffer* BufferHeader = nullptr; + CMemoryBuffer* BufferStrings = nullptr; + CMemoryBuffer* BufferBools = nullptr; + CMemoryBuffer* BufferGeneral = nullptr; + + void Init(); + void Clear(); + + }; + +private: + SMemoryBuffers Buffers; Flags8 ControlFlagsDefault; Flags8 ControlFlagsRead; @@ -15,6 +71,8 @@ class XRCORE_API CSaveManager void WriteBools(); void WriteData(); + void CompileData(); + public: enum class ESaveManagerFlagsGeneral : u8 { @@ -38,4 +96,7 @@ class XRCORE_API CSaveManager CSaveObjectSave* BeginSave(); void WriteSavedData(const string_path& to_file); + void ConditionalWriteString(shared_str Value, CMemoryBuffer& buffer); + void ConditionalWriteBool(bool& Value, CMemoryBuffer& buffer); + }; \ No newline at end of file diff --git a/src/xrCore/Save/SaveObject.cpp b/src/xrCore/Save/SaveObject.cpp index d50f3cc2af..c7a8a4fcdf 100644 --- a/src/xrCore/Save/SaveObject.cpp +++ b/src/xrCore/Save/SaveObject.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "SaveObject.h" +#include "SaveManager.h" CSaveObject::CSaveObject() { @@ -62,6 +63,11 @@ void CSaveObjectSave::BeginChunk(shared_str ChunkName) _chunkStack.push(_chunkStack.top()->BeginChunk(ChunkName)); } +void CSaveObjectSave::Write(CMemoryBuffer* buffer) +{ + _rootChunk->Write(*buffer); +} + CSaveObjectLoad::CSaveObjectLoad() { _rootChunk = new CSaveChunk("Root"); diff --git a/src/xrCore/Save/SaveObject.h b/src/xrCore/Save/SaveObject.h index a8d2d6129b..6ee9ccf169 100644 --- a/src/xrCore/Save/SaveObject.h +++ b/src/xrCore/Save/SaveObject.h @@ -16,6 +16,7 @@ class XRCORE_API CSaveObject { CSaveChunk* GetCurrentChunk(); virtual void BeginChunk(shared_str ChunkName) = 0; void EndChunk(); + }; class XRCORE_API CSaveObjectSave: public CSaveObject { @@ -24,6 +25,8 @@ class XRCORE_API CSaveObjectSave: public CSaveObject { CSaveObjectSave(CSaveChunk* Root); virtual void BeginChunk(shared_str ChunkName) override; + + void Write(CMemoryBuffer* buffer); }; class XRCORE_API CSaveObjectLoad: public CSaveObject { diff --git a/src/xrCore/Save/SaveVariables.cpp b/src/xrCore/Save/SaveVariables.cpp index 49b75a4b91..e7c3f58688 100644 --- a/src/xrCore/Save/SaveVariables.cpp +++ b/src/xrCore/Save/SaveVariables.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include "SaveVariables.h" +#include "MemoryBuffer.h" +#include "SaveManager.h" CSaveVariableArray::~CSaveVariableArray() { @@ -7,3 +9,188 @@ CSaveVariableArray::~CSaveVariableArray() xr_delete(_array[i]); } } + +void CSaveVariableArray::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_array); + Buffer.Write(_size); + for (const auto& elem : _array) { + elem->Write(Buffer); + } +} + +void CSaveVariableBool::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_bool); + CSaveManager::GetInstance().ConditionalWriteBool(_value, Buffer); +} + +void CSaveVariableFloat::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_float); + Buffer.Write(_value); +} + +void CSaveVariableDouble::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_double); + Buffer.Write(_value); +} + +void CSaveVariableVec3::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_vec3); + Buffer.Write(_value.x); + Buffer.Write(_value.y); + Buffer.Write(_value.z); +} + +void CSaveVariableVec4::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_vec3); + Buffer.Write(_value.x); + Buffer.Write(_value.y); + Buffer.Write(_value.z); + Buffer.Write(_value.w); +} + +void CSaveVariableU64::Write(CMemoryBuffer& Buffer) +{ + if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseIntOptimization)) { + if (_value <= std::numeric_limits::max()) { + Buffer.Write(ESaveVariableType::t_u64_op8); + Buffer.Write(_value); + return; + } + if (_value <= std::numeric_limits::max()) { + Buffer.Write(ESaveVariableType::t_u64_op16); + Buffer.Write(_value); + return; + } + if (_value <= std::numeric_limits::max()) { + Buffer.Write(ESaveVariableType::t_u64_op32); + Buffer.Write(_value); + return; + } + } + Buffer.Write(ESaveVariableType::t_u64); + Buffer.Write(_value); +} + +void CSaveVariableS64::Write(CMemoryBuffer& Buffer) +{ + if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseIntOptimization)) { + if (_value <= std::numeric_limits::max() && _value >= std::numeric_limits::min()) { + Buffer.Write(ESaveVariableType::t_s64_op8); + Buffer.Write(_value); + return; + } + if (_value <= std::numeric_limits::max() && _value >= std::numeric_limits::min()) { + Buffer.Write(ESaveVariableType::t_s64_op16); + Buffer.Write(_value); + return; + } + if (_value <= std::numeric_limits::max() && _value >= std::numeric_limits::min()) { + Buffer.Write(ESaveVariableType::t_s64_op32); + Buffer.Write(_value); + return; + } + } + Buffer.Write(ESaveVariableType::t_s64); + Buffer.Write(_value); +} + +void CSaveVariableU32::Write(CMemoryBuffer& Buffer) +{ + if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseIntOptimization)) { + if (_value <= std::numeric_limits::max()) { + Buffer.Write(ESaveVariableType::t_u32_op8); + Buffer.Write(_value); + return; + } + if (_value <= std::numeric_limits::max()) { + Buffer.Write(ESaveVariableType::t_u32_op16); + Buffer.Write(_value); + return; + } + } + Buffer.Write(ESaveVariableType::t_u32); + Buffer.Write(_value); +} + +void CSaveVariableS32::Write(CMemoryBuffer& Buffer) +{ + if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseIntOptimization)) { + if (_value <= std::numeric_limits::max() && _value >= std::numeric_limits::min()) { + Buffer.Write(ESaveVariableType::t_s32_op8); + Buffer.Write(_value); + return; + } + if (_value <= std::numeric_limits::max() && _value >= std::numeric_limits::min()) { + Buffer.Write(ESaveVariableType::t_s32_op16); + Buffer.Write(_value); + return; + } + } + Buffer.Write(ESaveVariableType::t_s32); + Buffer.Write(_value); +} + +void CSaveVariableU16::Write(CMemoryBuffer& Buffer) +{ + if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseIntOptimization)) { + if (_value <= std::numeric_limits::max()) { + Buffer.Write(ESaveVariableType::t_u16_op8); + Buffer.Write(_value); + return; + } + } + Buffer.Write(ESaveVariableType::t_u16); + Buffer.Write(_value); +} + +void CSaveVariableS16::Write(CMemoryBuffer& Buffer) +{ + if (CSaveManager::GetInstance().TestFlag(CSaveManager::ESaveManagerFlagsGeneral::EUseIntOptimization)) { + if (_value <= std::numeric_limits::max() && _value >= std::numeric_limits::min()) { + Buffer.Write(ESaveVariableType::t_s16_op8); + Buffer.Write(_value); + return; + } + } + Buffer.Write(ESaveVariableType::t_s16); + Buffer.Write(_value); +} + +void CSaveVariableU8::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_u8); + Buffer.Write(_value); +} + +void CSaveVariableS8::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_s8); + Buffer.Write(_value); +} + +void CSaveVariableString::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_string); + CSaveManager::GetInstance().ConditionalWriteString(_value, Buffer); +} + +void CSaveVariableMatrix::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_matrix); + Buffer.Write(_value._11); Buffer.Write(_value._12); Buffer.Write(_value._13); Buffer.Write(_value._14); + Buffer.Write(_value._21); Buffer.Write(_value._22); Buffer.Write(_value._23); Buffer.Write(_value._24); + Buffer.Write(_value._31); Buffer.Write(_value._32); Buffer.Write(_value._33); Buffer.Write(_value._34); + Buffer.Write(_value._41); Buffer.Write(_value._42); Buffer.Write(_value._43); Buffer.Write(_value._44); +} + +void CSaveVariableClientID::Write(CMemoryBuffer& Buffer) +{ + Buffer.Write(ESaveVariableType::t_clientID); + Buffer.Write(_value.value()); +} diff --git a/src/xrCore/Save/SaveVariables.h b/src/xrCore/Save/SaveVariables.h index 2ed4d32e18..c6cb08f085 100644 --- a/src/xrCore/Save/SaveVariables.h +++ b/src/xrCore/Save/SaveVariables.h @@ -3,6 +3,8 @@ #include "../xrCore/_types.h" #include "../xrCore/_vector4.h" +class CMemoryBuffer; + enum class XRCORE_API ESaveVariableType : u8 { t_bool, t_float, @@ -74,6 +76,7 @@ class XRCORE_API CSaveVariableArray : virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_array; } virtual bool IsArray() { return true; } + virtual void Write(CMemoryBuffer& Buffer) override; u64 GetSize() { return _size; } ISaveable* GetCurrentElement() { VERIFY(_currentReadPos < _size); return _array[_currentReadPos]; } @@ -95,6 +98,7 @@ class XRCORE_API CSaveVariableBool: CSaveVariableBool(bool Value): _value(Value){} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_bool; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableFloat : @@ -110,6 +114,7 @@ class XRCORE_API CSaveVariableFloat : CSaveVariableFloat(float Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_float; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableDouble : @@ -125,6 +130,7 @@ class XRCORE_API CSaveVariableDouble : CSaveVariableDouble(double Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_double; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableVec3 : @@ -140,6 +146,7 @@ class XRCORE_API CSaveVariableVec3 : CSaveVariableVec3(const Fvector& Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_vec3; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableVec4 : @@ -155,6 +162,7 @@ class XRCORE_API CSaveVariableVec4 : CSaveVariableVec4(const Fvector4& Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_vec4; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableU64 : @@ -170,6 +178,7 @@ class XRCORE_API CSaveVariableU64 : CSaveVariableU64(u64 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_u64; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableS64 : @@ -185,6 +194,7 @@ class XRCORE_API CSaveVariableS64 : CSaveVariableS64(s64 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_s64; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableU32 : @@ -200,6 +210,7 @@ class XRCORE_API CSaveVariableU32 : CSaveVariableU32(u32 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_u32; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableS32 : @@ -215,6 +226,7 @@ class XRCORE_API CSaveVariableS32 : CSaveVariableS32(s32 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_s32; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableU16 : @@ -230,6 +242,7 @@ class XRCORE_API CSaveVariableU16 : CSaveVariableU16(u16 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_u16; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableS16 : @@ -245,6 +258,7 @@ class XRCORE_API CSaveVariableS16 : CSaveVariableS16(s16 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_s16; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableU8 : @@ -260,6 +274,7 @@ class XRCORE_API CSaveVariableU8 : CSaveVariableU8(u8 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_u8; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableS8 : @@ -275,6 +290,7 @@ class XRCORE_API CSaveVariableS8 : CSaveVariableS8(s8 Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_s8; } + virtual void Write(CMemoryBuffer& Buffer) override; }; /*class CSaveVariableFloatQ16 : @@ -395,6 +411,7 @@ class XRCORE_API CSaveVariableString : CSaveVariableString(LPCSTR Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_string; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableMatrix : @@ -410,6 +427,7 @@ class XRCORE_API CSaveVariableMatrix : CSaveVariableMatrix(const Fmatrix& Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_matrix; } + virtual void Write(CMemoryBuffer& Buffer) override; }; class XRCORE_API CSaveVariableClientID : @@ -425,6 +443,7 @@ class XRCORE_API CSaveVariableClientID : CSaveVariableClientID(ClientID Value) : _value(Value) {} virtual ESaveVariableType GetVariableType() override { return ESaveVariableType::t_clientID; } + virtual void Write(CMemoryBuffer& Buffer) override; }; struct SSaveVariableGetter { diff --git a/src/xrGame/GameObject.cpp b/src/xrGame/GameObject.cpp index 42b3737fa9..5837282495 100644 --- a/src/xrGame/GameObject.cpp +++ b/src/xrGame/GameObject.cpp @@ -46,7 +46,7 @@ CGameObject::CGameObject () { m_ai_obstacle = 0; - m_ScriptBinderComponent = xr_make_unique(); + m_ScriptBinderComponent = xr_make_unique(this); init (); //----------------------------------------- diff --git a/src/xrGame/alife_storage_manager.cpp b/src/xrGame/alife_storage_manager.cpp index 2865d55481..cbea3cd186 100644 --- a/src/xrGame/alife_storage_manager.cpp +++ b/src/xrGame/alife_storage_manager.cpp @@ -21,6 +21,7 @@ #include "saved_game_wrapper.h" #include "../xrEngine/IGame_Persistent.h" #include "autosave_manager.h" +#include "Save/SaveManager.h" XRCORE_API string_path g_bug_report_file; @@ -58,7 +59,11 @@ void CALifeStorageManager::save (LPCSTR save_name_no_check, bool update_name) if (ai().script_engine().functor("save_manager.BeforeSaveEvent", funct)) funct((LPCSTR)save_name); - CSaveObjectSave* SaveObj = new CSaveObjectSave(); + + string_path temp; + FS.update_path(temp, "$game_saves$", m_save_name); + + CSaveObjectSave* SaveObj = CSaveManager::GetInstance().BeginSave(); { header().Save(SaveObj); time_manager().Save(SaveObj); @@ -66,8 +71,9 @@ void CALifeStorageManager::save (LPCSTR save_name_no_check, bool update_name) objects().Save(SaveObj); registry().Save(SaveObj); } + CSaveManager::GetInstance().WriteSavedData(temp); - u32 source_count; + /*u32 source_count; u32 dest_count; void *dest_data; { @@ -99,7 +105,7 @@ void CALifeStorageManager::save (LPCSTR save_name_no_check, bool update_name) Msg ("* Game %s is successfully saved to file '%s' (%d bytes compressed to %d)",m_save_name,temp,source_count,dest_count + 4); #else // DEBUG Msg ("* Game %s is successfully saved to file '%s'",m_save_name,temp); -#endif // DEBUG +#endif*/ // DEBUG if (!update_name) xr_strcpy (m_save_name,save); diff --git a/src/xrGame/script_binder.cpp b/src/xrGame/script_binder.cpp index 80639e83ed..3e4dda4e73 100644 --- a/src/xrGame/script_binder.cpp +++ b/src/xrGame/script_binder.cpp @@ -21,8 +21,9 @@ // comment next string when commiting //#define DBG_DISABLE_SCRIPTS -CScriptBinder::CScriptBinder () +CScriptBinder::CScriptBinder (CGameObject* Owner) { + m_Owner = Owner; init (); } @@ -77,7 +78,7 @@ void CScriptBinder::reload (LPCSTR section) return; } - CGameObject *game_object = smart_cast(this); + CGameObject *game_object = m_Owner; try { lua_function (game_object ? game_object->lua_game_object() : 0); diff --git a/src/xrGame/script_binder.h b/src/xrGame/script_binder.h index c6ec34ec5f..f380610da4 100644 --- a/src/xrGame/script_binder.h +++ b/src/xrGame/script_binder.h @@ -13,13 +13,15 @@ class CSE_Abstract; class CScriptBinderObject; class NET_Packet; class CSaveObject; +class CGameObject; class CScriptBinder { protected: CScriptBinderObject *m_object; + CGameObject* m_Owner; public: - CScriptBinder (); + CScriptBinder (CGameObject* Owner); virtual ~CScriptBinder (); void init (); void clear (); diff --git a/src/xrScripts/exports/SaveSystem_script.cpp b/src/xrScripts/exports/SaveSystem_script.cpp index 733b3a92db..974b5db7e4 100644 --- a/src/xrScripts/exports/SaveSystem_script.cpp +++ b/src/xrScripts/exports/SaveSystem_script.cpp @@ -98,10 +98,6 @@ namespace CSaveObject_script { void BeginChunk(CSaveObject* Object, LPCSTR ChunkName) { Object->BeginChunk(ChunkName); } - - void FindChunk(CSaveObject* Object, LPCSTR ChunkName) { - Object->BeginChunk(ChunkName); - } } using namespace luabind; @@ -151,12 +147,10 @@ void SaveSystemScript::script_register(lua_State* L) class_("SaveObjectSave") .def("GetCurrentChunk", &CSaveObject::GetCurrentChunk) .def("BeginChunk", &CSaveObject_script::BeginChunk) - .def("FindChunk", &CSaveObject_script::FindChunk) .def("EndChunk", &CSaveObject::EndChunk), class_("SaveObjectLoad") .def("GetCurrentChunk", &CSaveObject::GetCurrentChunk) .def("BeginChunk", &CSaveObject_script::BeginChunk) - .def("FindChunk", &CSaveObject_script::FindChunk) .def("EndChunk", &CSaveObject::EndChunk) ]; }