1 #ifndef MSP_DEMOSCENE_SEQUENCER_H_
2 #define MSP_DEMOSCENE_SEQUENCER_H_
5 #include <sigc++/signal.h>
6 #include <msp/core/maputils.h>
7 #include <msp/core/refptr.h>
8 #include <msp/datafile/loadabletyperegistry.h>
9 #include <msp/datafile/objectloader.h>
10 #include <msp/time/timedelta.h>
11 #include <msp/time/timestamp.h>
22 class Loader: public Msp::DataFile::ObjectLoader<Sequencer>
29 Loader(Sequencer &, Demo &);
33 void define_action(const std::string &);
35 void repeat(float, float, unsigned);
36 void segment(float, float);
40 class ActionDefLoader: public Msp::DataFile::ObjectLoader<Sequencer>
46 static void add(ActionDefLoader &ldr, const std::string &kw) { ldr.add(kw, &ActionDefLoader::action_def<T>); }
50 Msp::RefPtr<Action> action;
53 ActionDefLoader(Sequencer &, Demo &);
55 Action *get_action() { return action.release(); }
58 virtual void action_loaded() { }
64 friend class Sequencer;
74 class SegmentLoader: public ActionDefLoader
81 SegmentLoader(Sequencer &, float, float, Demo &);
84 virtual void action_loaded();
86 void apply(const std::string &);
90 sigc::signal<void> signal_finished;
93 DataFile::LoadableTypeRegistry<ActionDefLoader, ActionDefLoader::AddAction> action_registry;
94 std::map<std::string, Action *> named_actions;
95 std::vector<Action *> anonymous_actions;
97 Msp::Time::TimeDelta secs_per_beat;
98 std::vector<Action *> static_actions;
99 std::vector<Segment> segments;
100 std::vector<Segment>::const_iterator begin;
101 std::vector<Segment>::const_iterator end;
107 Sequencer(float = 120.0f);
110 void register_action_type(const std::string &);
112 void set_beats_per_minute(float);
113 float get_beats_per_minute() const { return Msp::Time::min/secs_per_beat; }
114 void add_static_action(Action &);
115 void add_action(Action &, float, float);
119 void tick(const Msp::Time::TimeDelta &);
121 void advance_to(float);
122 void update_next_event();
124 float get_current_beat() const { return beat; }
128 inline void Sequencer::register_action_type(const std::string &n)
130 action_registry.register_type<T>(n);
134 void Sequencer::ActionDefLoader::action_def()
137 throw std::runtime_error("Only one action per definition is allowed");
139 Msp::RefPtr<T> act = new T;
140 load_sub(*act, demo);
142 action = act.release();
146 } // namespace DemoScene