• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ossia / score / 30712882626

01 Aug 2026 06:35PM UTC coverage: 15.224% (-0.04%) from 15.263%
30712882626

Pull #2170

github

web-flow
Merge 03b0da44d into 3ceec338e
Pull Request #2170: Make the X11-dependent parts optional (gfx, vst3, linuxcheck)

30381 of 199565 relevant lines covered (15.22%)

1075.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.1
/src/plugins/score-plugin-scenario/Scenario/Document/Interval/IntervalDurations.cpp
1
// This is an open source non-commercial project. Dear PVS-Studio, please check
2
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3
#include "IntervalDurations.hpp"
4

5
#include "IntervalModel.hpp"
6

7
#include <Process/TimeValue.hpp>
8
#include <Process/TimeValueSerialization.hpp>
9

10
#include <Scenario/Document/ModelConsistency.hpp>
11

12
#include <score/serialization/DataStreamVisitor.hpp>
13
#include <score/serialization/JSONValueVisitor.hpp>
14
#include <score/serialization/JSONVisitor.hpp>
15

16
#define TIME_TOLERANCE_MSEC 0.5
17
#include <wobjectimpl.h>
18
W_OBJECT_IMPL(Scenario::IntervalDurations)
283✔
19
namespace Scenario
20
{
21
IntervalDurations::~IntervalDurations() { }
20✔
22

23
IntervalDurations& IntervalDurations::operator=(const IntervalDurations& other)
×
24
{
25
  m_defaultDuration = other.m_defaultDuration;
×
26
  m_minDuration = other.m_minDuration;
×
27
  m_maxDuration = other.m_maxDuration;
×
28
  m_guiDuration = other.m_guiDuration;
×
29

30
  m_playPercentage = other.m_playPercentage;
×
31
  m_speed = other.m_speed;
×
32
  m_rigidity = other.m_rigidity;
×
33

34
  m_isMinNull = other.m_isMinNull;
×
35
  m_isMaxInfinite = other.m_isMaxInfinite;
×
36

37
  return *this;
×
38
}
39

40
void IntervalDurations::checkConsistency()
18✔
41
{
42
  m_model.consistency.setWarning(
36✔
43
      minDuration().msec() < 0 - TIME_TOLERANCE_MSEC
18✔
44
      || (isRigid() && minDuration() != maxDuration())); // a voir
18✔
45

46
  m_model.consistency.setValid(
36✔
47
      minDuration() - TimeVal::fromMsecs(TIME_TOLERANCE_MSEC) <= m_defaultDuration
18✔
48
      && maxDuration() + TimeVal::fromMsecs(TIME_TOLERANCE_MSEC) >= m_defaultDuration
18✔
49
      && m_defaultDuration.msec() + TIME_TOLERANCE_MSEC > 0);
18✔
50
}
18✔
51

52
void IntervalDurations::setDefaultDuration(const TimeVal& arg)
×
53
{
54
  SCORE_ASSERT(arg.impl >= 0);
×
55
  if(m_defaultDuration != arg)
×
56
  {
57
    m_defaultDuration = arg;
×
58
    defaultDurationChanged(arg);
×
59

60
    if(m_guiDuration < m_defaultDuration)
×
61
      setGuiDuration(m_defaultDuration * 1.1);
×
62

63
    checkConsistency();
×
64
  }
×
65
}
×
66

67
void IntervalDurations::setMinDuration(const TimeVal& arg)
×
68
{
69
  if(m_minDuration != arg && !m_isMinNull)
×
70
  {
71
    m_minDuration = arg;
×
72
    minDurationChanged(arg);
×
73

74
    checkConsistency();
×
75
  }
×
76
}
×
77

78
void IntervalDurations::setMaxDuration(const TimeVal& arg)
×
79
{
80
  if(m_maxDuration != arg)
×
81
  {
82
    m_maxDuration = arg;
×
83
    maxDurationChanged(arg);
×
84

85
    if(m_guiDuration < m_maxDuration && !m_isMaxInfinite)
×
86
      setGuiDuration(m_maxDuration * 1.1);
×
87

88
    checkConsistency();
×
89
  }
×
90
}
×
91

92
void IntervalDurations::setGuiDuration(TimeVal guiDuration)
×
93
{
94
  SCORE_ASSERT(guiDuration.impl >= 0);
×
95
  if(m_guiDuration == guiDuration)
×
96
    return;
×
97

98
  m_guiDuration = guiDuration;
×
99
  guiDurationChanged(guiDuration);
×
100
}
×
101

102
void IntervalDurations::setPlayPercentage(double arg)
×
103
{
104
  if(m_playPercentage == arg)
×
105
    return;
×
106

107
  auto old = m_playPercentage;
×
108

109
  m_playPercentage = arg;
×
110

111
  positionChanged(arg);
×
112
  // Only used for DurationSectionWidget
113
  if(m_defaultDuration * std::abs(arg - old) > TimeVal::fromMsecs(32))
×
114
  {
115
    playPercentageChanged(arg);
×
116
  }
×
117
}
×
118

119
void IntervalDurations::setRigid(bool arg)
18✔
120
{
121
  if(m_rigidity == arg)
18✔
122
    return;
×
123

124
  m_rigidity = arg;
18✔
125
  rigidityChanged(arg);
18✔
126
}
18✔
127

128
void IntervalDurations::setMinNull(bool isMinNull)
×
129
{
130
  if(m_isMinNull == isMinNull)
×
131
    return;
×
132

133
  m_isMinNull = isMinNull;
×
134
  minNullChanged(isMinNull);
×
135
  minDurationChanged(minDuration());
×
136
}
×
137

138
void IntervalDurations::setMaxInfinite(bool isMaxInfinite)
18✔
139
{
140
  if(m_isMaxInfinite == isMaxInfinite)
18✔
141
    return;
×
142

143
  m_isMaxInfinite = isMaxInfinite;
18✔
144
  maxInfiniteChanged(isMaxInfinite);
18✔
145
  maxDurationChanged(maxDuration());
18✔
146
}
18✔
147

148
SCORE_PLUGIN_SCENARIO_EXPORT void IntervalDurations::Algorithms::setDurationInBounds(
×
149
    IntervalModel& cstr, const TimeVal& time)
150
{
151
  SCORE_ASSERT(time.impl >= 0);
×
152
  if(cstr.duration.defaultDuration() != time)
×
153
  {
154
    // Rigid
155
    if(cstr.duration.isRigid())
×
156
    {
157
      cstr.duration.setDefaultDuration(time);
×
158

159
      cstr.duration.setMinDuration(time);
×
160
      cstr.duration.setMaxDuration(time);
×
161
    }
×
162
    else // TODO The checking must be done elsewhere if(arg >= m_minDuration &&
163
         // arg <= m_maxDuration)
164
         // --> it should be in a command to be undoable
165
    {
166
      cstr.duration.setDefaultDuration(time);
×
167
    }
168
  }
×
169
}
×
170

171
SCORE_PLUGIN_SCENARIO_EXPORT void
172
IntervalDurations::Algorithms::fixAllDurations(IntervalModel& cstr, const TimeVal& time)
×
173
{
174
  SCORE_ASSERT(time.impl >= 0);
×
175
  auto& dur = cstr.duration;
×
176
  if(dur.defaultDuration() != time || dur.minDuration() != time
×
177
     || dur.maxDuration() != time)
×
178
  {
179
    dur.m_defaultDuration = time;
×
180
    dur.m_minDuration = time;
×
181
    dur.m_maxDuration = time;
×
182
    dur.m_guiDuration = time * 1.1;
×
183

184
    dur.defaultDurationChanged(time);
×
185
    dur.minDurationChanged(time);
×
186
    dur.maxDurationChanged(time);
×
187
    if(!dur.m_rigidity)
×
188
    {
189
      dur.m_rigidity = true;
×
190
      dur.rigidityChanged(true);
×
191
    }
×
192
  }
×
193
}
×
194

195
SCORE_PLUGIN_SCENARIO_EXPORT void IntervalDurations::Algorithms::changeAllDurations(
18✔
196
    IntervalModel& cstr, const TimeVal& time)
197
{
198
  SCORE_ASSERT(time.impl >= 0);
18✔
199
  auto& d = cstr.duration;
18✔
200
  if(d.isRigid())
18✔
201
  {
202
    fixAllDurations(cstr, time);
×
203
    return;
×
204
  }
205

206
  if(d.defaultDuration() != time)
18✔
207
  {
208
    const auto delta = time - d.defaultDuration();
18✔
209
    d.m_defaultDuration = time;
18✔
210
    if(auto new_gui_dur = time * 1.1; new_gui_dur > d.m_guiDuration)
18✔
211
      d.m_guiDuration = new_gui_dur;
18✔
212

213
    // FIXME ! why is there m_isMaxInfinite and m_maxDuration.isInfinite() ?!
214
    if(!d.m_isMinNull)
18✔
215
      d.m_minDuration += delta;
18✔
216

217
    if(!d.m_isMaxInfinite)
18✔
218
      d.m_maxDuration += delta;
18✔
219

220
    if(d.m_minDuration < TimeVal::zero())
18✔
221
      d.m_minDuration = TimeVal::zero();
×
222

223
    if(d.m_maxDuration <= d.m_defaultDuration && !d.m_isMaxInfinite)
18✔
224
      //      d.m_maxDuration =
225
      //      TimeVal{std::nextafter(d.m_defaultDuration.msec(),
226
      //      d.m_defaultDuration.msec() * 2.)};
227
      d.m_maxDuration = d.m_defaultDuration
36✔
228
                        * 1.05; // TimeVal{std::nextafter(d.m_defaultDuration.msec(),
18✔
229
                                // d.m_defaultDuration.msec() * 2.)};
230

231
    if(d.m_guiDuration < d.m_defaultDuration)
18✔
232
      d.m_guiDuration = time * 1.1;
×
233

234
    if(d.m_guiDuration < d.m_maxDuration && !d.m_isMaxInfinite)
18✔
235
      d.m_guiDuration = d.m_maxDuration * 1.1;
×
236

237
    d.defaultDurationChanged(time);
18✔
238
    d.guiDurationChanged(d.m_guiDuration);
18✔
239
    d.minDurationChanged(d.m_minDuration);
18✔
240
    d.maxDurationChanged(d.m_maxDuration);
18✔
241

242
    d.checkConsistency();
18✔
243
  }
18✔
244
}
18✔
245

246
SCORE_PLUGIN_SCENARIO_EXPORT void IntervalDurations::Algorithms::scaleAllDurations(
×
247
    IntervalModel& cstr, const TimeVal& time)
248
{
249
  if(time.impl <= 0)
×
250
  {
251
    cstr.duration.setDefaultDuration(TimeVal::zero());
×
252
    cstr.duration.setMinDuration(TimeVal::zero());
×
253
    cstr.duration.setMaxDuration(TimeVal::zero());
×
254
    return;
×
255
  }
256

257
  if(cstr.duration.defaultDuration() != time)
×
258
  {
259
    // Note: the OSSIA implementation requires min <= dur <= max at all time
260
    // and will throw if not the case. Hence this order.
261

262
    auto ratio = time / cstr.duration.defaultDuration();
×
263

264
    const bool same_min
×
265
        = (cstr.duration.defaultDuration() == cstr.duration.minDuration());
×
266
    const bool same_max
×
267
        = (cstr.duration.defaultDuration() == cstr.duration.maxDuration());
×
268

269
    cstr.duration.setDefaultDuration(time);
×
270

271
    TimeVal newmin = same_min ? time : TimeVal{cstr.duration.minDuration() * ratio};
×
272
    if(newmin.impl > time.impl)
×
273
      newmin.impl = time.impl - 1;
×
274
    if(newmin.impl < 0)
×
275
      newmin.impl = 0;
×
276

277
    TimeVal newmax = same_max ? cstr.duration.defaultDuration()
×
278
                              : TimeVal{cstr.duration.maxDuration() * ratio};
×
279
    if(newmax.impl < time.impl)
×
280
      newmax.impl = time.impl + 1;
×
281

282
    cstr.duration.setMinDuration(newmin);
×
283
    cstr.duration.setMaxDuration(newmax);
×
284
  }
×
285
}
×
286
}
287

