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)
#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>
};
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;
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
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;
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>
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