tested Serializable inheritance, fixed a bug in JSON deserialization
This commit is contained in:
parent
d1873c9de4
commit
8646073ae4
105
src/main.cpp
105
src/main.cpp
@ -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);
|
||||
|
||||
|
@ -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) {}
|
||||
|
@ -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;
|
||||
}
|
||||
os << "\t]" << 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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user