From 83ab54cf1339fcac560daa90496e6d4e956f7367 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 13 Apr 2021 23:53:43 +0300 Subject: [PATCH] Add a registry-based generic loader to Scene This is rather similar to the one in Material, but there's just enough differences and template complications that it isn't trivial to abstract. --- source/render/occludedscene.h | 3 ++ source/render/orderedscene.h | 3 ++ source/render/scene.cpp | 46 +++++++++++++++++++++++++++ source/render/scene.h | 59 ++++++++++++++++++++++++++++++++++- source/render/simplescene.h | 3 ++ source/render/zsortedscene.h | 3 ++ 6 files changed, 116 insertions(+), 1 deletion(-) diff --git a/source/render/occludedscene.h b/source/render/occludedscene.h index 78e3d3ca..2fb463c6 100644 --- a/source/render/occludedscene.h +++ b/source/render/occludedscene.h @@ -16,6 +16,9 @@ entirely occluded by others. */ class OccludedScene: public Scene { +public: + using Scene::Loader; + private: struct OccludedRenderable { diff --git a/source/render/orderedscene.h b/source/render/orderedscene.h index c41282b4..0ca1c465 100644 --- a/source/render/orderedscene.h +++ b/source/render/orderedscene.h @@ -13,6 +13,9 @@ in the middle and removing them are O(N) operations. */ class OrderedScene: public Scene { +public: + using Scene::Loader; + private: typedef std::list RenderableList; diff --git a/source/render/scene.cpp b/source/render/scene.cpp index e6c62e80..dd611536 100644 --- a/source/render/scene.cpp +++ b/source/render/scene.cpp @@ -1,8 +1,11 @@ #include #include "animatedobject.h" #include "camera.h" +#include "orderedscene.h" #include "renderer.h" #include "scene.h" +#include "simplescene.h" +#include "zsortedscene.h" using namespace std; @@ -73,6 +76,22 @@ bool Scene::frustum_cull(const Renderable &renderable) const return false; } +Scene::SceneRegistry &Scene::get_scene_registry() +{ + static SceneRegistry registry; + static bool initialized = false; + if(!initialized) + { + initialized = true; + register_type("simple"); + register_type("zsorted"); + register_type("ordered"); + // TODO OccludedScene requires a collection as a constructor parameter + //register_type("occluded"); + } + return registry; +} + Scene::Loader::Loader(Scene &s, Collection &c): DataFile::CollectionObjectLoader(s, &c), @@ -109,5 +128,32 @@ void Scene::Loader::object_tagged(const string &n, const string &t) obj.owned_data.push_back(anob.release()); } + +DataFile::Loader::ActionMap Scene::GenericLoader::shared_actions; + +Scene::GenericLoader::GenericLoader(DataFile::Collection &c): + coll(c), + scene(0), + scene_loader(0) +{ + set_actions(shared_actions); +} + +Scene::GenericLoader::~GenericLoader() +{ + delete scene; + delete scene_loader; +} + +void Scene::GenericLoader::init_actions() +{ + add("type", &GenericLoader::type); +} + +void Scene::GenericLoader::type(const DataFile::Symbol &sym) +{ + get_scene_registry().invoke(sym.name, *this); +} + } // namespace GL } // namespace Msp diff --git a/source/render/scene.h b/source/render/scene.h index 639a467f..305bf62a 100644 --- a/source/render/scene.h +++ b/source/render/scene.h @@ -2,6 +2,7 @@ #define MSP_GL_SCENE_H_ #include +#include #include #include "matrix.h" #include "renderable.h" @@ -17,7 +18,7 @@ InstancedScene and OrderedScene. */ class Scene: public Renderable { -public: +protected: class Loader: public DataFile::CollectionObjectLoader { public: @@ -36,6 +37,38 @@ public: void object_tagged(const std::string &, const std::string &); }; +public: + class GenericLoader: public DataFile::Loader + { + private: + template + struct CreateScene + { + void operator()(const std::string &, GenericLoader &) const; + }; + + DataFile::Collection &coll; + Scene *scene; + Loader *scene_loader; + + static ActionMap shared_actions; + + public: + GenericLoader(DataFile::Collection &); + ~GenericLoader(); + + Scene *get_scene() { Scene *s = scene; scene = 0; return s; } + private: + virtual void init_actions(); + + void type(const DataFile::Symbol &); + + friend class Scene; + }; + +private: + typedef TypeRegistry SceneRegistry; + protected: // XXX If a loaded renderable is removed from the scene it needs to be removed from here as well std::vector owned_data; @@ -55,8 +88,32 @@ public: protected: bool setup_frustum(const Renderer &) const; bool frustum_cull(const Renderable &) const; + +public: + template + static void register_type(const std::string &); +private: + static SceneRegistry &get_scene_registry(); }; +template +void Scene::register_type(const std::string &kw) +{ + get_scene_registry().register_type(kw); +} + +template +void Scene::GenericLoader::CreateScene::operator()(const std::string &, GenericLoader &ldr) const +{ + if(ldr.scene) + throw std::logic_error("Scene type was already specified"); + + T *scene = new T; + ldr.scene = scene; + ldr.scene_loader = new typename T::Loader(*scene, ldr.coll); + ldr.add_auxiliary_loader(*ldr.scene_loader); +} + } // namespace GL } // namespace Msp diff --git a/source/render/simplescene.h b/source/render/simplescene.h index 04d466d7..2fb89a31 100644 --- a/source/render/simplescene.h +++ b/source/render/simplescene.h @@ -12,6 +12,9 @@ A simple yet efficient scene. Rendering order is unspecified. */ class SimpleScene: public Scene { +public: + using Scene::Loader; + private: typedef std::set RenderableSet; typedef std::vector RenderableArray; diff --git a/source/render/zsortedscene.h b/source/render/zsortedscene.h index 24e06a6b..319cd8c3 100644 --- a/source/render/zsortedscene.h +++ b/source/render/zsortedscene.h @@ -27,6 +27,9 @@ renderables to have a matrix. */ class ZSortedScene: public Scene { +public: + using Scene::Loader; + private: struct SortedRenderable { -- 2.43.0