enforced platform agnostic serialization + version barrier

This commit is contained in:
turanszkij
2016-06-22 00:04:03 +02:00
parent ecea57d528
commit dfb9bbb5f6
5 changed files with 345 additions and 66 deletions
+10 -1
View File
@@ -1,7 +1,10 @@
#include "wiArchive.h"
#include "wiHelper.h"
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
unsigned long __archiveVersion = 0;
uint64_t __archiveVersion = 1;
// this is the version number of which below the archive is not compatible with the current version
uint64_t __archiveVersionBarrier = 1;
wiArchive::wiArchive(const string& fileName, bool readMode):readMode(readMode),pos(0),DATA(nullptr)
{
@@ -18,6 +21,12 @@ wiArchive::wiArchive(const string& fileName, bool readMode):readMode(readMode),p
file.read(DATA, dataSize);
file.close();
(*this) >> version;
if (version < __archiveVersionBarrier)
{
stringstream ss("");
ss << "The archive version (" << version << ") is no longer supported!";
wiHelper::messageBox(ss.str(), "Error!");
}
}
}
else
+237 -36
View File
@@ -1,10 +1,11 @@
#pragma once
#include "CommonInclude.h"
#include <stdint.h>
class wiArchive
{
private:
unsigned long version;
uint64_t version;
fstream file;
bool readMode;
streamsize pos;
@@ -13,14 +14,122 @@ public:
wiArchive(const string& fileName, bool readMode = true);
~wiArchive();
unsigned long GetVersion() { return version; }
uint64_t GetVersion() { return version; }
bool IsReadMode() { return readMode; }
bool IsOpen();
void Close();
// It could be templated but we have to be extremely careful of different datasizes on different platforms
// because serialized data should be interchangeable!
// So providing exact copy operations for exact types enforces platform agnosticism
// Write data using file operations
template<typename T>
wiArchive& operator<<(const T& data)
wiArchive& operator<<(bool data)
{
uint32_t temp = (uint32_t)(data ? 1 : 0);
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(int data)
{
int64_t temp = (int64_t)data;
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(unsigned int data)
{
uint64_t temp = (uint64_t)data;
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(long data)
{
int64_t temp = (int64_t)data;
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(unsigned long data)
{
uint64_t temp = (uint64_t)data;
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(long long data)
{
int64_t temp = (int64_t)data;
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(unsigned long long data)
{
uint64_t temp = (uint64_t)data;
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&temp), sizeof(temp));
pos += sizeof(temp);
return *this;
}
wiArchive& operator<<(float data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(double data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(const XMFLOAT2& data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(const XMFLOAT3& data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(const XMFLOAT4& data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(const XMFLOAT3X3& data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(const XMFLOAT4X3& data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator<<(const XMFLOAT4X4& data)
{
file.seekp(pos);
file.write(reinterpret_cast<const char*>(&data), sizeof(data));
@@ -30,7 +139,7 @@ public:
wiArchive& operator<<(const string& data)
{
file.seekp(pos);
size_t len = data.length() + 1; // +1 for the null-terminator
uint64_t len = (uint64_t)(data.length() + 1); // +1 for the null-terminator
file.write(reinterpret_cast<const char*>(&len), sizeof(len));
pos += sizeof(len);
file.seekp(pos);
@@ -40,49 +149,141 @@ public:
}
// Read data using memory operations
template<typename T>
wiArchive& operator >> (T& data)
wiArchive& operator >> (bool& data)
{
memcpy(&data, reinterpret_cast<void*>((int)DATA + (int)pos), sizeof(data));
uint32_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (temp == 1);
return *this;
}
wiArchive& operator >> (int& data)
{
int64_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (int)temp;
return *this;
}
wiArchive& operator >> (unsigned int& data)
{
uint64_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (unsigned int)temp;
return *this;
}
wiArchive& operator >> (long& data)
{
int64_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (long)temp;
return *this;
}
wiArchive& operator >> (unsigned long& data)
{
uint64_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (unsigned long)temp;
return *this;
}
wiArchive& operator >> (long long& data)
{
int64_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (long long)temp;
return *this;
}
wiArchive& operator >> (unsigned long long& data)
{
uint64_t temp;
memcpy(&temp, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(temp));
pos += sizeof(temp);
data = (unsigned long long)temp;
return *this;
}
wiArchive& operator >> (float& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (double& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (XMFLOAT2& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (XMFLOAT3& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (XMFLOAT4& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (XMFLOAT3X3& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (XMFLOAT4X3& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (XMFLOAT4X4& data)
{
memcpy(&data, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), sizeof(data));
pos += sizeof(data);
return *this;
}
wiArchive& operator >> (string& data)
{
size_t len;
uint64_t len;
(*this) >> len;
char* str = new char[len];
memset(str, '\0', sizeof(char)*len);
memcpy(str, reinterpret_cast<void*>((int)DATA + (int)pos), sizeof(char)*len);
pos += sizeof(char)*len;
char* str = new char[(size_t)len];
memset(str, '\0', (size_t)(sizeof(char)*len));
memcpy(str, reinterpret_cast<void*>((uint64_t)DATA + (uint64_t)pos), (size_t)(sizeof(char)*len));
pos += (size_t)(sizeof(char)*len);
data = string(str);
delete[] str;
return *this;
}
//template<typename T>
//wiArchive& operator >> (T& data)
//{
// file.seekg(pos);
// file.read(reinterpret_cast<char*>(&data), sizeof(data));
// pos += sizeof(data);
// return *this;
//}
//wiArchive& operator >> (string& data)
//{
// file.seekg(pos);
// size_t len;
// file.read(reinterpret_cast<char*>(&len), sizeof(len));
// pos += sizeof(len);
// char* str = new char[len];
// memset(str, '\0', sizeof(char)*len);
// file.seekg(pos);
// file.read(str, sizeof(char)*len);
// pos += sizeof(char)*len;
// data = string(str);
// delete[] str;
// return *this;
//}
//private:
//
// template<typename T>
// wiArchive& operator<<(const T& data)
// {
// file.seekp(pos);
// file.write(reinterpret_cast<const char*>(&data), sizeof(data));
// pos += sizeof(data);
// return *this;
// }
// template<typename T>
// wiArchive& operator >> (T& data)
// {
// memcpy(&data, reinterpret_cast<void*>((int)DATA + (int)pos), sizeof(data));
// pos += sizeof(data);
// return *this;
// }
};
+94 -28
View File
@@ -1272,6 +1272,28 @@ void GenerateSPTree(wiSPTree*& tree, vector<Cullable*>& objects, int type){
tree->initialize(objects);
}
#pragma region SKINNEDVERTEX
void SkinnedVertex::Serialize(wiArchive& archive)
{
if (archive.IsReadMode())
{
archive >> pos;
archive >> nor;
archive >> tex;
archive >> bon;
archive >> wei;
}
else
{
archive << pos;
archive << nor;
archive << tex;
archive << bon;
archive << wei;
}
}
#pragma endregion
#pragma region SCENE
Scene::Scene()
{
@@ -1325,14 +1347,7 @@ void Scene::Update()
Cullable::Cullable():bounds(AABB())/*,lastSquaredDistMulThousand(0)*/{}
void Cullable::Serialize(wiArchive& archive)
{
if (archive.IsReadMode())
{
archive >> bounds;
}
else
{
archive << bounds;
}
bounds.Serialize(archive);
}
#pragma endregion
@@ -1435,7 +1450,9 @@ void Material::Serialize(wiArchive& archive)
archive >> refMapName;
archive >> textureName;
archive >> premultipliedTexture;
archive >> blendFlag;
int temp;
archive >> temp;
blendFlag = (BLENDMODE)temp;
archive >> normalMapName;
archive >> displacementMapName;
archive >> specularMapName;
@@ -1481,7 +1498,7 @@ void Material::Serialize(wiArchive& archive)
archive << refMapName;
archive << textureName;
archive << premultipliedTexture;
archive << blendFlag;
archive << (int)blendFlag;
archive << normalMapName;
archive << displacementMapName;
archive << specularMapName;
@@ -2001,7 +2018,7 @@ void Mesh::Serialize(wiArchive& archive)
SkinnedVertex tempVert;
for (size_t i = 0; i < vertexCount; ++i)
{
archive >> tempVert;
tempVert.Serialize(archive);
vertices.push_back(tempVert);
}
}
@@ -2082,7 +2099,9 @@ void Mesh::Serialize(wiArchive& archive)
}
archive >> renderable;
archive >> doubleSided;
archive >> stencilRef;
int temp;
archive >> temp;
stencilRef = (STENCILREF)temp;
archive >> calculatedAO;
archive >> trailInfo.base;
archive >> trailInfo.tip;
@@ -2094,8 +2113,8 @@ void Mesh::Serialize(wiArchive& archive)
archive >> massVG;
archive >> goalVG;
archive >> softVG;
archive >> aabb;
archive >> armatureName;
aabb.Serialize(archive);
}
else
{
@@ -2107,7 +2126,7 @@ void Mesh::Serialize(wiArchive& archive)
archive << vertices.size();
for (auto& x : vertices)
{
archive << x;
x.Serialize(archive);
}
}
// indices
@@ -2164,7 +2183,7 @@ void Mesh::Serialize(wiArchive& archive)
}
archive << renderable;
archive << doubleSided;
archive << stencilRef;
archive << (int)stencilRef;
archive << calculatedAO;
archive << trailInfo.base;
archive << trailInfo.tip;
@@ -2176,8 +2195,8 @@ void Mesh::Serialize(wiArchive& archive)
archive << massVG;
archive << goalVG;
archive << softVG;
archive << aabb;
archive << armatureName;
aabb.Serialize(archive);
}
}
#pragma endregion
@@ -2735,6 +2754,31 @@ AABB AABB::Merge(const AABB& a, const AABB& b)
{
return AABB(wiMath::Min(a.getMin(), b.getMin()), wiMath::Max(a.getMax(), b.getMax()));
}
void AABB::Serialize(wiArchive& archive)
{
if (archive.IsReadMode())
{
archive >> corners[0];
archive >> corners[1];
archive >> corners[2];
archive >> corners[3];
archive >> corners[4];
archive >> corners[5];
archive >> corners[6];
archive >> corners[7];
}
else
{
archive << corners[0];
archive << corners[1];
archive << corners[2];
archive << corners[3];
archive << corners[4];
archive << corners[5];
archive << corners[6];
archive << corners[7];
}
}
#pragma endregion
#pragma region SPHERE
@@ -2836,19 +2880,19 @@ void Bone::Serialize(wiArchive& archive)
archive >> tempCount;
for (size_t i = 0; i < tempCount; ++i)
{
archive >> tempKeyFrame;
tempKeyFrame.Serialize(archive);
aframes.keyframesRot.push_back(tempKeyFrame);
}
archive >> tempCount;
for (size_t i = 0; i < tempCount; ++i)
{
archive >> tempKeyFrame;
tempKeyFrame.Serialize(archive);
aframes.keyframesPos.push_back(tempKeyFrame);
}
archive >> tempCount;
for (size_t i = 0; i < tempCount; ++i)
{
archive >> tempKeyFrame;
tempKeyFrame.Serialize(archive);
aframes.keyframesSca.push_back(tempKeyFrame);
}
actionFrames.push_back(aframes);
@@ -2874,17 +2918,17 @@ void Bone::Serialize(wiArchive& archive)
archive << x.keyframesRot.size();
for (auto& y : x.keyframesRot)
{
archive << y;
y.Serialize(archive);
}
archive << x.keyframesPos.size();
for (auto& y : x.keyframesPos)
{
archive << y;
y.Serialize(archive);
}
archive << x.keyframesSca.size();
for (auto& y : x.keyframesSca)
{
archive << y;
y.Serialize(archive);
}
}
archive << recursivePose;
@@ -2896,6 +2940,22 @@ void Bone::Serialize(wiArchive& archive)
}
#pragma endregion
#pragma region KEYFRAME
void KeyFrame::Serialize(wiArchive& archive)
{
if (archive.IsReadMode())
{
archive >> data;
archive >> frameI;
}
else
{
archive << data;
archive << frameI;
}
}
#pragma endregion
#pragma region ANIMATIONLAYER
AnimationLayer::AnimationLayer()
{
@@ -2956,7 +3016,9 @@ void AnimationLayer::Serialize(wiArchive& archive)
archive >> blendFrames;
archive >> blendFact;
archive >> weight;
archive >> type;
int temp;
archive >> temp;
type = (ANIMATIONLAYER_TYPE)temp;
archive >> looped;
}
else
@@ -2965,7 +3027,7 @@ void AnimationLayer::Serialize(wiArchive& archive)
archive << blendFrames;
archive << blendFact;
archive << weight;
archive << type;
archive << (int)type;
archive << looped;
}
}
@@ -3573,7 +3635,9 @@ void Object::Serialize(wiArchive& archive)
if (archive.IsReadMode())
{
archive >> emitterType;
int temp;
archive >> temp;
emitterType = (EmitterType)temp;
archive >> transparency;
archive >> color;
archive >> rigidBody;
@@ -3604,7 +3668,7 @@ void Object::Serialize(wiArchive& archive)
}
else
{
archive << emitterType;
archive << (int)emitterType;
archive << transparency;
archive << color;
archive << rigidBody;
@@ -3744,7 +3808,9 @@ void Light::Serialize(wiArchive& archive)
archive >> noHalo;
archive >> shadow;
archive >> shadowBias;
archive >> type;
int temp;
archive >> temp;
type = (LightType)temp;
if (type == DIRECTIONAL)
{
shadowMaps_dirLight.resize(3);
@@ -3769,7 +3835,7 @@ void Light::Serialize(wiArchive& archive)
archive << noHalo;
archive << shadow;
archive << shadowBias;
archive << type;
archive << (int)type;
archive << lensFlareNames.size();
for (auto& x : lensFlareNames)
{
+3
View File
@@ -48,6 +48,7 @@ struct SkinnedVertex
bon=XMFLOAT4(0,0,0,0);
wei=XMFLOAT4(0,0,0,0);
}
void Serialize(wiArchive& archive);
};
struct Vertex
{
@@ -272,6 +273,7 @@ struct AABB{
bool intersects(const RAY& ray) const;
AABB operator* (float a);
static AABB Merge(const AABB& a, const AABB& b);
void Serialize(wiArchive& archive);
};
struct SPHERE{
float radius;
@@ -520,6 +522,7 @@ struct KeyFrame
frameI=newFrameI;
data=XMFLOAT4(x,y,z,w);
}
void Serialize(wiArchive& archive);
};
struct Action
{
+1 -1
View File
@@ -7,7 +7,7 @@ namespace wiVersion
// minor features, major bug fixes
const int minor = 8;
// minor bug fixes, alterations, refactors
const int revision = 18;
const int revision = 19;
long GetVersion()