288
template <>
289
void DataStreamReader::read(const Scenario::IntervalDurations& durs)
25✔
290
{
291
  m_stream << durs.m_defaultDuration << durs.m_minDuration << durs.m_maxDuration
25✔
292
           << durs.m_guiDuration << durs.m_speed << durs.m_rigidity << durs.m_isMinNull
25✔
293
           << durs.m_isMaxInfinite;
25✔
294
}
25✔
295

296
template <>
297
void DataStreamWriter::write(Scenario::IntervalDurations& durs)
2✔
298
{
299
  m_stream >> durs.m_defaultDuration >> durs.m_minDuration >> durs.m_maxDuration
2✔
300
      >> durs.m_guiDuration >> durs.m_speed >> durs.m_rigidity >> durs.m_isMinNull
2✔
301
      >> durs.m_isMaxInfinite;
2✔
302
}
2✔
303

304
template <>
305
void JSONReader::read(const Scenario::IntervalDurations& durs)
×
306
{
307
  obj[strings.DefaultDuration] = durs.m_defaultDuration;
×
308
  obj[strings.MinDuration] = durs.m_minDuration;
×
309
  obj[strings.MaxDuration] = durs.m_maxDuration;
×
310
  obj[strings.GuiDuration] = durs.m_guiDuration;
×
311
  obj["Speed"] = durs.m_speed;
×
312
  obj[strings.Rigidity] = durs.m_rigidity;
×
313
  obj[strings.MinNull] = durs.m_isMinNull;
×
314
  obj[strings.MaxInf] = durs.m_isMaxInfinite;
×
315
}
×
316

