Added FloatNode and smart save/load of definition tree
Node children are now saved with their name, and if a child is not found, it is skipped. This will allow for backward/forward compatibility of saves.
This commit is contained in:
parent
6062c755b5
commit
0fc10fd28b
15 changed files with 319 additions and 34 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include "DefinitionNode.h"
|
#include "DefinitionNode.h"
|
||||||
|
|
||||||
|
#include "Logs.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
|
||||||
DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name):
|
DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name):
|
||||||
|
@ -72,20 +73,57 @@ std::string DefinitionNode::toString(int indent) const
|
||||||
|
|
||||||
void DefinitionNode::save(PackStream* stream) const
|
void DefinitionNode::save(PackStream* stream) const
|
||||||
{
|
{
|
||||||
stream->write(name);
|
int children_count = (int)children.size();
|
||||||
|
stream->write(&children_count);
|
||||||
|
|
||||||
for (auto child: children)
|
for (auto child: children)
|
||||||
{
|
{
|
||||||
|
stream->write(child->name);
|
||||||
|
|
||||||
|
int child_size = child->getStreamSize();
|
||||||
|
if (child_size >= 0)
|
||||||
|
{
|
||||||
|
stream->write(&child_size);
|
||||||
child->save(stream);
|
child->save(stream);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Child size not known, write it to a temporary stream to know it
|
||||||
|
Logs::debug() << "Unknown size for child " << child->name << ", unefficient writing to temporary stream" << std::endl;
|
||||||
|
PackStream substream;
|
||||||
|
child->save(&substream);
|
||||||
|
stream->writeFromBuffer(substream, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::load(PackStream* stream)
|
void DefinitionNode::load(PackStream* stream)
|
||||||
{
|
{
|
||||||
name = stream->readString();
|
int children_count;
|
||||||
for (auto child: children)
|
|
||||||
|
stream->read(&children_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < children_count; i++)
|
||||||
{
|
{
|
||||||
|
std::string child_name = stream->readString();
|
||||||
|
|
||||||
|
int child_size;
|
||||||
|
stream->read(&child_size);
|
||||||
|
|
||||||
|
DefinitionNode *child = findChildByName(child_name);
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
// TODO type check
|
||||||
child->load(stream);
|
child->load(stream);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO Ask subclass if it can instanciate a child
|
||||||
|
// Else skip length of unknown child
|
||||||
|
stream->skipBytes(child_size);
|
||||||
|
Logs::warning() << "Skipped unknown child '" << child_name << "'" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::copy(DefinitionNode* destination) const
|
void DefinitionNode::copy(DefinitionNode* destination) const
|
||||||
|
@ -122,6 +160,23 @@ void DefinitionNode::removeChild(DefinitionNode* child)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qWarning("Trying to remove not found child '%s' from '%s'", child->name.c_str(), name.c_str());
|
Logs::warning() << "Trying to remove not found child '" << child->name << "' from '" << name << "'" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefinitionNode *DefinitionNode::findChildByName(const std::string name)
|
||||||
|
{
|
||||||
|
for (auto child: children)
|
||||||
|
{
|
||||||
|
if (child->name == name)
|
||||||
|
{
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DefinitionNode::getStreamSize() const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,15 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void addChild(DefinitionNode* child);
|
void addChild(DefinitionNode* child);
|
||||||
void removeChild(DefinitionNode* child);
|
void removeChild(DefinitionNode* child);
|
||||||
|
virtual DefinitionNode *findChildByName(const std::string name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size in bytes this child will consume when serialized to a stream.
|
||||||
|
*
|
||||||
|
* Return -1 if it can't be known. In this case, the saving will be done in a temporary
|
||||||
|
* stream to know the exact size, which will not be very efficient.
|
||||||
|
*/
|
||||||
|
int getStreamSize() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DefinitionNode* parent;
|
DefinitionNode* parent;
|
||||||
|
|
35
src/definition/FloatNode.cpp
Normal file
35
src/definition/FloatNode.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include "FloatNode.h"
|
||||||
|
|
||||||
|
#include "PackStream.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
FloatNode::FloatNode(DefinitionNode* parent, const std::string &name, double value):
|
||||||
|
DefinitionNode(parent, name), value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FloatNode::toString(int indent) const
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
stream << DefinitionNode::toString(indent) << " " << value;
|
||||||
|
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloatNode::save(PackStream *stream) const
|
||||||
|
{
|
||||||
|
stream->write(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloatNode::load(PackStream *stream)
|
||||||
|
{
|
||||||
|
stream->read(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloatNode::copy(DefinitionNode *destination) const
|
||||||
|
{
|
||||||
|
// TODO type check
|
||||||
|
|
||||||
|
((FloatNode *)destination)->value = value;
|
||||||
|
}
|
32
src/definition/FloatNode.h
Normal file
32
src/definition/FloatNode.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef FLOATNODE_H
|
||||||
|
#define FLOATNODE_H
|
||||||
|
|
||||||
|
#include "definition_global.h"
|
||||||
|
|
||||||
|
#include "DefinitionNode.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Node with a single floating point numeric value, for the definition tree.
|
||||||
|
*/
|
||||||
|
class DEFINITIONSHARED_EXPORT FloatNode: public DefinitionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FloatNode(DefinitionNode* parent, const std::string &name, double value = 0.0);
|
||||||
|
|
||||||
|
inline double getValue() const {return value;}
|
||||||
|
|
||||||
|
virtual std::string toString(int indent) const override;
|
||||||
|
virtual void save(PackStream* stream) const override;
|
||||||
|
virtual void load(PackStream* stream) override;
|
||||||
|
virtual void copy(DefinitionNode* destination) const override;
|
||||||
|
private:
|
||||||
|
double value;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FLOATNODE_H
|
|
@ -21,7 +21,11 @@ void Layers::save(PackStream *stream) const
|
||||||
int layer_count = (int)layers.size();
|
int layer_count = (int)layers.size();
|
||||||
stream->write(&layer_count);
|
stream->write(&layer_count);
|
||||||
|
|
||||||
DefinitionNode::save(stream);
|
for (int i = 0; i < layer_count; i++)
|
||||||
|
{
|
||||||
|
stream->write(layers[i]->getName());
|
||||||
|
layers[i]->save(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layers::load(PackStream *stream)
|
void Layers::load(PackStream *stream)
|
||||||
|
@ -36,10 +40,13 @@ void Layers::load(PackStream *stream)
|
||||||
clear();
|
clear();
|
||||||
for (int i = 0; i < layer_count; i++)
|
for (int i = 0; i < layer_count; i++)
|
||||||
{
|
{
|
||||||
addLayer();
|
int position = addLayer();
|
||||||
|
if (position >= 0)
|
||||||
|
{
|
||||||
|
layers[position]->setName(stream->readString());
|
||||||
|
layers[position]->load(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DefinitionNode::load(stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layers::copy(DefinitionNode* destination_) const
|
void Layers::copy(DefinitionNode* destination_) const
|
||||||
|
@ -171,3 +178,26 @@ void Layers::clear()
|
||||||
removeLayer(0);
|
removeLayer(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefinitionNode *Layers::findChildByName(const std::string name)
|
||||||
|
{
|
||||||
|
DefinitionNode *result = DefinitionNode::findChildByName(name);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int position = addLayer();
|
||||||
|
if (position >= 0)
|
||||||
|
{
|
||||||
|
result = getLayer(position);
|
||||||
|
result->setName(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ public:
|
||||||
void moveLayer(DefinitionNode* layer, int new_position);
|
void moveLayer(DefinitionNode* layer, int new_position);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual DefinitionNode *findChildByName(const std::string name) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LayerConstructor layer_constructor;
|
LayerConstructor layer_constructor;
|
||||||
int max_layer_count;
|
int max_layer_count;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "TerrainHeightMap.h"
|
#include "TerrainHeightMap.h"
|
||||||
#include "NoiseGenerator.h"
|
#include "NoiseGenerator.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
|
||||||
TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
||||||
DefinitionNode(parent, "terrain")
|
DefinitionNode(parent, "terrain")
|
||||||
|
@ -15,6 +16,7 @@ TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
||||||
addChild(height_map);
|
addChild(height_map);
|
||||||
|
|
||||||
water_height = -0.3;
|
water_height = -0.3;
|
||||||
|
_water_height = new FloatNode(this, "water_height", -0.3);
|
||||||
|
|
||||||
_height_noise = new NoiseGenerator;
|
_height_noise = new NoiseGenerator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ public:
|
||||||
NoiseGenerator* _height_noise;
|
NoiseGenerator* _height_noise;
|
||||||
double _min_height;
|
double _min_height;
|
||||||
double _max_height;
|
double _max_height;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FloatNode *_water_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ SOURCES += \
|
||||||
PaintedGrid.cpp \
|
PaintedGrid.cpp \
|
||||||
PaintedGridBrush.cpp \
|
PaintedGridBrush.cpp \
|
||||||
PaintedGridData.cpp \
|
PaintedGridData.cpp \
|
||||||
DefinitionNode.cpp
|
DefinitionNode.cpp \
|
||||||
|
FloatNode.cpp
|
||||||
|
|
||||||
HEADERS +=\
|
HEADERS +=\
|
||||||
definition_global.h \
|
definition_global.h \
|
||||||
|
@ -50,7 +51,8 @@ HEADERS +=\
|
||||||
PaintedGrid.h \
|
PaintedGrid.h \
|
||||||
PaintedGridBrush.h \
|
PaintedGridBrush.h \
|
||||||
PaintedGridData.h \
|
PaintedGridData.h \
|
||||||
DefinitionNode.h
|
DefinitionNode.h \
|
||||||
|
FloatNode.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace definition {
|
namespace definition {
|
||||||
class DefinitionNode;
|
class DefinitionNode;
|
||||||
|
class FloatNode;
|
||||||
class Scenery;
|
class Scenery;
|
||||||
class CameraDefinition;
|
class CameraDefinition;
|
||||||
class SurfaceMaterial;
|
class SurfaceMaterial;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
|
||||||
|
#include "Logs.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -7,15 +8,15 @@
|
||||||
PackStream::PackStream()
|
PackStream::PackStream()
|
||||||
{
|
{
|
||||||
file = NULL;
|
file = NULL;
|
||||||
stream = NULL;
|
buffer = new QByteArray();
|
||||||
|
stream = new QDataStream(buffer, QIODevice::WriteOnly);
|
||||||
|
stream->setVersion(QDataStream::Qt_5_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackStream::~PackStream()
|
PackStream::~PackStream()
|
||||||
{
|
{
|
||||||
if (stream)
|
delete buffer;
|
||||||
{
|
|
||||||
delete stream;
|
delete stream;
|
||||||
}
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
delete file;
|
delete file;
|
||||||
|
@ -24,7 +25,7 @@ PackStream::~PackStream()
|
||||||
|
|
||||||
bool PackStream::bindToFile(const std::string &filepath, bool write)
|
bool PackStream::bindToFile(const std::string &filepath, bool write)
|
||||||
{
|
{
|
||||||
if (not file and not stream)
|
if (not file)
|
||||||
{
|
{
|
||||||
file = new QFile(QString::fromStdString(filepath));
|
file = new QFile(QString::fromStdString(filepath));
|
||||||
if (not file->open(write ? QIODevice::WriteOnly : QIODevice::ReadOnly))
|
if (not file->open(write ? QIODevice::WriteOnly : QIODevice::ReadOnly))
|
||||||
|
@ -32,14 +33,28 @@ bool PackStream::bindToFile(const std::string &filepath, bool write)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream = new QDataStream(file);
|
QDataStream *new_stream = new QDataStream(file);
|
||||||
|
if (new_stream)
|
||||||
|
{
|
||||||
|
delete stream;
|
||||||
|
stream = new_stream;
|
||||||
|
stream->setVersion(QDataStream::Qt_5_2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return stream != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackStream::write(const int *value)
|
void PackStream::write(const int *value)
|
||||||
{
|
{
|
||||||
if (stream and value)
|
if (value)
|
||||||
{
|
{
|
||||||
*stream << *value;
|
*stream << *value;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +62,7 @@ void PackStream::write(const int *value)
|
||||||
|
|
||||||
void PackStream::write(const double *value)
|
void PackStream::write(const double *value)
|
||||||
{
|
{
|
||||||
if (stream and value)
|
if (value)
|
||||||
{
|
{
|
||||||
*stream << *value;
|
*stream << *value;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +70,7 @@ void PackStream::write(const double *value)
|
||||||
|
|
||||||
void PackStream::write(const char *value, int max_length)
|
void PackStream::write(const char *value, int max_length)
|
||||||
{
|
{
|
||||||
if (stream and value)
|
if (value)
|
||||||
{
|
{
|
||||||
int length = qstrlen(value);
|
int length = qstrlen(value);
|
||||||
*stream << QString::fromUtf8(value, length > max_length ? max_length : length);
|
*stream << QString::fromUtf8(value, length > max_length ? max_length : length);
|
||||||
|
@ -63,16 +78,30 @@ void PackStream::write(const char *value, int max_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackStream::write(const std::string &value)
|
void PackStream::write(const std::string &value)
|
||||||
{
|
|
||||||
if (stream)
|
|
||||||
{
|
{
|
||||||
*stream << QString::fromStdString(value);
|
*stream << QString::fromStdString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackStream::writeFromBuffer(const PackStream &other, bool prepend_size)
|
||||||
|
{
|
||||||
|
if (other.file)
|
||||||
|
{
|
||||||
|
Logs::error() << "Try to write from a substream bound to a file: " << other.file->fileName().toStdString() << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prepend_size)
|
||||||
|
{
|
||||||
|
int buffer_size = (int)other.buffer->size();
|
||||||
|
write(&buffer_size);
|
||||||
|
}
|
||||||
|
stream->writeRawData(other.buffer->data(), other.buffer->size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackStream::read(int* value)
|
void PackStream::read(int* value)
|
||||||
{
|
{
|
||||||
if (stream and value and not stream->atEnd())
|
if (value and not stream->atEnd())
|
||||||
{
|
{
|
||||||
int output;
|
int output;
|
||||||
*stream >> output;
|
*stream >> output;
|
||||||
|
@ -82,7 +111,7 @@ void PackStream::read(int* value)
|
||||||
|
|
||||||
void PackStream::read(double* value)
|
void PackStream::read(double* value)
|
||||||
{
|
{
|
||||||
if (stream and value and not stream->atEnd())
|
if (value and not stream->atEnd())
|
||||||
{
|
{
|
||||||
double output;
|
double output;
|
||||||
*stream >> output;
|
*stream >> output;
|
||||||
|
@ -92,7 +121,7 @@ void PackStream::read(double* value)
|
||||||
|
|
||||||
void PackStream::read(char* value, int max_length)
|
void PackStream::read(char* value, int max_length)
|
||||||
{
|
{
|
||||||
if (stream and value and not stream->atEnd())
|
if (value and not stream->atEnd())
|
||||||
{
|
{
|
||||||
QString output;
|
QString output;
|
||||||
*stream >> output;
|
*stream >> output;
|
||||||
|
@ -103,7 +132,7 @@ void PackStream::read(char* value, int max_length)
|
||||||
|
|
||||||
std::string PackStream::readString()
|
std::string PackStream::readString()
|
||||||
{
|
{
|
||||||
if (stream and not stream->atEnd())
|
if (not stream->atEnd())
|
||||||
{
|
{
|
||||||
QString output;
|
QString output;
|
||||||
*stream >> output;
|
*stream >> output;
|
||||||
|
@ -124,3 +153,8 @@ void PackStream::skip(const double &value, int count)
|
||||||
{
|
{
|
||||||
stream->skipRawData(sizeof(value) * count);
|
stream->skipRawData(sizeof(value) * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void paysages::system::PackStream::skipBytes(int bytes)
|
||||||
|
{
|
||||||
|
stream->skipRawData(bytes);
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,15 @@ public:
|
||||||
void write(const char *value, const int max_length);
|
void write(const char *value, const int max_length);
|
||||||
void write(const std::string &value);
|
void write(const std::string &value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of another stream into this one.
|
||||||
|
*
|
||||||
|
* The other stream must not have been bound to a file (still a memory buffer).
|
||||||
|
*
|
||||||
|
* If *prepend_size* is true, an integer will be written on front with the number of bytes written.
|
||||||
|
*/
|
||||||
|
void writeFromBuffer(const PackStream &other, bool prepend_size = false);
|
||||||
|
|
||||||
void read(int *value);
|
void read(int *value);
|
||||||
void read(double *value);
|
void read(double *value);
|
||||||
void read(char *value, int max_length);
|
void read(char *value, int max_length);
|
||||||
|
@ -34,9 +43,11 @@ public:
|
||||||
|
|
||||||
void skip(const int &value, int count=1);
|
void skip(const int &value, int count=1);
|
||||||
void skip(const double &value, int count=1);
|
void skip(const double &value, int count=1);
|
||||||
|
void skipBytes(int bytes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFile *file;
|
QFile *file;
|
||||||
|
QByteArray *buffer;
|
||||||
QDataStream *stream;
|
QDataStream *stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "BaseTestCase.h"
|
#include "BaseTestCase.h"
|
||||||
|
|
||||||
#include "DefinitionNode.h"
|
#include "DefinitionNode.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
#include "PackStream.h"
|
||||||
|
|
||||||
TEST(DefinitionNode, toString)
|
TEST(DefinitionNode, toString)
|
||||||
{
|
{
|
||||||
|
@ -33,3 +35,40 @@ TEST(DefinitionNode, attachDetach)
|
||||||
|
|
||||||
delete root;
|
delete root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DefinitionNode, saveLoad)
|
||||||
|
{
|
||||||
|
PackStream *stream;
|
||||||
|
|
||||||
|
DefinitionNode* before = new DefinitionNode(NULL, "root");
|
||||||
|
DefinitionNode* before1 = new DefinitionNode(before, "before1");
|
||||||
|
FloatNode* before11 = new FloatNode(before1, "before11", 2.1);
|
||||||
|
FloatNode* before12 = new FloatNode(before1, "before12", -4.3);
|
||||||
|
DefinitionNode* before2 = new DefinitionNode(before, "before2");
|
||||||
|
DefinitionNode* before21 = new DefinitionNode(before2, "before21");
|
||||||
|
FloatNode* before22 = new FloatNode(before2, "before22");
|
||||||
|
FloatNode* before3 = new FloatNode(before, "before3", 6.7);
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack", true);
|
||||||
|
before->save(stream);
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
// Same definition tree, but with missing nodes, and added ones
|
||||||
|
DefinitionNode* after = new DefinitionNode(NULL, "root");
|
||||||
|
DefinitionNode* after1 = new DefinitionNode(after, "before1");
|
||||||
|
FloatNode* after12 = new FloatNode(after1, "before12");
|
||||||
|
FloatNode* after13 = new FloatNode(after1, "before13");
|
||||||
|
FloatNode* after3 = new FloatNode(after, "before3");
|
||||||
|
FloatNode* after4 = new FloatNode(after, "before4");
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack");
|
||||||
|
after->load(stream);
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
EXPECT_DOUBLE_EQ(-4.3, after12->getValue());
|
||||||
|
EXPECT_DOUBLE_EQ(0.0, after13->getValue());
|
||||||
|
EXPECT_DOUBLE_EQ(6.7, after3->getValue());
|
||||||
|
EXPECT_DOUBLE_EQ(0.0, after4->getValue());
|
||||||
|
}
|
||||||
|
|
|
@ -77,3 +77,31 @@ TEST(Layers, maxLayerCount)
|
||||||
layers1.addLayer();
|
layers1.addLayer();
|
||||||
EXPECT_EQ(2, layers1.count());
|
EXPECT_EQ(2, layers1.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Layers, saveLoad)
|
||||||
|
{
|
||||||
|
PackStream *stream;
|
||||||
|
|
||||||
|
Layers layers1(NULL, "test", _construc1);
|
||||||
|
layers1.addLayer();
|
||||||
|
layers1.addLayer();
|
||||||
|
ASSERT_EQ(2, layers1.count());
|
||||||
|
layers1.getLayer(0)->setName("first");
|
||||||
|
layers1.getLayer(1)->setName("second");
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack", true);
|
||||||
|
layers1.save(stream);
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
Layers layers2(NULL, "test", _construc1);
|
||||||
|
|
||||||
|
stream = new PackStream();
|
||||||
|
stream->bindToFile("/tmp/test_paysages_pack");
|
||||||
|
layers2.load(stream);
|
||||||
|
delete stream;
|
||||||
|
|
||||||
|
ASSERT_EQ(2, layers2.count());
|
||||||
|
EXPECT_EQ("first", layers2.getLayer(0)->getName());
|
||||||
|
EXPECT_EQ("second", layers2.getLayer(1)->getName());
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "BaseTestCase.h"
|
#include "BaseTestCase.h"
|
||||||
|
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
TEST(Scenery, saveGlobal)
|
TEST(Scenery, saveGlobal)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue