tested Serializable inheritance, fixed a bug in JSON deserialization

This commit is contained in:
Anselme 2017-01-22 14:44:06 +01:00
parent d1873c9de4
commit 8646073ae4
4 changed files with 114 additions and 32 deletions

View File

@ -6,67 +6,116 @@
#include <sstream>
#include <fstream>
class Foo : public Serializable
/**
* @brief Plop = Serializable mother class (incomplete)
*/
class Plop : public Serializable
{
public:
P_REFERENCE (Plop, myPlop)
};
/**
* @brief Bar = Serializable class Inheriting Plop
*/
class Bar : public Plop
{
public:
P_STRING (myTruc)
SERIALIZABLE(Bar,
CAST(myTruc),
CAST(myPlop))
Bar()
{
myTruc = "Je suis un Bar";
myPlop = this;
}
};
/**
* @brief Bar = Other Serializable class Inheriting Plop, referencing an instance of the Bar class
*/
class Foo : public Plop
{
public:
P_INT (myInt)
P_STRING (myString)
P_VECTOR_FLOAT(myFloatArray)
P_VEC3 (myVec3)
P_REFERENCE (Foo, myFoo)
SERIALIZABLE(Foo,
CAST(myInt),
CAST(myString),
CAST(myFloatArray),
CAST(myVec3),
CAST(myFoo))
CAST(myPlop))
Foo()
{
myInt = 3;
myString = "plop";
myString = "Je suis un Foo";
myFloatArray.push_back(1.5);
myFloatArray.push_back(1.3);
myFloatArray.push_back(2.5);
myFloatArray.push_back(6.2);
myVec3 = glm::vec3(0.1, 0, 5.4);
myFoo = this;
Bar* bar = new Bar();
bar->myPlop = nullptr;
myPlop = bar;
}
};
INIT_SERIALIZABLE(Bar)
INIT_SERIALIZABLE(Foo)
int main()
{
// init
Foo* f1 = new Foo();
f1->myString = "Hello, i am foo 1";
Foo* f2 = new Foo();
f2->myString = "How's it goin', my name is \"Foo 2\"";
f1->myFloatArray.clear();
f2->myVec3 = glm::vec3(1, 2, 3);
f1->myFoo = f2;
f2->myFoo = nullptr;
// testing polymorphism on Serializables
Foo* foo = new Foo();
// print before
std::cout << "Before :" << std::endl;
ObjectSaver printer;
printer.addObject(foo);
printer.saveAscii(std::cout);
// saving as binary
ObjectSaver saver;
saver.addObject(f1);
std::fstream outFile;
outFile.open("test.bin", std::ios_base::out);
saver.saveBinary(outFile);
outFile.close();
ObjectSaver saverBinary;
saverBinary.addObject(foo);
std::fstream outFileBinary;
outFileBinary.open("test.bin", std::ios_base::out);
saverBinary.saveBinary(outFileBinary);
outFileBinary.close();
// loading as binary
ObjectLoader loader;
std::fstream inFile;
inFile.open("test.bin", std::ios_base::in);
loader.loadBinary(inFile);
inFile.close();
ObjectLoader loaderBinary;
std::fstream inFileBinary;
inFileBinary.open("test.bin", std::ios_base::in);
loaderBinary.loadBinary(inFileBinary);
inFileBinary.close();
// print result
ObjectSaver printer;
for(Foo* f : loader.getObjects<Foo>())
// saving as json
ObjectSaver saverAscii;
for(Foo* f : loaderBinary.getObjects<Foo>())
saverAscii.addObject(f);
std::fstream outFileAscii;
outFileAscii.open("test.txt", std::ios_base::out);
saverAscii.saveAscii(outFileAscii);
outFileAscii.close();
// loading as json
ObjectLoader loaderAscii;
std::fstream inFileAscii;
inFileAscii.open("test.txt", std::ios_base::in);
loaderAscii.loadAscii(inFileAscii);
inFileAscii.close();
// print after
std::cout << "After :" << std::endl;
printer.clearObjects();
for(Foo* f : loaderAscii.getObjects<Foo>())
printer.addObject(f);
printer.saveAscii(std::cout);

View File

@ -110,6 +110,7 @@ public:
template <typename T>
class Property : public AbstractProperty
{
protected:
T m_value;
public:
Property(T val) : m_value(val) {}
@ -136,6 +137,7 @@ public:
template <typename T>
class Property<T*> : public AbstractProperty
{
protected:
T* m_value;
public:
Property(T* val) : m_value(val) {}
@ -166,6 +168,7 @@ public:
template <typename T>
class ArrayProperty : public AbstractArrayProperty
{
protected:
std::vector<T> m_value;
public:
ArrayProperty(const std::vector<T> &val) : m_value(val) {}

View File

@ -28,6 +28,17 @@ void ObjectSaver::addObject(Serializable *object)
}
}
void ObjectSaver::removeObject(Serializable *object)
{
if(object == nullptr)
return;
const std::string &type = object->getType();
ObjectType &objectsOfSameType = m_objects[type];
objectsOfSameType.erase(object);
if(objectsOfSameType.size() == 0)
m_objects.erase(type);
}
std::ostream& ObjectSaver::saveBinary(std::ostream& os)
{
// loop on serializable types
@ -87,9 +98,13 @@ std::ostream& ObjectSaver::saveBinary(std::ostream& os)
std::ostream& ObjectSaver::saveAscii(std::ostream& os)
{
os << "{" << std::endl;
int nbTypes = m_objects.size();
int currentType = 0;
// loop on serializable types
for(const std::pair<std::string, ObjectType> &type : m_objects)
{
++currentType;
// serialize type
os << "\t\"" << type.first << "\": [" << std::endl;
@ -144,7 +159,10 @@ std::ostream& ObjectSaver::saveAscii(std::ostream& os)
else
os << "," << std::endl;
}
if(nbTypes == currentType)
os << "\t]" << std::endl;
else
os << "\t]," << std::endl;
}
return os << "}" << std::endl;
}
@ -272,7 +290,7 @@ std::istream& ObjectLoader::loadAscii(std::istream& is)
Serializable* object = instancer();
objectsOfThatType.push_back(object);
PropertySet* properties = object->getProperties();
for(AbstractProperty* p : *properties)
for(AbstractProperty* p : *properties) // loop on the properties of this object
{
if(p->getPropertyType() == AbstractProperty::REFERENCE)
{
@ -284,7 +302,6 @@ std::istream& ObjectLoader::loadAscii(std::istream& is)
ss.ignore(1); // ,
Property<int> id; // id of the object
id.loadAscii(ss);
ss.ignore(1);
PendingReference ref;
ref.ptr = &(((Property<Serializable*>*)p)->getValueRef());
ref.type = type.getValueRef();
@ -322,19 +339,26 @@ std::istream& ObjectLoader::loadAscii(std::istream& is)
}
else
ss.ignore(6); // "null"
if(ss.peek() != ',')
if(ss.peek() == ',')
ss.ignore(1); // ,
}
ss.ignore(1); // ]
}
else
p->loadAscii(ss);
// loop on the properties of this object
if(p != properties->back())
ss.ignore(1); // ,
}
// loop on the objects of that type
ss.ignore(1); // }
if(ss.peek() == ',')
ss.ignore(1); // ,
}
// loop on serializable types
ss.ignore(1); // ]
if(ss.peek() == ',')
ss.ignore(1); // ,
}
buildReferences();
return is;

View File

@ -15,6 +15,12 @@ public:
template <typename T>
void addObject(T *object) { addObject((Serializable*)object); }
void removeObject(Serializable *object);
template <typename T>
void removeObject(T *object) { removeObject((Serializable*)object); }
void clearObjects() { m_objects.clear(); }
std::ostream& saveBinary(std::ostream& os);
std::ostream& saveAscii(std::ostream& os);
};