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/objectloader.h>
9 #include <msp/time/timedelta.h>
10 #include <msp/time/timestamp.h>
21 class Loader: public Msp::DataFile::ObjectLoader<Sequencer>
28 Loader(Sequencer &, Demo &);
32 void define_action(const std::string &);
34 void segment(float, float);
38 class ActionDefLoader;
41 class RegisteredAction
44 typedef void (ActionDefLoader::*DefLoaderFunc)();
45 typedef void (SegmentLoader::*LoaderFunc)();
47 virtual ~RegisteredAction() { }
48 virtual DefLoaderFunc get_def_loader_func() const = 0;
49 virtual LoaderFunc get_loader_func() const = 0;
53 class RegisteredActionType: public RegisteredAction
56 virtual DefLoaderFunc get_def_loader_func() const;
57 virtual LoaderFunc get_loader_func() const;
60 class ActionDefLoader: public Msp::DataFile::ObjectLoader<Sequencer>
64 Msp::RefPtr<Action> action;
67 ActionDefLoader(Sequencer &, Demo &);
69 Action *get_action() { return action.release(); }
72 virtual void finished();
78 friend class RegisteredActionType;
88 class SegmentLoader: public Msp::DataFile::ObjectLoader<Sequencer>
96 SegmentLoader(Sequencer &, float, float, Demo &);
102 void apply(const std::string &);
105 friend class RegisteredActionType;
109 sigc::signal<void> signal_finished;
112 std::map<std::string, RegisteredAction *> action_types;
113 std::map<std::string, Action *> named_actions;
114 std::vector<Action *> anonymous_actions;
116 Msp::Time::TimeDelta secs_per_beat;
117 std::vector<Action *> static_actions;
118 std::vector<Segment> segments;
119 std::vector<Segment>::const_iterator begin;
120 std::vector<Segment>::const_iterator end;
126 Sequencer(float = 120.0f);
129 void register_action_type(const std::string &);
131 void set_beats_per_minute(float);
132 float get_beats_per_minute() const { return Msp::Time::min/secs_per_beat; }
133 void add_static_action(Action &);
134 void add_action(Action &, float, float);
138 void tick(const Msp::Time::TimeDelta &);
140 void advance_to(float);
141 void update_next_event();
143 float get_current_beat() const { return beat; }
147 inline void Sequencer::register_action_type(const std::string &n)
149 if(action_types.count(n))
150 throw Msp::key_error(n);
152 action_types[n] = new RegisteredActionType<T>;
156 Sequencer::RegisteredAction::DefLoaderFunc Sequencer::RegisteredActionType<T>::get_def_loader_func() const
158 return &ActionDefLoader::action_def<T>;
162 Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType<T>::get_loader_func() const
164 return &SegmentLoader::action<T>;
168 void Sequencer::ActionDefLoader::action_def()
171 throw std::runtime_error("Only one action per definition is allowed");
173 Msp::RefPtr<T> act = new T;
174 load_sub(*act, demo);
179 void Sequencer::SegmentLoader::action()
181 Msp::RefPtr<T> act = new T;
182 load_sub(*act, demo);
183 obj.add_action(*act, start_beat, end_beat);
184 obj.anonymous_actions.push_back(act.release());
187 } // namespace DemoScene