317
template <>
318
void JSONWriter::write(Scenario::IntervalDurations& durs)
×
319
{
320
  durs.m_defaultDuration <<= obj[strings.DefaultDuration];
×
321
  durs.m_minDuration <<= obj[strings.MinDuration];
×
322
  durs.m_maxDuration <<= obj[strings.MaxDuration];
×
323

324
  assign_with_default(durs.m_speed, obj.tryGet("Speed"), 1.0);
×
325
  durs.m_rigidity = obj[strings.Rigidity].toBool();
×
326
  durs.m_isMinNull = obj[strings.MinNull].toBool();
×
327
  durs.m_isMaxInfinite = obj[strings.MaxInf].toBool();
×
328

329
  using namespace std::chrono;
330
  if(durs.m_minDuration.msec() < 0)
×
331
    durs.m_minDuration = durs.m_defaultDuration;
×
332
  if(durs.m_maxDuration.msec() < 0)
×
333
    durs.m_maxDuration = durs.m_defaultDuration;
×
334
  if(durs.isRigid())
×
335
  {
336
    durs.m_minDuration = durs.m_defaultDuration;
×
337
    durs.m_maxDuration = durs.m_defaultDuration;
×
338
  }
×
339

340
  auto guidur = obj.constFind(strings.GuiDuration);
×
341
  if(guidur != obj.constEnd())
×
342
    durs.m_guiDuration <<= *guidur;
×
343
  else
344
  {
345
    if(durs.m_isMaxInfinite)
×
346
      durs.m_guiDuration = durs.m_defaultDuration;
×
347
    else
348
      durs.m_guiDuration = durs.m_maxDuration;
×
349
  }
350
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc