]> git.tdb.fi Git - libs/demoscene.git/commitdiff
Use LoadableTypeRegistry to manage action types in Sequencer
authorMikko Rasa <tdb@tdb.fi>
Wed, 12 Jun 2019 12:37:02 +0000 (15:37 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 12 Jun 2019 12:37:02 +0000 (15:37 +0300)
source/sequencer.cpp
source/sequencer.h

index b4969bb30337182b35500b7ec378797bd8c1e86c..25182b8ef6ee7f4e623b83cfc942f8fe17339e86 100644 (file)
@@ -189,26 +189,22 @@ Sequencer::ActionDefLoader::ActionDefLoader(Sequencer &s, Demo &d):
        DataFile::ObjectLoader<Sequencer>(s),
        demo(d)
 {
-       for(const auto &t: obj.action_types)
-               add(t.first, t.second->get_def_loader_func());
-}
-
-void Sequencer::ActionDefLoader::finished()
-{
-       if(action)
-               action->validate();
+       obj.action_registry.add_all(*this);
 }
 
 
 Sequencer::SegmentLoader::SegmentLoader(Sequencer &s, float b, float e, Demo &d):
-       ObjectLoader<Sequencer>(s),
+       ActionDefLoader(s, d),
        start_beat(b),
-       end_beat(e),
-       demo(d)
+       end_beat(e)
 {
        add("apply", &SegmentLoader::apply);
-       for(const auto &t: obj.action_types)
-               add(t.first, t.second->get_loader_func());
+}
+
+void Sequencer::SegmentLoader::action_loaded()
+{
+       obj.add_action(*action, start_beat, end_beat);
+       obj.anonymous_actions.push_back(action.release());
 }
 
 void Sequencer::SegmentLoader::apply(const string &n)
index cb80f8f05d87b9a7d55583c1e7f70080f4ac1e2f..d01ee6865da58811745c592ee17d83b2cfde007e 100644 (file)
@@ -5,6 +5,7 @@
 #include <sigc++/signal.h>
 #include <msp/core/maputils.h>
 #include <msp/core/refptr.h>
+#include <msp/datafile/loadabletyperegistry.h>
 #include <msp/datafile/objectloader.h>
 #include <msp/time/timedelta.h>
 #include <msp/time/timestamp.h>
@@ -36,31 +37,15 @@ public:
        };
 
 private:
-       class ActionDefLoader;
-       class SegmentLoader;
-
-       class RegisteredAction
-       {
-       public:
-               typedef void (ActionDefLoader::*DefLoaderFunc)();
-               typedef void (SegmentLoader::*LoaderFunc)();
-
-               virtual ~RegisteredAction() { }
-               virtual DefLoaderFunc get_def_loader_func() const = 0;
-               virtual LoaderFunc get_loader_func() const = 0;
-       };
-
-       template<typename T>
-       class RegisteredActionType: public RegisteredAction
-       {
-       public:
-               virtual DefLoaderFunc get_def_loader_func() const;
-               virtual LoaderFunc get_loader_func() const;
-       };
-
        class ActionDefLoader: public Msp::DataFile::ObjectLoader<Sequencer>
        {
-       private:
+       protected:
+               template<typename T>
+               struct AddAction
+               {
+                       static void add(ActionDefLoader &ldr, const std::string &kw) { ldr.add(kw, &ActionDefLoader::action_def<T>); }
+               };
+
                Demo &demo;
                Msp::RefPtr<Action> action;
 
@@ -69,14 +54,14 @@ private:
 
                Action *get_action() { return action.release(); }
 
-       private:
-               virtual void finished();
+       protected:
+               virtual void action_loaded() { }
 
+       private:
                template<typename T>
                void action_def();
 
-               template<typename T>
-               friend class RegisteredActionType;
+               friend class Sequencer;
        };
 
        struct Segment
@@ -86,31 +71,26 @@ private:
                float end_beat;
        };
 
-       class SegmentLoader: public Msp::DataFile::ObjectLoader<Sequencer>
+       class SegmentLoader: public ActionDefLoader
        {
        private:
                float start_beat;
                float end_beat;
-               Demo &demo;
 
        public:
                SegmentLoader(Sequencer &, float, float, Demo &);
 
        private:
-               template<typename T>
-               void action();
+               virtual void action_loaded();
 
                void apply(const std::string &);
-
-               template<typename T>
-               friend class RegisteredActionType;
        };
 
 public:
        sigc::signal<void> signal_finished;
 
 private:
-       std::map<std::string, RegisteredAction *> action_types;
+       DataFile::LoadableTypeRegistry<ActionDefLoader, ActionDefLoader::AddAction> action_registry;
        std::map<std::string, Action *> named_actions;
        std::vector<Action *> anonymous_actions;
 
@@ -147,22 +127,7 @@ public:
 template<typename T>
 inline void Sequencer::register_action_type(const std::string &n)
 {
-       if(action_types.count(n))
-               throw Msp::key_error(n);
-
-       action_types[n] = new RegisteredActionType<T>;
-}
-
-template<typename T>
-Sequencer::RegisteredAction::DefLoaderFunc Sequencer::RegisteredActionType<T>::get_def_loader_func() const
-{
-       return &ActionDefLoader::action_def<T>;
-}
-
-template<typename T>
-Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType<T>::get_loader_func() const
-{
-       return &SegmentLoader::action<T>;
+       action_registry.register_type<T>(n);
 }
 
 template<typename T>
@@ -171,19 +136,11 @@ void Sequencer::ActionDefLoader::action_def()
        if(action)
                throw std::runtime_error("Only one action per definition is allowed");
 
-       Msp::RefPtr<T> act = new T;
-       load_sub(*act, demo);
-       action = act;
-}
-
-template<typename T>
-void Sequencer::SegmentLoader::action()
-{
        Msp::RefPtr<T> act = new T;
        load_sub(*act, demo);
        act->validate();
-       obj.add_action(*act, start_beat, end_beat);
-       obj.anonymous_actions.push_back(act.release());
+       action = act.release();
+       action_loaded();
 }
 
 } // namespace DemoScene