summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assetFactory/modelFactory.cpp17
-rw-r--r--assetFactory/modelFactory.h9
-rw-r--r--assetFactory/object.cpp22
-rw-r--r--assetFactory/object.h13
-rw-r--r--assetFactory/use.cpp20
-rw-r--r--assetFactory/use.h12
-rw-r--r--res/brush47.xml15
-rw-r--r--test/Jamfile.jam2
-rw-r--r--test/test-modelFactory.cpp23
9 files changed, 129 insertions, 4 deletions
diff --git a/assetFactory/modelFactory.cpp b/assetFactory/modelFactory.cpp
index 4c25e48..2642900 100644
--- a/assetFactory/modelFactory.cpp
+++ b/assetFactory/modelFactory.cpp
@@ -2,7 +2,10 @@
#include "cuboid.h"
#include "cylinder.h"
#include "modelFactoryMesh_fwd.h"
+#include "object.h"
#include "plane.h"
+#include "saxParse-persistence.h"
+#include <filesystem.h>
ModelFactory::ModelFactory() :
shapes {
@@ -12,3 +15,17 @@ ModelFactory::ModelFactory() :
}
{
}
+
+std::shared_ptr<ModelFactory>
+ModelFactory::loadXML(const std::filesystem::path & filename)
+{
+ filesystem::FileStar file {filename.c_str(), "r"};
+ return Persistence::SAXParsePersistence {}.loadState<std::shared_ptr<ModelFactory>>(file);
+}
+
+bool
+ModelFactory::persist(Persistence::PersistenceStore & store)
+{
+ using MapObjects = Persistence::MapByMember<Shapes, Object>;
+ return STORE_TYPE && STORE_NAME_HELPER("object", shapes, MapObjects);
+}
diff --git a/assetFactory/modelFactory.h b/assetFactory/modelFactory.h
index f2b1b48..94db055 100644
--- a/assetFactory/modelFactory.h
+++ b/assetFactory/modelFactory.h
@@ -1,12 +1,19 @@
#pragma once
+#include "persistence.h"
#include "shape.h"
+#include <filesystem>
-class ModelFactory {
+class ModelFactory : public Persistence::Persistable {
public:
using Shapes = std::map<std::string, Shape::CPtr, std::less<>>;
ModelFactory();
+ [[nodiscard]] static std::shared_ptr<ModelFactory> loadXML(const std::filesystem::path &);
Shapes shapes;
+
+private:
+ friend Persistence::SelectionPtrBase<std::shared_ptr<ModelFactory>, true>;
+ bool persist(Persistence::PersistenceStore & store) override;
};
diff --git a/assetFactory/object.cpp b/assetFactory/object.cpp
index 8b70676..faa9a17 100644
--- a/assetFactory/object.cpp
+++ b/assetFactory/object.cpp
@@ -15,3 +15,25 @@ Object::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) c
}
return faces;
}
+
+template<typename Container, typename Type> struct Appender : public Persistence::SelectionT<std::shared_ptr<Type>> {
+ Appender(Container & c) : Persistence::SelectionT<std::shared_ptr<Type>> {s}, container {c} { }
+ using Persistence::SelectionT<std::shared_ptr<Type>>::SelectionT;
+ void
+ endObject(Persistence::Stack & stk) override
+ {
+ container.emplace_back(s);
+ stk.pop();
+ }
+
+private:
+ std::shared_ptr<Type> s;
+ Container & container;
+};
+
+bool
+Object::persist(Persistence::PersistenceStore & store)
+{
+ using UseAppend = Appender<Use::Collection, Use>;
+ return STORE_TYPE && STORE_MEMBER(id) && STORE_NAME_HELPER("use", uses, UseAppend);
+}
diff --git a/assetFactory/object.h b/assetFactory/object.h
index da28c1f..1069f66 100644
--- a/assetFactory/object.h
+++ b/assetFactory/object.h
@@ -1,15 +1,26 @@
#pragma once
+#include "persistence.h"
#include "shape.h"
#include "stdTypeDefs.hpp"
#include "use.h"
-class Object : public StdTypeDefs<Object>, public Shape {
+class Object : public StdTypeDefs<Object>, public Shape, public Persistence::Persistable {
public:
+ Object() = default;
Object(std::string i);
CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override;
Use::Collection uses;
std::string id;
+
+private:
+ friend Persistence::SelectionPtrBase<std::shared_ptr<Object>, true>;
+ bool persist(Persistence::PersistenceStore & store) override;
+ std::string
+ getId() const override
+ {
+ return id;
+ };
};
diff --git a/assetFactory/use.cpp b/assetFactory/use.cpp
index d191329..21e26f3 100644
--- a/assetFactory/use.cpp
+++ b/assetFactory/use.cpp
@@ -1,4 +1,5 @@
#include "use.h"
+#include "modelFactory.h"
Shape::CreatedFaces
Use::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const
@@ -9,3 +10,22 @@ Use::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) cons
}
return faces;
}
+
+struct Lookup : public Persistence::SelectionV<Shape::CPtr> {
+ using Persistence::SelectionV<Shape::CPtr>::SelectionV;
+ using Persistence::SelectionV<Shape::CPtr>::setValue;
+ void
+ setValue(std::string && str) override
+ {
+ if (auto mf = std::dynamic_pointer_cast<const ModelFactory>(Persistence::sharedObjects.at("modelFactory"))) {
+ v = mf->shapes.at(str);
+ }
+ }
+};
+
+bool
+Use::persist(Persistence::PersistenceStore & store)
+{
+ return STORE_TYPE && STORE_HELPER(type, Lookup) && STORE_MEMBER(position) && STORE_MEMBER(scale)
+ && STORE_MEMBER(rotation);
+}
diff --git a/assetFactory/use.h b/assetFactory/use.h
index 28f5459..96f07f6 100644
--- a/assetFactory/use.h
+++ b/assetFactory/use.h
@@ -2,10 +2,11 @@
#include "faceController.h"
#include "modelFactoryMesh_fwd.h"
+#include "persistence.h"
#include "shape.h"
#include "stdTypeDefs.hpp"
-class Use : public StdTypeDefs<Use>, public Mutation {
+class Use : public StdTypeDefs<Use>, public Mutation, public Persistence::Persistable {
public:
using FaceControllers = std::map<std::string, FaceController>;
@@ -14,4 +15,13 @@ public:
Shape::CPtr type;
std::string colour;
FaceControllers faceControllers;
+
+private:
+ friend Persistence::SelectionPtrBase<std::shared_ptr<Use>, true>;
+ bool persist(Persistence::PersistenceStore & store) override;
+ std::string
+ getId() const override
+ {
+ return {};
+ };
};
diff --git a/res/brush47.xml b/res/brush47.xml
new file mode 100644
index 0000000..8f1d934
--- /dev/null
+++ b/res/brush47.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<ilt p.id="modelFactory">
+ <object id="wheel">
+ <use type="cylinder" position="0,0,0.571" scale="1.142,1.142,0.07" rotation="0,0,90"/>
+ </object>
+ <object id="axel">
+ <use type="wheel" position="0.717,0,0"/>
+ <use type="wheel" position="-0.717,0,0" rotation="0,90,0"/>
+ </object>
+ <object id="bogey">
+ <use type="axel" position="0,0,0"/>
+ <use type="axel" position="0,2,0"/>
+ <use type="axel" position="0,-2,0"/>
+ </object>
+</ilt>
diff --git a/test/Jamfile.jam b/test/Jamfile.jam
index d802975..027b880 100644
--- a/test/Jamfile.jam
+++ b/test/Jamfile.jam
@@ -52,6 +52,6 @@ run test-text.cpp ;
run test-enumDetails.cpp ;
run test-render.cpp : : : <library>test ;
run test-glContextBhvr.cpp ;
-run test-modelFactory.cpp : : : <library>test ;
+run test-modelFactory.cpp : -- : ../res/brush47.xml : <library>test ;
compile test-static-enumDetails.cpp ;
compile test-static-stream_support.cpp ;
diff --git a/test/test-modelFactory.cpp b/test/test-modelFactory.cpp
index 39362f5..8f2d56c 100644
--- a/test/test-modelFactory.cpp
+++ b/test/test-modelFactory.cpp
@@ -147,4 +147,27 @@ BOOST_AUTO_TEST_CASE(brush47)
render(20);
}
+BOOST_AUTO_TEST_CASE(brush47xml)
+{
+ auto mf = ModelFactory::loadXML(RESDIR "/brush47.xml");
+ BOOST_REQUIRE(mf);
+ BOOST_REQUIRE_EQUAL(6, mf->shapes.size());
+ BOOST_CHECK(mf->shapes.at("plane"));
+ BOOST_CHECK(mf->shapes.at("cylinder"));
+ BOOST_CHECK(mf->shapes.at("cuboid"));
+ BOOST_CHECK(mf->shapes.at("wheel"));
+ BOOST_CHECK(mf->shapes.at("axel"));
+ auto bogey = mf->shapes.at("bogey");
+ BOOST_REQUIRE(bogey);
+ auto bogeyObj = std::dynamic_pointer_cast<const Object>(bogey);
+ BOOST_CHECK_EQUAL(3, bogeyObj->uses.size());
+
+ FactoryMesh::Collection factoryMeshes;
+ std::transform(factoryMeshes.begin(), factoryMeshes.end(), std::back_inserter(meshes.objects),
+ [](const FactoryMesh::CPtr & factoryMesh) -> Mesh::Ptr {
+ return factoryMesh->createMesh();
+ });
+
+ render(20);
+}
BOOST_AUTO_TEST_SUITE_END();