#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 RegisteredAction
- {
- public:
- typedef void (ActionDefLoader::*LoaderFunc)();
-
- virtual ~RegisteredAction() { }
- virtual LoaderFunc get_loader_func() const = 0;
- };
-
- template<typename T>
- class RegisteredActionType: public RegisteredAction
- {
- public:
- 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;
public:
- SegmentLoader(Sequencer &, float, float);
+ SegmentLoader(Sequencer &, float, float, Demo &);
private:
+ virtual void action_loaded();
+
void apply(const std::string &);
};
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;
Msp::Time::TimeDelta secs_per_beat;
std::vector<Action *> static_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::LoaderFunc Sequencer::RegisteredActionType<T>::get_loader_func() const
-{
- return &ActionDefLoader::action_def<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();
}
+} // namespace DemoScene
+} // namespace Msp
+
#endif