X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fsequencer.h;h=f8137177bbd73c31d792a5f59299187a49d99fdd;hb=5296c1532980c5918ac91370e7dd670d673edb85;hp=e6eb2b7849381a4f4ad2f4a6196c71610040d186;hpb=8ffa42fba0e6a13286b465473fd399cac7c77dcf;p=libs%2Fdemoscene.git diff --git a/source/sequencer.h b/source/sequencer.h index e6eb2b7..f813717 100644 --- a/source/sequencer.h +++ b/source/sequencer.h @@ -3,14 +3,76 @@ #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 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 + class RegisteredActionType: public RegisteredAction + { + public: + virtual DefLoaderFunc get_def_loader_func() const; + 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 +80,34 @@ private: float end_beat; }; + class SegmentLoader: public Msp::DataFile::ObjectLoader + { + private: + float start_beat; + float end_beat; + Demo &demo; + + public: + SegmentLoader(Sequencer &, float, float, Demo &); + + private: + template + void action(); + + void apply(const std::string &); + + template + friend class RegisteredActionType; + }; + public: sigc::signal signal_finished; private: + std::map action_types; + std::map named_actions; + std::vector anonymous_actions; + Msp::Time::TimeDelta secs_per_beat; std::vector static_actions; std::vector segments; @@ -34,6 +120,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 +138,45 @@ 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::DefLoaderFunc Sequencer::RegisteredActionType::get_def_loader_func() const +{ + return &ActionDefLoader::action_def; +} + +template +Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType::get_loader_func() const +{ + return &SegmentLoader::action; +} + +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; +} + +template +void Sequencer::SegmentLoader::action() +{ + Msp::RefPtr act = new T; + load_sub(*act, demo); + obj.add_action(*act, start_beat, end_beat); + obj.anonymous_actions.push_back(act.release()); +} + #endif