2014-06-26 01:52:37 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
|
|
class Snapshotable
|
|
|
|
{
|
|
|
|
uint8_t* _stream;
|
|
|
|
uint32_t _position;
|
2014-07-01 16:44:01 +00:00
|
|
|
uint32_t _streamSize;
|
2014-06-26 01:52:37 +00:00
|
|
|
bool _saving;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void StreamState(bool saving) = 0;
|
|
|
|
|
2015-07-15 03:35:30 +00:00
|
|
|
void Stream(Snapshotable* snapshotable)
|
|
|
|
{
|
|
|
|
stringstream stream;
|
|
|
|
if(_saving) {
|
|
|
|
snapshotable->SaveSnapshot(&stream);
|
|
|
|
uint32_t size = (uint32_t)stream.tellp();
|
|
|
|
stream.seekg(0, ios::beg);
|
|
|
|
stream.seekp(0, ios::beg);
|
|
|
|
|
|
|
|
uint8_t *buffer = new uint8_t[size];
|
|
|
|
stream.read((char*)buffer, size);
|
|
|
|
Stream<uint32_t>(size);
|
|
|
|
StreamArray<uint8_t>(buffer, size);
|
|
|
|
delete[] buffer;
|
|
|
|
} else {
|
|
|
|
uint32_t size = 0;
|
|
|
|
Stream<uint32_t>(size);
|
|
|
|
|
2016-01-16 04:52:17 +00:00
|
|
|
if(_position + size <= _streamSize) {
|
|
|
|
uint8_t *buffer = new uint8_t[size];
|
|
|
|
StreamArray(buffer, size);
|
2015-07-15 03:35:30 +00:00
|
|
|
|
2016-01-16 04:52:17 +00:00
|
|
|
stream.write((char*)buffer, size);
|
|
|
|
stream.seekg(0, ios::beg);
|
|
|
|
stream.seekp(0, ios::beg);
|
|
|
|
snapshotable->LoadSnapshot(&stream);
|
|
|
|
delete[] buffer;
|
|
|
|
} else {
|
|
|
|
_position = _streamSize;
|
|
|
|
}
|
2015-07-15 03:35:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-26 01:52:37 +00:00
|
|
|
template<typename T>
|
|
|
|
void Stream(T &value)
|
|
|
|
{
|
|
|
|
if(_saving) {
|
|
|
|
uint8_t* bytes = (uint8_t*)&value;
|
|
|
|
int typeSize = sizeof(T);
|
|
|
|
for(int i = 0; i < typeSize; i++) {
|
|
|
|
_stream[_position++] = bytes[i];
|
|
|
|
}
|
|
|
|
} else {
|
2016-01-16 04:52:17 +00:00
|
|
|
if(_position + sizeof(T) <= _streamSize) {
|
|
|
|
value = *((T*)(_stream + _position));
|
|
|
|
_position += sizeof(T);
|
|
|
|
} else {
|
|
|
|
_position = _streamSize;
|
|
|
|
}
|
2014-06-26 01:52:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
void StreamArray(T* value, uint32_t length)
|
|
|
|
{
|
2016-01-29 03:34:23 +00:00
|
|
|
uint32_t typeSize = sizeof(T);
|
2014-06-26 01:52:37 +00:00
|
|
|
if(_saving) {
|
|
|
|
uint8_t* bytes = (uint8_t*)value;
|
|
|
|
for(uint32_t i = 0, len = length*typeSize; i < len; i++) {
|
|
|
|
_stream[_position++] = bytes[i];
|
|
|
|
}
|
|
|
|
} else {
|
2015-07-02 03:17:14 +00:00
|
|
|
for(uint32_t i = 0, len = length*typeSize; i < len; i++) {
|
2016-01-16 04:52:17 +00:00
|
|
|
if(_position < _streamSize) {
|
|
|
|
((uint8_t*)value)[i] = _stream[_position];
|
|
|
|
_position++;
|
|
|
|
} else {
|
|
|
|
((uint8_t*)value)[i] = 0;
|
|
|
|
_position = _streamSize;
|
|
|
|
}
|
2014-06-26 01:52:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2014-07-01 16:44:01 +00:00
|
|
|
void SaveSnapshot(ostream* file)
|
2014-06-26 01:52:37 +00:00
|
|
|
{
|
2016-01-25 02:54:05 +00:00
|
|
|
_stream = new uint8_t[0xFFFFF];
|
|
|
|
memset((char*)_stream, 0, 0xFFFFF);
|
2014-06-26 01:52:37 +00:00
|
|
|
_position = 0;
|
|
|
|
_saving = true;
|
|
|
|
|
|
|
|
StreamState(_saving);
|
2014-07-01 16:44:01 +00:00
|
|
|
file->write((char*)&_position, sizeof(_position));
|
|
|
|
file->write((char*)_stream, _position);
|
2014-06-26 01:52:37 +00:00
|
|
|
|
|
|
|
delete[] _stream;
|
|
|
|
}
|
|
|
|
|
2014-07-01 16:44:01 +00:00
|
|
|
void LoadSnapshot(istream* file)
|
2014-06-26 01:52:37 +00:00
|
|
|
{
|
2016-01-25 02:54:05 +00:00
|
|
|
_stream = new uint8_t[0xFFFFF];
|
|
|
|
memset((char*)_stream, 0, 0xFFFFF);
|
2014-06-26 01:52:37 +00:00
|
|
|
_position = 0;
|
|
|
|
_saving = false;
|
|
|
|
|
2014-07-01 16:44:01 +00:00
|
|
|
file->read((char*)&_streamSize, sizeof(_streamSize));
|
|
|
|
file->read((char*)_stream, _streamSize);
|
2014-06-26 01:52:37 +00:00
|
|
|
StreamState(_saving);
|
|
|
|
|
|
|
|
delete[] _stream;
|
|
|
|
}
|
|
|
|
};
|