diff --git a/include/imodel.h b/include/imodel.h index d3dd3a7e5c..0a141cd1cb 100644 --- a/include/imodel.h +++ b/include/imodel.h @@ -112,6 +112,9 @@ class ModelNode }; typedef std::shared_ptr ModelNodePtr; +class IModelExporter; +typedef std::shared_ptr IModelExporterPtr; + /** * Exporter Interface for models (meshes). */ @@ -121,6 +124,11 @@ class IModelExporter virtual ~IModelExporter() {} + // Virtual constructor idiom. Use this method to generate a new + // instance of the implementing subclass. This way the model format manager + // can create a fresh instance of this exporter on demand. + virtual IModelExporterPtr clone() = 0; + // Returns the uppercase file extension this exporter is suitable for virtual const std::string& getExtension() const = 0; @@ -130,11 +138,13 @@ class IModelExporter // Export the model file to the given stream virtual void exportToStream(std::ostream& stream) = 0; }; -typedef std::shared_ptr IModelExporterPtr; /** * Importer interface for models. An importer must be able * to load a model (node) from the VFS. + * The importer instance shouldn't maintain an internal state, + * such that the same instance can be used to load several models, + * from different client code. */ class IModelImporter { diff --git a/plugins/model/AseExporter.cpp b/plugins/model/AseExporter.cpp index 822dfdd561..561c0b466d 100644 --- a/plugins/model/AseExporter.cpp +++ b/plugins/model/AseExporter.cpp @@ -12,6 +12,11 @@ namespace model AseExporter::AseExporter() {} +IModelExporterPtr AseExporter::clone() +{ + return std::make_shared(); +} + const std::string& AseExporter::getExtension() const { static std::string _extension("ASE"); diff --git a/plugins/model/AseExporter.h b/plugins/model/AseExporter.h index 51c4f5bc2a..7ff06bcd35 100644 --- a/plugins/model/AseExporter.h +++ b/plugins/model/AseExporter.h @@ -39,6 +39,8 @@ class AseExporter : public: AseExporter(); + IModelExporterPtr clone() override; + // Returns the uppercase file extension this exporter is suitable for const std::string& getExtension() const override; diff --git a/plugins/model/Makefile.am b/plugins/model/Makefile.am index f6ebe1957c..4e1619df8b 100644 --- a/plugins/model/Makefile.am +++ b/plugins/model/Makefile.am @@ -8,7 +8,8 @@ model_la_LDFLAGS = -module -avoid-version \ model_la_LIBADD = $(top_builddir)/libs/picomodel/libpicomodel.la \ $(top_builddir)/libs/math/libmath.la \ $(top_builddir)/libs/scene/libscenegraph.la -model_la_SOURCES = PicoModelNode.cpp \ +model_la_SOURCES = AseExporter.cpp \ + PicoModelNode.cpp \ RenderablePicoModel.cpp \ PicoModelLoader.cpp \ RenderablePicoSurface.cpp \ diff --git a/radiant/model/ModelFormatManager.cpp b/radiant/model/ModelFormatManager.cpp index 97c9038a16..88afe2dee9 100644 --- a/radiant/model/ModelFormatManager.cpp +++ b/radiant/model/ModelFormatManager.cpp @@ -102,7 +102,8 @@ IModelExporterPtr ModelFormatManager::getExporter(const std::string& extension) ExporterMap::const_iterator found = _exporters.find(extensionUpper); - return found != _exporters.end() ? found->second : IModelExporterPtr(); + // Return a cloned instance if we found a matching exporter + return found != _exporters.end() ? found->second->clone() : IModelExporterPtr(); } module::StaticModule _staticModelFormatManagerModule;