]> git.tdb.fi Git - libs/demoscene.git/blobdiff - source/sequencer.cpp
Allow specifying one-off actions inside segments
[libs/demoscene.git] / source / sequencer.cpp
index 4acad43b2891bc9bf813bf481e75277fa0a4bf71..0297c4397ff254bf30d26d95a44f4ec7909a1122 100644 (file)
@@ -1,6 +1,10 @@
 #include <cmath>
 #include <msp/core/algorithm.h>
+#include <msp/core/maputils.h>
+#include "animate.h"
+#include "fadeoverlay.h"
 #include "sequencer.h"
+#include "stage.h"
 
 using namespace std;
 using namespace Msp;
@@ -11,6 +15,11 @@ Sequencer::Sequencer(float bpm):
        next_event(0)
 {
        set_beats_per_minute(bpm);
+
+       register_action_type<Animate>("animate");
+       register_action_type<FadeOverlay::Fade>("fade");
+       register_action_type<Stage::UseInView>("use_stage");
+       register_action_type<Stage::SetCamera>("set_camera");
 }
 
 void Sequencer::set_beats_per_minute(float bpm)
@@ -28,12 +37,12 @@ void Sequencer::add_action(Action &act, float sb, float eb)
        if(sb<0 || sb>eb)
                throw invalid_argument("Sequencer::add_action");
 
-       Segment seq_act;
-       seq_act.action = &act;
-       seq_act.start_beat = sb;
-       seq_act.end_beat = eb;
+       Segment seg;
+       seg.action = &act;
+       seg.start_beat = sb;
+       seg.end_beat = eb;
        auto i = find_if(segments, [=](const Segment &s){ return s.start_beat>sb; });
-       segments.insert(i, seq_act);
+       segments.insert(i, seg);
 }
 
 void Sequencer::start()
@@ -127,38 +136,61 @@ void Sequencer::update_next_event()
 }
 
 
-Sequencer::InterpolationAction::InterpolationAction(bool h):
-       hermite(h),
-       start_beat(0),
-       duration(0)
-{ }
+Sequencer::Loader::Loader(Sequencer &s, Demo &d):
+       DataFile::ObjectLoader<Sequencer>(s),
+       demo(d)
+{
+       add("define_action", &Loader::define_action);
+       add("instant", &Loader::instant);
+       add("segment", &Loader::segment);
+}
 
-void Sequencer::InterpolationAction::start(float b, float d)
+void Sequencer::Loader::define_action(const string &n)
 {
-       start_beat = b;
-       duration = d;
-       interpolate(0.0f, 0.0f);
+       ActionDefLoader ldr(obj, demo);
+       load_sub_with(ldr);
+       obj.named_actions[n] = ldr.get_action();
 }
 
-void Sequencer::InterpolationAction::tick(float b, float d)
+void Sequencer::Loader::instant(float beat)
 {
-       if(duration)
-       {
-               float t = (b-start_beat)/duration;
-               float dt = d/duration;
-               if(hermite)
-               {
-                       dt = t-dt;
-                       t = (3-2*t)*t*t;
-                       dt = t-(3-2*dt)*dt*dt;
-               }
-               interpolate(t, dt);
-       }
-       else
-               interpolate(1.0f, 1.0f);
+       segment(beat, beat);
+}
+
+void Sequencer::Loader::segment(float start, float end)
+{
+       SegmentLoader ldr(obj, start, end, demo);
+       load_sub_with(ldr);
+}
+
+
+Sequencer::ActionDefLoader::ActionDefLoader(Sequencer &s, Demo &d):
+       DataFile::ObjectLoader<Sequencer>(s),
+       demo(d)
+{
+       for(const auto &t: obj.action_types)
+               add(t.first, t.second->get_def_loader_func());
+}
+
+void Sequencer::ActionDefLoader::finished()
+{
+       if(action)
+               action->validate();
+}
+
+
+Sequencer::SegmentLoader::SegmentLoader(Sequencer &s, float b, float e, Demo &d):
+       ObjectLoader<Sequencer>(s),
+       start_beat(b),
+       end_beat(e),
+       demo(d)
+{
+       add("apply", &SegmentLoader::apply);
+       for(const auto &t: obj.action_types)
+               add(t.first, t.second->get_loader_func());
 }
 
-void Sequencer::InterpolationAction::end(float)
+void Sequencer::SegmentLoader::apply(const string &n)
 {
-       interpolate(1.0f, 0.0f);
+       obj.add_action(*get_item(obj.named_actions, n), start_beat, end_beat);
 }