X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fsequencer.h;h=387cdde3cfbc0118047f045c37b5b8de3a198e3d;hb=2a957e891f86cc692ddbb80f71b1478ea03d5a4f;hp=028c5d5161d5094ffb92bbd0f59b333ecfbabd6b;hpb=35332818fc6bad98fe77831de2c51a11326e31aa;p=libs%2Fdemoscene.git diff --git a/source/sequencer.h b/source/sequencer.h index 028c5d5..387cdde 100644 --- a/source/sequencer.h +++ b/source/sequencer.h @@ -3,42 +3,72 @@ #include #include +#include +#include +#include #include #include +#include "action.h" + +class Demo; class Sequencer { public: - class Action + class Loader: public Msp::DataFile::ObjectLoader { - protected: - Action() { } + private: + Demo &demo; + 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 define_action(const std::string &); + void instant(float); + void segment(float, float); }; - class InterpolationAction: public Action +private: + class ActionDefLoader; + + class RegisteredAction { - protected: - bool hermite; - float start_beat; - float duration; + public: + typedef void (ActionDefLoader::*LoaderFunc)(); - InterpolationAction(bool = false); + virtual ~RegisteredAction() { } + virtual LoaderFunc get_loader_func() const = 0; + }; + template + class RegisteredActionType: public RegisteredAction + { public: - virtual void start(float, float); - virtual void tick(float, float); - virtual void end(float); - virtual void interpolate(float, float) { } + virtual LoaderFunc get_loader_func() const; + }; + + class ActionDefLoader: public Msp::DataFile::ObjectLoader + { + private: + Demo &demo; + Msp::RefPtr action; + + public: + ActionDefLoader(Sequencer &, Demo &); + + Action *get_action() { return action.release(); } + + private: + virtual void finished(); + + template + void action_def(); + + template + friend class RegisteredActionType; }; -private: struct Segment { Action *action; @@ -46,10 +76,26 @@ private: float end_beat; }; + class SegmentLoader: public Msp::DataFile::ObjectLoader + { + private: + float start_beat; + float end_beat; + + public: + SegmentLoader(Sequencer &, float, float); + + private: + void apply(const std::string &); + }; + public: sigc::signal signal_finished; private: + std::map action_types; + std::map named_actions; + Msp::Time::TimeDelta secs_per_beat; std::vector static_actions; std::vector segments; @@ -62,6 +108,9 @@ private: public: Sequencer(float = 120.0f); + template + void register_action_type(const std::string &); + 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 +126,30 @@ public: float get_current_beat() const { return beat; } }; +template +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; +} + +template +Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType::get_loader_func() const +{ + return &ActionDefLoader::action_def; +} + +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); + action = act; +} + #endif