-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathtimeline.cpp
126 lines (104 loc) · 3.29 KB
/
timeline.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "timeline.h"
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include "luascriptcontext.h"
#include "project.h"
Timeline::Timeline()
: mBPM(120)
{
}
std::shared_ptr<TimelineLayer> Timeline::createLayer()
{
QString name = QString("layer_%1").arg(mLayers.size());
mLayers.push_back(std::make_shared<TimelineLayer>(name));
emit layerAdded(mLayers.size() - 1, mLayers.last());
return mLayers.last();
}
void Timeline::removeLayer(int idx)
{
mLayers.remove(idx);
emit layerRemoved(idx);
}
void Timeline::clearLayers()
{
while (!mLayers.empty())
removeLayer(mLayers.size() - 1);
}
void Timeline::setBPM(double bpm)
{
mBPM = bpm;
emit bpmChanged(mBPM);
}
void Timeline::setBackingTrack(const QString& track)
{
mBackingTrack = track;
emit backingTrackChanged(track);
}
QJsonObject Timeline::toJSON() const
{
// layers
QJsonArray layers;
for (auto layer = mLayers.begin(); layer != mLayers.end(); layer++) {
layers.append(layer->get()->toJSON());
}
QJsonObject timeline;
// can we make it backing track relative?
if (Project::get() != nullptr) {
QDir dir(Project::get()->root());
QString relPath = dir.relativeFilePath(mBackingTrack);
// if it goes out of the project directory, forget it
if (relPath.startsWith(".."))
timeline["backingTrack"] = mBackingTrack;
else
timeline["backingTrack"] = relPath;
} else {
timeline["backingTrack"] = mBackingTrack;
}
timeline["bpm"] = mBPM;
timeline["layers"] = layers;
return timeline;
}
void Timeline::fromJSON(const QJsonObject& timeline)
{
setBackingTrack(timeline["backingTrack"].toString());
if (Project::get() != nullptr && !QFileInfo(mBackingTrack).exists()) {
QDir dir(Project::get()->root());
QFileInfo path = dir.filePath(mBackingTrack);
if (path.exists())
setBackingTrack(path.filePath());
}
setBPM(timeline["bpm"].toDouble());
// layers
clearLayers();
const QJsonArray& layers = timeline["layers"].toArray();
for (auto it = layers.begin(); it != layers.end(); it++) {
createLayer()->fromJSON((*it).toObject());
}
}
std::shared_ptr<Timeline> Timeline::process() const
{
std::shared_ptr<Timeline> timeline = std::make_shared<Timeline>();
// copy timeline values
timeline->setBackingTrack(backingTrack());
timeline->setBPM(bpm());
for (auto sourceLayer = mLayers.begin(); sourceLayer != mLayers.end(); sourceLayer++) {
std::shared_ptr<TimelineLayer> newLayer = timeline->createLayer();
newLayer->setName(sourceLayer->get()->name());
if (QFileInfo(sourceLayer->get()->scriptPath()).exists()) {
LuaScriptContext script(sourceLayer->get()->scriptPath());
script.process(sourceLayer->get(), newLayer.get());
} else {
// should reaaaaally do a deep copy here
// but right now the process()'d timeline is just saved and discarded
const auto& events = sourceLayer->get()->events();
for (auto ev = events.begin(); ev != events.end(); ev++) {
newLayer->events().addEvent(*ev);
}
}
}
return timeline;
}