2 #include <msp/core/algorithm.h>
3 #include <msp/core/maputils.h>
5 #include "fadeoverlay.h"
14 Sequencer::Sequencer(float bpm):
19 set_beats_per_minute(bpm);
21 register_action_type<Animate>("animate");
22 register_action_type<FadeOverlay::Fade>("fade");
23 register_action_type<Stage::UseInView>("use_stage");
24 register_action_type<Stage::SetCamera>("set_camera");
27 void Sequencer::set_beats_per_minute(float bpm)
29 secs_per_beat = Time::min/bpm;
32 void Sequencer::add_static_action(Action &act)
34 static_actions.push_back(&act);
37 void Sequencer::add_action(Action &act, float sb, float eb)
40 throw invalid_argument("Sequencer::add_action");
46 auto i = find_if(segments, [=](const Segment &s){ return s.start_beat>sb; });
47 segments.insert(i, seg);
50 void Sequencer::start()
53 end = begin = segments.begin();
54 for(auto a: static_actions)
55 a->start(0, numeric_limits<float>::max());
56 float start_beat = beat;
58 advance_to(start_beat);
61 void Sequencer::seek(float b)
64 throw logic_error("Sequencer::seek");
72 void Sequencer::tick(const Time::TimeDelta &dt)
76 if(begin==segments.end())
79 advance_to(beat+dt/secs_per_beat);
82 void Sequencer::advance_to(float target_beat)
84 while(target_beat>next_event)
85 advance_to(next_event);
87 float prev_beat = beat;
90 while(end!=segments.end() && end->start_beat<=beat)
93 int ibeat = static_cast<int>(floor(beat));
94 bool do_beat = (ibeat!=static_cast<int>(floor(prev_beat)));
96 for(auto a: static_actions)
100 a->tick(beat, beat-prev_beat);
103 for(auto i=begin; i!=end; ++i)
105 if(i->start_beat>prev_beat)
106 i->action->start(i->start_beat, i->end_beat-i->start_beat);
108 i->action->beat(ibeat);
109 if(i->end_beat>=prev_beat)
111 float tick_beat = min(beat, i->end_beat);
112 i->action->tick(tick_beat, tick_beat-max(prev_beat, i->start_beat));
113 if(i->end_beat<=beat)
114 i->action->end(i->end_beat);
118 while(begin!=end && begin->end_beat<=beat)
121 if(target_beat>=next_event)
124 if(begin==segments.end())
125 signal_finished.emit();
128 void Sequencer::update_next_event()
130 next_event = numeric_limits<float>::max();
132 if(end!=segments.end())
133 next_event = min(next_event, end->start_beat);
135 for(auto i=begin; i!=end; ++i)
137 next_event = min(next_event, i->end_beat);
141 Sequencer::Loader::Loader(Sequencer &s, Demo &d):
142 DataFile::ObjectLoader<Sequencer>(s),
145 add("define_action", &Loader::define_action);
146 add("instant", &Loader::instant);
147 add("segment", &Loader::segment);
150 void Sequencer::Loader::define_action(const string &n)
152 ActionDefLoader ldr(obj, demo);
154 obj.named_actions[n] = ldr.get_action();
157 void Sequencer::Loader::instant(float beat)
162 void Sequencer::Loader::segment(float start, float end)
164 SegmentLoader ldr(obj, start, end, demo);
169 Sequencer::ActionDefLoader::ActionDefLoader(Sequencer &s, Demo &d):
170 DataFile::ObjectLoader<Sequencer>(s),
173 for(const auto &t: obj.action_types)
174 add(t.first, t.second->get_def_loader_func());
177 void Sequencer::ActionDefLoader::finished()
184 Sequencer::SegmentLoader::SegmentLoader(Sequencer &s, float b, float e, Demo &d):
185 ObjectLoader<Sequencer>(s),
190 add("apply", &SegmentLoader::apply);
191 for(const auto &t: obj.action_types)
192 add(t.first, t.second->get_loader_func());
195 void Sequencer::SegmentLoader::apply(const string &n)
197 obj.add_action(*get_item(obj.named_actions, n), start_beat, end_beat);
200 } // namespace DemoScene