]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a registry-based generic loader to Scene
authorMikko Rasa <tdb@tdb.fi>
Tue, 13 Apr 2021 20:53:43 +0000 (23:53 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 13 Apr 2021 20:53:43 +0000 (23:53 +0300)
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
source/render/orderedscene.h
source/render/scene.cpp
source/render/scene.h
source/render/simplescene.h
source/render/zsortedscene.h

index 78e3d3ca696f7ef091d68738ed375c8764478b26..2fb463c641b9d826e5f664f3d57d99d3deb339a7 100644 (file)
@@ -16,6 +16,9 @@ entirely occluded by others.
 */
 class OccludedScene: public Scene
 {
+public:
+       using Scene::Loader;
+
 private:
        struct OccludedRenderable
        {
index c41282b4df0b87ddbfe7fd6330e4483d4088c008..0ca1c4650697e7a845a7f54e09ebf9648f352ddd 100644 (file)
@@ -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<Renderable *> RenderableList;
 
index e6c62e802f8c9672fafce477d3eae50c9f2efaac..dd611536bf605ab8b53708e60831ba342560e54b 100644 (file)
@@ -1,8 +1,11 @@
 #include <msp/datafile/collection.h>
 #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<SimpleScene>("simple");
+               register_type<ZSortedScene>("zsorted");
+               register_type<OrderedScene>("ordered");
+               // TODO OccludedScene requires a collection as a constructor parameter
+               //register_type<OccludedScene>("occluded");
+       }
+       return registry;
+}
+
 
 Scene::Loader::Loader(Scene &s, Collection &c):
        DataFile::CollectionObjectLoader<Scene>(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
index 639a467fa849cb526c19ac31744b957f820af7ea..305bf62aefd5a2ed3fb4748bf9258772643eb52b 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_SCENE_H_
 
 #include <vector>
+#include <msp/core/typeregistry.h>
 #include <msp/datafile/objectloader.h>
 #include "matrix.h"
 #include "renderable.h"
@@ -17,7 +18,7 @@ InstancedScene and OrderedScene.
 */
 class Scene: public Renderable
 {
-public:
+protected:
        class Loader: public DataFile::CollectionObjectLoader<Scene>
        {
        public:
@@ -36,6 +37,38 @@ public:
                void object_tagged(const std::string &, const std::string &);
        };
 
+public:
+       class GenericLoader: public DataFile::Loader
+       {
+       private:
+               template<typename T>
+               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<GenericLoader::CreateScene, GenericLoader &> SceneRegistry;
+
 protected:
        // XXX If a loaded renderable is removed from the scene it needs to be removed from here as well
        std::vector<Renderable *> owned_data;
@@ -55,8 +88,32 @@ public:
 protected:
        bool setup_frustum(const Renderer &) const;
        bool frustum_cull(const Renderable &) const;
+
+public:
+       template<typename T>
+       static void register_type(const std::string &);
+private:
+       static SceneRegistry &get_scene_registry();
 };
 
+template<typename T>
+void Scene::register_type(const std::string &kw)
+{
+       get_scene_registry().register_type<T>(kw);
+}
+
+template<typename T>
+void Scene::GenericLoader::CreateScene<T>::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
 
index 04d466d791033290921663b97e3f4a48927d0ad9..2fb89a315113198160340b66139481f9d555aa28 100644 (file)
@@ -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<Renderable *> RenderableSet;
        typedef std::vector<Renderable *> RenderableArray;
index 24e06a6bd8f96ff56ce319a811d1cdcdea57db44..319cd8c35dfe2b17e93a84b836def3a23427409b 100644 (file)
@@ -27,6 +27,9 @@ renderables to have a matrix.
 */
 class ZSortedScene: public Scene
 {
+public:
+       using Scene::Loader;
+
 private:
        struct SortedRenderable
        {