X-Git-Url: http://git.tdb.fi/?p=libs%2Fdemoscene.git;a=blobdiff_plain;f=source%2Fsequencer.h;h=387cdde3cfbc0118047f045c37b5b8de3a198e3d;hp=e6eb2b7849381a4f4ad2f4a6196c71610040d186;hb=2a957e891f86cc692ddbb80f71b1478ea03d5a4f;hpb=da21a5a971c2dfa3fdd729c4f799908253bb3873 diff --git a/source/sequencer.h b/source/sequencer.h index e6eb2b7..387cdde 100644 --- a/source/sequencer.h +++ b/source/sequencer.h @@ -3,14 +3,72 @@ #include #include +#include +#include +#include #include #include +#include "action.h" -class Action; +class Demo; class Sequencer { +public: + class Loader: public Msp::DataFile::ObjectLoader + { + private: + Demo &demo; + + public: + Loader(Sequencer &, Demo &); + + private: + void define_action(const std::string &); + void instant(float); + void segment(float, float); + }; + private: + class ActionDefLoader; + + class RegisteredAction + { + public: + typedef void (ActionDefLoader::*LoaderFunc)(); + + virtual ~RegisteredAction() { } + virtual LoaderFunc get_loader_func() const = 0; + }; + + template + class RegisteredActionType: public RegisteredAction + { + public: + 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; + }; + struct Segment { Action *action; @@ -18,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; @@ -34,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 &); @@ -49,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