#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>
#include "action.h"
+namespace Msp {
+namespace DemoScene {
+
class Demo;
class Sequencer
{
private:
Demo &demo;
+ float base_beat;
public:
Loader(Sequencer &, Demo &);
private:
+ void base(float);
void define_action(const std::string &);
void instant(float);
+ void repeat(float, float, unsigned);
void segment(float, float);
};
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>
Msp::RefPtr<T> act = new T;
load_sub(*act, demo);
- action = act;
+ act->validate();
+ action = act.release();
+ action_loaded();
}
-template<typename T>
-void Sequencer::SegmentLoader::action()
-{
- Msp::RefPtr<T> act = new T;
- load_sub(*act, demo);
- obj.add_action(*act, start_beat, end_beat);
- obj.anonymous_actions.push_back(act.release());
-}
+} // namespace DemoScene
+} // namespace Msp
#endif