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>
27 Loader(Sequencer &, Demo &);
30 void define_action(const std::string &);
32 void segment(float, float);
36 class ActionDefLoader;
39 class RegisteredAction
42 typedef void (ActionDefLoader::*DefLoaderFunc)();
43 typedef void (SegmentLoader::*LoaderFunc)();
45 virtual ~RegisteredAction() { }
46 virtual DefLoaderFunc get_def_loader_func() const = 0;
47 virtual LoaderFunc get_loader_func() const = 0;
51 class RegisteredActionType: public RegisteredAction
54 virtual DefLoaderFunc get_def_loader_func() const;
55 virtual LoaderFunc get_loader_func() const;
58 class ActionDefLoader: public Msp::DataFile::ObjectLoader<Sequencer>
62 Msp::RefPtr<Action> action;
65 ActionDefLoader(Sequencer &, Demo &);
67 Action *get_action() { return action.release(); }
70 virtual void finished();
76 friend class RegisteredActionType;
86 class SegmentLoader: public Msp::DataFile::ObjectLoader<Sequencer>
94 SegmentLoader(Sequencer &, float, float, Demo &);
100 void apply(const std::string &);
103 friend class RegisteredActionType;
107 sigc::signal<void> signal_finished;
110 std::map<std::string, RegisteredAction *> action_types;
111 std::map<std::string, Action *> named_actions;
112 std::vector<Action *> anonymous_actions;
114 Msp::Time::TimeDelta secs_per_beat;
115 std::vector<Action *> static_actions;
116 std::vector<Segment> segments;
117 std::vector<Segment>::const_iterator begin;
118 std::vector<Segment>::const_iterator end;
124 Sequencer(float = 120.0f);
127 void register_action_type(const std::string &);
129 void set_beats_per_minute(float);
130 float get_beats_per_minute() const { return Msp::Time::min/secs_per_beat; }
131 void add_static_action(Action &);
132 void add_action(Action &, float, float);
136 void tick(const Msp::Time::TimeDelta &);
138 void advance_to(float);
139 void update_next_event();
141 float get_current_beat() const { return beat; }
145 inline void Sequencer::register_action_type(const std::string &n)
147 if(action_types.count(n))
148 throw Msp::key_error(n);
150 action_types[n] = new RegisteredActionType<T>;
154 Sequencer::RegisteredAction::DefLoaderFunc Sequencer::RegisteredActionType<T>::get_def_loader_func() const
156 return &ActionDefLoader::action_def<T>;
160 Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType<T>::get_loader_func() const
162 return &SegmentLoader::action<T>;
166 void Sequencer::ActionDefLoader::action_def()
169 throw std::runtime_error("Only one action per definition is allowed");
171 Msp::RefPtr<T> act = new T;
172 load_sub(*act, demo);
177 void Sequencer::SegmentLoader::action()
179 Msp::RefPtr<T> act = new T;
180 load_sub(*act, demo);
181 obj.add_action(*act, start_beat, end_beat);
182 obj.anonymous_actions.push_back(act.release());
185 } // namespace DemoScene