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 repeat(float, float, unsigned);
35 void segment(float, float);
39 class ActionDefLoader;
42 class RegisteredAction
45 typedef void (ActionDefLoader::*DefLoaderFunc)();
46 typedef void (SegmentLoader::*LoaderFunc)();
48 virtual ~RegisteredAction() { }
49 virtual DefLoaderFunc get_def_loader_func() const = 0;
50 virtual LoaderFunc get_loader_func() const = 0;
54 class RegisteredActionType: public RegisteredAction
57 virtual DefLoaderFunc get_def_loader_func() const;
58 virtual LoaderFunc get_loader_func() const;
61 class ActionDefLoader: public Msp::DataFile::ObjectLoader<Sequencer>
65 Msp::RefPtr<Action> action;
68 ActionDefLoader(Sequencer &, Demo &);
70 Action *get_action() { return action.release(); }
73 virtual void finished();
79 friend class RegisteredActionType;
89 class SegmentLoader: public Msp::DataFile::ObjectLoader<Sequencer>
97 SegmentLoader(Sequencer &, float, float, Demo &);
103 void apply(const std::string &);
106 friend class RegisteredActionType;
110 sigc::signal<void> signal_finished;
113 std::map<std::string, RegisteredAction *> action_types;
114 std::map<std::string, Action *> named_actions;
115 std::vector<Action *> anonymous_actions;
117 Msp::Time::TimeDelta secs_per_beat;
118 std::vector<Action *> static_actions;
119 std::vector<Segment> segments;
120 std::vector<Segment>::const_iterator begin;
121 std::vector<Segment>::const_iterator end;
127 Sequencer(float = 120.0f);
130 void register_action_type(const std::string &);
132 void set_beats_per_minute(float);
133 float get_beats_per_minute() const { return Msp::Time::min/secs_per_beat; }
134 void add_static_action(Action &);
135 void add_action(Action &, float, float);
139 void tick(const Msp::Time::TimeDelta &);
141 void advance_to(float);
142 void update_next_event();
144 float get_current_beat() const { return beat; }
148 inline void Sequencer::register_action_type(const std::string &n)
150 if(action_types.count(n))
151 throw Msp::key_error(n);
153 action_types[n] = new RegisteredActionType<T>;
157 Sequencer::RegisteredAction::DefLoaderFunc Sequencer::RegisteredActionType<T>::get_def_loader_func() const
159 return &ActionDefLoader::action_def<T>;
163 Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType<T>::get_loader_func() const
165 return &SegmentLoader::action<T>;
169 void Sequencer::ActionDefLoader::action_def()
172 throw std::runtime_error("Only one action per definition is allowed");
174 Msp::RefPtr<T> act = new T;
175 load_sub(*act, demo);
180 void Sequencer::SegmentLoader::action()
182 Msp::RefPtr<T> act = new T;
183 load_sub(*act, demo);
185 obj.add_action(*act, start_beat, end_beat);
186 obj.anonymous_actions.push_back(act.release());
189 } // namespace DemoScene