2 #include <msp/core/algorithm.h>
3 #include <msp/core/maputils.h>
4 #include <msp/core/raii.h>
6 #include "fadeoverlay.h"
15 Sequencer::Sequencer(float bpm):
20 set_beats_per_minute(bpm);
22 register_action_type<Animate>("animate");
23 register_action_type<FadeOverlay::Fade>("fade");
24 register_action_type<Stage::UseInView>("use_stage");
25 register_action_type<Stage::SetCamera>("set_camera");
28 void Sequencer::set_beats_per_minute(float bpm)
30 secs_per_beat = Time::min/bpm;
33 void Sequencer::add_static_action(Action &act)
35 static_actions.push_back(&act);
38 void Sequencer::add_action(Action &act, float sb, float eb)
41 throw invalid_argument("Sequencer::add_action");
47 auto i = find_if(segments, [=](const Segment &s){ return s.start_beat>sb; });
48 segments.insert(i, seg);
51 void Sequencer::start()
54 end = begin = segments.begin();
55 for(auto a: static_actions)
56 a->start(0, numeric_limits<float>::max());
57 float start_beat = beat;
59 advance_to(start_beat);
62 void Sequencer::seek(float b)
65 throw logic_error("Sequencer::seek");
73 void Sequencer::tick(const Time::TimeDelta &dt)
77 if(begin==segments.end())
80 advance_to(beat+dt/secs_per_beat);
83 void Sequencer::advance_to(float target_beat)
85 while(target_beat>next_event)
86 advance_to(next_event);
88 float prev_beat = beat;
91 while(end!=segments.end() && end->start_beat<=beat)
94 int ibeat = static_cast<int>(floor(beat));
95 bool do_beat = (ibeat!=static_cast<int>(floor(prev_beat)));
97 for(auto a: static_actions)
101 a->tick(beat, beat-prev_beat);
104 for(auto i=begin; i!=end; ++i)
106 if(i->start_beat>prev_beat)
107 i->action->start(i->start_beat, i->end_beat-i->start_beat);
109 i->action->beat(ibeat);
110 if(i->end_beat>=prev_beat)
112 float tick_beat = min(beat, i->end_beat);
113 i->action->tick(tick_beat, tick_beat-max(prev_beat, i->start_beat));
114 if(i->end_beat<=beat)
115 i->action->end(i->end_beat);
119 while(begin!=end && begin->end_beat<=beat)
122 if(target_beat>=next_event)
125 if(begin==segments.end())
126 signal_finished.emit();
129 void Sequencer::update_next_event()
131 next_event = numeric_limits<float>::max();
133 if(end!=segments.end())
134 next_event = min(next_event, end->start_beat);
136 for(auto i=begin; i!=end; ++i)
138 next_event = min(next_event, i->end_beat);
142 Sequencer::Loader::Loader(Sequencer &s, Demo &d):
143 DataFile::ObjectLoader<Sequencer>(s),
147 add("base", &Loader::base);
148 add("define_action", &Loader::define_action);
149 add("instant", &Loader::instant);
150 add("repeat", &Loader::repeat);
151 add("segment", &Loader::segment);
154 void Sequencer::Loader::base(float b)
156 SetForScope<float> set_base(base_beat, base_beat+b);
157 load_sub_with(*this);
160 void Sequencer::Loader::define_action(const string &n)
162 ActionDefLoader ldr(obj, demo);
164 obj.named_actions[n] = ldr.get_action();
167 void Sequencer::Loader::instant(float beat)
172 void Sequencer::Loader::repeat(float b, float d, unsigned n)
174 for(unsigned i=0; i<n; ++i)
176 SetForScope<float> set_base(base_beat, base_beat+b+i*d);
177 load_sub_with(*this);
181 void Sequencer::Loader::segment(float start, float end)
183 SegmentLoader ldr(obj, base_beat+start, base_beat+end, demo);
188 Sequencer::ActionDefLoader::ActionDefLoader(Sequencer &s, Demo &d):
189 DataFile::ObjectLoader<Sequencer>(s),
192 obj.action_registry.add_all(*this);
196 Sequencer::SegmentLoader::SegmentLoader(Sequencer &s, float b, float e, Demo &d):
197 ActionDefLoader(s, d),
201 add("apply", &SegmentLoader::apply);
204 void Sequencer::SegmentLoader::action_loaded()
206 obj.add_action(*action, start_beat, end_beat);
207 obj.anonymous_actions.push_back(action.release());
210 void Sequencer::SegmentLoader::apply(const string &n)
212 obj.add_action(*get_item(obj.named_actions, n), start_beat, end_beat);
215 } // namespace DemoScene