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>
18 class Loader: public Msp::DataFile::ObjectLoader<Sequencer>
24 Loader(Sequencer &, Demo &);
27 void define_action(const std::string &);
29 void segment(float, float);
33 class ActionDefLoader;
36 class RegisteredAction
39 typedef void (ActionDefLoader::*DefLoaderFunc)();
40 typedef void (SegmentLoader::*LoaderFunc)();
42 virtual ~RegisteredAction() { }
43 virtual DefLoaderFunc get_def_loader_func() const = 0;
44 virtual LoaderFunc get_loader_func() const = 0;
48 class RegisteredActionType: public RegisteredAction
51 virtual DefLoaderFunc get_def_loader_func() const;
52 virtual LoaderFunc get_loader_func() const;
55 class ActionDefLoader: public Msp::DataFile::ObjectLoader<Sequencer>
59 Msp::RefPtr<Action> action;
62 ActionDefLoader(Sequencer &, Demo &);
64 Action *get_action() { return action.release(); }
67 virtual void finished();
73 friend class RegisteredActionType;
83 class SegmentLoader: public Msp::DataFile::ObjectLoader<Sequencer>
91 SegmentLoader(Sequencer &, float, float, Demo &);
97 void apply(const std::string &);
100 friend class RegisteredActionType;
104 sigc::signal<void> signal_finished;
107 std::map<std::string, RegisteredAction *> action_types;
108 std::map<std::string, Action *> named_actions;
109 std::vector<Action *> anonymous_actions;
111 Msp::Time::TimeDelta secs_per_beat;
112 std::vector<Action *> static_actions;
113 std::vector<Segment> segments;
114 std::vector<Segment>::const_iterator begin;
115 std::vector<Segment>::const_iterator end;
121 Sequencer(float = 120.0f);
124 void register_action_type(const std::string &);
126 void set_beats_per_minute(float);
127 float get_beats_per_minute() const { return Msp::Time::min/secs_per_beat; }
128 void add_static_action(Action &);
129 void add_action(Action &, float, float);
133 void tick(const Msp::Time::TimeDelta &);
135 void advance_to(float);
136 void update_next_event();
138 float get_current_beat() const { return beat; }
142 inline void Sequencer::register_action_type(const std::string &n)
144 if(action_types.count(n))
145 throw Msp::key_error(n);
147 action_types[n] = new RegisteredActionType<T>;
151 Sequencer::RegisteredAction::DefLoaderFunc Sequencer::RegisteredActionType<T>::get_def_loader_func() const
153 return &ActionDefLoader::action_def<T>;
157 Sequencer::RegisteredAction::LoaderFunc Sequencer::RegisteredActionType<T>::get_loader_func() const
159 return &SegmentLoader::action<T>;
163 void Sequencer::ActionDefLoader::action_def()
166 throw std::runtime_error("Only one action per definition is allowed");
168 Msp::RefPtr<T> act = new T;
169 load_sub(*act, demo);
174 void Sequencer::SegmentLoader::action()
176 Msp::RefPtr<T> act = new T;
177 load_sub(*act, demo);
178 obj.add_action(*act, start_beat, end_beat);
179 obj.anonymous_actions.push_back(act.release());