X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fsequencer.h;h=d2a786987e8d58cd43a6d2b1b1bc83e2f7132884;hb=HEAD;hp=028c5d5161d5094ffb92bbd0f59b333ecfbabd6b;hpb=35332818fc6bad98fe77831de2c51a11326e31aa;p=libs%2Fdemoscene.git diff --git a/source/sequencer.h b/source/sequencer.h index 028c5d5..d2a7869 100644 --- a/source/sequencer.h +++ b/source/sequencer.h @@ -3,42 +3,67 @@ #include #include +#include +#include +#include +#include #include #include +#include "action.h" + +namespace Msp { +namespace DemoScene { + +class Demo; class Sequencer { public: - class Action + class Loader: public Msp::DataFile::ObjectLoader { - protected: - Action() { } + private: + Demo &demo; + float base_beat; + public: - virtual ~Action() { } + Loader(Sequencer &, Demo &); - virtual void start(float, float) { } - virtual void beat(int) { } - virtual void tick(float, float) { } - virtual void end(float) { } + private: + void base(float); + void define_action(const std::string &); + void instant(float); + void repeat(float, float, unsigned); + void segment(float, float); }; - class InterpolationAction: public Action +private: + class ActionDefLoader: public Msp::DataFile::ObjectLoader { protected: - bool hermite; - float start_beat; - float duration; + template + struct AddAction + { + static void add(ActionDefLoader &ldr, const std::string &kw) { ldr.add(kw, &ActionDefLoader::action_def); } + }; - InterpolationAction(bool = false); + Demo &demo; + Msp::RefPtr action; public: - virtual void start(float, float); - virtual void tick(float, float); - virtual void end(float); - virtual void interpolate(float, float) { } + ActionDefLoader(Sequencer &, Demo &); + + Action *get_action() { return action.release(); } + + protected: + virtual void action_loaded() { } + + private: + template + void action_def(); + + friend class Sequencer; }; -private: struct Segment { Action *action; @@ -46,10 +71,29 @@ private: float end_beat; }; + class SegmentLoader: public ActionDefLoader + { + private: + float start_beat; + float end_beat; + + public: + SegmentLoader(Sequencer &, float, float, Demo &); + + private: + virtual void action_loaded(); + + void apply(const std::string &); + }; + public: sigc::signal signal_finished; private: + DataFile::LoadableTypeRegistry action_registry; + std::map named_actions; + std::vector anonymous_actions; + Msp::Time::TimeDelta secs_per_beat; std::vector static_actions; std::vector segments; @@ -62,6 +106,10 @@ private: public: Sequencer(float = 120.0f); + template + void register_action_type(const std::string &); + void define_action(const std::string &, Action &); + void set_beats_per_minute(float); float get_beats_per_minute() const { return Msp::Time::min/secs_per_beat; } void add_static_action(Action &); @@ -77,4 +125,26 @@ public: float get_current_beat() const { return beat; } }; +template +inline void Sequencer::register_action_type(const std::string &n) +{ + action_registry.register_type(n); +} + +template +void Sequencer::ActionDefLoader::action_def() +{ + if(action) + throw std::runtime_error("Only one action per definition is allowed"); + + Msp::RefPtr act = new T; + load_sub(*act, demo); + act->validate(); + action = act.release(); + action_loaded(); +} + +} // namespace DemoScene +} // namespace Msp + #endif