2 #include <msp/core/algorithm.h>
3 #include <msp/core/maputils.h>
4 #include "fadeoverlay.h"
11 Sequencer::Sequencer(float bpm):
16 set_beats_per_minute(bpm);
18 register_action_type<FadeOverlay::Fade>("fade");
19 register_action_type<Stage::UseInView>("use_stage");
22 void Sequencer::set_beats_per_minute(float bpm)
24 secs_per_beat = Time::min/bpm;
27 void Sequencer::add_static_action(Action &act)
29 static_actions.push_back(&act);
32 void Sequencer::add_action(Action &act, float sb, float eb)
35 throw invalid_argument("Sequencer::add_action");
41 auto i = find_if(segments, [=](const Segment &s){ return s.start_beat>sb; });
42 segments.insert(i, seg);
45 void Sequencer::start()
48 end = begin = segments.begin();
49 for(auto a: static_actions)
50 a->start(0, numeric_limits<float>::max());
51 float start_beat = beat;
53 advance_to(start_beat);
56 void Sequencer::seek(float b)
59 throw logic_error("Sequencer::seek");
67 void Sequencer::tick(const Time::TimeDelta &dt)
71 if(begin==segments.end())
74 advance_to(beat+dt/secs_per_beat);
77 void Sequencer::advance_to(float target_beat)
79 while(target_beat>next_event)
80 advance_to(next_event);
82 float prev_beat = beat;
85 while(end!=segments.end() && end->start_beat<=beat)
88 int ibeat = static_cast<int>(floor(beat));
89 bool do_beat = (ibeat!=static_cast<int>(floor(prev_beat)));
91 for(auto a: static_actions)
95 a->tick(beat, beat-prev_beat);
98 for(auto i=begin; i!=end; ++i)
100 if(i->start_beat>prev_beat)
101 i->action->start(i->start_beat, i->end_beat-i->start_beat);
103 i->action->beat(ibeat);
104 if(i->end_beat>=prev_beat)
106 float tick_beat = min(beat, i->end_beat);
107 i->action->tick(tick_beat, tick_beat-max(prev_beat, i->start_beat));
108 if(i->end_beat<=beat)
109 i->action->end(i->end_beat);
113 while(begin!=end && begin->end_beat<=beat)
116 if(target_beat>=next_event)
119 if(begin==segments.end())
120 signal_finished.emit();
123 void Sequencer::update_next_event()
125 next_event = numeric_limits<float>::max();
127 if(end!=segments.end())
128 next_event = min(next_event, end->start_beat);
130 for(auto i=begin; i!=end; ++i)
132 next_event = min(next_event, i->end_beat);
136 Sequencer::Loader::Loader(Sequencer &s, Demo &d):
137 DataFile::ObjectLoader<Sequencer>(s),
140 add("define_action", &Loader::define_action);
141 add("instant", &Loader::instant);
142 add("segment", &Loader::segment);
145 void Sequencer::Loader::define_action(const string &n)
147 ActionDefLoader ldr(obj, demo);
149 obj.named_actions[n] = ldr.get_action();
152 void Sequencer::Loader::instant(float beat)
157 void Sequencer::Loader::segment(float start, float end)
159 SegmentLoader ldr(obj, start, end);
164 Sequencer::ActionDefLoader::ActionDefLoader(Sequencer &s, Demo &d):
165 DataFile::ObjectLoader<Sequencer>(s),
168 for(const auto &t: obj.action_types)
169 add(t.first, t.second->get_loader_func());
172 void Sequencer::ActionDefLoader::finished()
179 Sequencer::SegmentLoader::SegmentLoader(Sequencer &s, float b, float e):
180 ObjectLoader<Sequencer>(s),
184 add("apply", &SegmentLoader::apply);
187 void Sequencer::SegmentLoader::apply(const string &n)
189 obj.add_action(*get_item(obj.named_actions, n), start_beat, end_beat);