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

ossia / score / 31952604910

16 Aug 2026 02:24PM UTC coverage: 19.438% (+3.2%) from 16.231%
31952604910

push

github

jcelerier
execution: fix a crash that has been lurking since 2018 in execution cleanup

0 of 1 new or added line in 1 file covered. (0.0%)

2699 existing lines in 72 files now uncovered.

41088 of 211385 relevant lines covered (19.44%)

4325.7 hits per line

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

67.24
/src/plugins/score-lib-process/Process/Process.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 "Process.hpp"
4

5
#include <Process/Dataflow/PortVisibility.hpp>
6

7
#include <Process/Dataflow/Port.hpp>
8
#include <Process/ExpandMode.hpp>
9
#include <Process/PresetHelpers.hpp>
10
#include <Process/TimeValue.hpp>
11

12
#include <LocalTree/ProcessComponent.hpp>
13

14
#include <score/model/ComponentUtils.hpp>
15
#include <score/model/EntitySerialization.hpp>
16
#include <score/model/IdentifiedObject.hpp>
17
#include <score/model/Identifier.hpp>
18
#include <score/model/ModelMetadata.hpp>
19
#include <score/tools/Bind.hpp>
20
#include <score/widgets/SetIcons.hpp>
21

22
#include <ossia/detail/algorithms.hpp>
23
#include <ossia/detail/disable_fpe.hpp>
24
#include <ossia/network/base/device.hpp>
25
#include <ossia/network/base/node.hpp>
26

27
#include <QObject>
28

29
#include <wobjectimpl.h>
30

31
W_OBJECT_IMPL(Process::ProcessModel)
4,415✔
32

33
#if !defined(SCORE_ALL_UNITY)
34
template class IdentifiedObject<Process::ProcessModel>;
35
template class score::SerializableInterface<Process::ProcessModelFactory>;
36
#endif
37
namespace Process
38
{
39

40
const QIcon& getCategoryIcon(const QString& category) noexcept
3,024✔
41
{
42
  static const ossia::flat_map<QString, QIcon> categoryIcon{
3,249✔
43
      {"AI", makeIcon(QStringLiteral(":/icons/ai.png"))},
15✔
44
      {"Analysis", makeIcon(QStringLiteral(":/icons/analysis.png"))},
15✔
45
      {"Audio", makeIcon(QStringLiteral(":/icons/audio.png"))},
15✔
46
      {"Plugins", makeIcon(QStringLiteral(":/icons/filter.png"))},
15✔
47
      {"Midi", makeIcon(QStringLiteral(":/icons/midi.png"))},
15✔
48
      {"Control", makeIcon(QStringLiteral(":/icons/controls.png"))},
15✔
49
      {"Visuals", makeIcon(QStringLiteral(":/icons/gfx.png"))},
15✔
50
      {"Automations", makeIcon(QStringLiteral(":/icons/automation.png"))},
15✔
51
      {"Impro", makeIcon(QStringLiteral(":/icons/controls.png"))},
15✔
52
      {"Script", makeIcon(QStringLiteral(":/icons/script.png"))},
15✔
53
      {"Structure", makeIcon(QStringLiteral(":/icons/structure.png"))},
15✔
54
      {"Network", makeIcon(QStringLiteral(":/icons/sync.png"))},
15✔
55
      {"Monitoring", makeIcon(QStringLiteral(":/icons/ui.png"))},
15✔
56
      {"Spatialization", makeIcon(QStringLiteral(":/icons/spatial.png"))},
15✔
57
      {"Timing", makeIcon(QStringLiteral(":/icons/timing.png"))},
15✔
58
  };
59
  static const QIcon invalid;
3,024✔
60
  if(auto it = categoryIcon.find(category); it != categoryIcon.end())
3,024✔
61
  {
62
    return it->second;
2,970✔
63
  }
64
  if(auto slash_it = category.indexOf("/"); slash_it != -1)
54✔
65
  {
66
    if(auto it = categoryIcon.find(category.mid(0, slash_it)); it != categoryIcon.end())
×
67
    {
68
      return it->second;
×
69
    }
UNCOV
70
  }
×
71
  return invalid;
54✔
72
}
3,024✔
73
ProcessModel::ProcessModel(
918✔
74
    TimeVal duration, const Id<ProcessModel>& id, const QString& name, QObject* parent)
75
    : Entity{id, name, parent}
459✔
76
    , m_duration{std::move(duration)}
77
    , m_slotHeight{300}
78
    , m_loopDuration{m_duration}
79
    , m_size{200, 100}
80
    , m_loops{false}
81
{
918✔
82
  ossia::disable_fpe();
459✔
83
  con(metadata(), &score::ModelMetadata::NameChanged, this,
918✔
84
      [this] { prettyNameChanged(); });
928✔
85
  connect(this, &Process::ProcessModel::resetExecution, this, [this] {
484✔
86
    for(auto& p : this->m_inlets)
46✔
87
      p->executionReset();
21✔
88
    for(auto& p : this->m_outlets)
50✔
89
      p->executionReset();
25✔
90
  });
25✔
91
  // metadata().setInstanceName(*this);
UNCOV
92
}
×
93

94
ProcessModel::~ProcessModel()
1,155✔
95
{
1,155✔
96
  identified_object_destroying(this);
1,155✔
97
}
1,155✔
98

99
QString ProcessModel::effect() const noexcept
26✔
100
{
101
  return {};
26✔
102
}
103

104
void ProcessModel::setDurationAndScale(const TimeVal& newDuration) noexcept
×
105
{
UNCOV
106
  setDuration(newDuration);
×
107
}
×
108

109
void ProcessModel::setDurationAndGrow(const TimeVal& newDuration) noexcept
×
110
{
UNCOV
111
  setDuration(newDuration);
×
112
}
×
113

114
void ProcessModel::setDurationAndShrink(const TimeVal& newDuration) noexcept
×
115
{
UNCOV
116
  setDuration(newDuration);
×
UNCOV
117
}
×
118

119
ProcessModel::ProcessModel(DataStream::Deserializer& vis, QObject* parent)
684✔
120
    : Entity(vis, parent)
342✔
121
{
684✔
122
  ossia::disable_fpe();
342✔
123
  vis.writeTo(*this);
342✔
124
  con(metadata(), &score::ModelMetadata::NameChanged, this,
684✔
125
      [this] { prettyNameChanged(); });
342✔
UNCOV
126
}
×
127

128
ProcessModel::ProcessModel(JSONObject::Deserializer& vis, QObject* parent)
708✔
129
    : Entity(vis, parent)
354✔
130
{
708✔
131
  ossia::disable_fpe();
354✔
132
  vis.writeTo(*this);
354✔
133
  con(metadata(), &score::ModelMetadata::NameChanged, this,
708✔
134
      [this] { prettyNameChanged(); });
354✔
UNCOV
135
}
×
136

137
QString ProcessModel::prettyName() const noexcept
264✔
138
{
139
  return metadata().getName();
264✔
140
}
141

142
void ProcessModel::setParentDuration(ExpandMode mode, const TimeVal& t) noexcept
×
143
{
UNCOV
144
  switch(mode)
×
145
  {
146
    case ExpandMode::Scale:
UNCOV
147
      setDurationAndScale(t);
×
148
      break;
×
149
    case ExpandMode::GrowShrink: {
UNCOV
150
      if(duration() < t)
×
151
        setDurationAndGrow(t);
×
152
      else
UNCOV
153
        setDurationAndShrink(t);
×
UNCOV
154
      break;
×
155
    }
156
    case ExpandMode::ForceGrow: {
157
      if(duration() < t)
×
UNCOV
158
        setDurationAndGrow(t);
×
159
      break;
×
160
    }
161
    case ExpandMode::CannotExpand:
×
162
    default:
163
      break;
×
164
  }
165
}
×
166

167
TimeVal ProcessModel::contentDuration() const noexcept
×
168
{
UNCOV
169
  return TimeVal::zero();
×
170
}
171

172
void ProcessModel::setDuration(const TimeVal& other) noexcept
1✔
173
{
174
  m_duration = other;
1✔
175
  durationChanged(m_duration);
1✔
176
}
1✔
177

178
const TimeVal& ProcessModel::duration() const noexcept
974✔
179
{
180
  return m_duration;
974✔
181
}
182

183
ProcessStateDataInterface* ProcessModel::startStateData() const noexcept
80✔
184
{
185
  return nullptr;
80✔
186
}
187

188
ProcessStateDataInterface* ProcessModel::endStateData() const noexcept
80✔
189
{
190
  return nullptr;
80✔
191
}
192

193
Selection ProcessModel::selectableChildren() const noexcept
×
194
{
UNCOV
195
  return {};
×
196
}
197

198
Selection ProcessModel::selectedChildren() const noexcept
×
199
{
UNCOV
200
  return {};
×
201
}
202

203
void ProcessModel::setSelection(const Selection& s) const noexcept
1✔
204
{
205
  // OPTIMIZEME
206
  auto cld = this->findChildren<Selectable*>();
1✔
207
  for(Selectable* child : cld)
10✔
208
  {
209
    child->set(s.contains(child->parent()));
9✔
210
  }
211
}
1✔
212

213
Process::Inlet* ProcessModel::inlet(const Id<Process::Port>& p) const noexcept
4✔
214
{
215
  for(auto e : m_inlets)
11✔
216
    if(e->id() == p)
10✔
217
      return e;
3✔
218
  return nullptr;
1✔
219
}
4✔
220

221
Process::Outlet* ProcessModel::outlet(const Id<Process::Port>& p) const noexcept
1✔
222
{
223
  for(auto e : m_outlets)
1✔
224
    if(e->id() == p)
1✔
225
      return e;
1✔
UNCOV
226
  return nullptr;
×
227
}
1✔
228

229
void ProcessModel::loadPreset(const Preset& preset)
2✔
230
{
231
  const rapidjson::Document doc = readJson(preset.data);
2✔
232
  loadFixedControls(doc.GetArray(), *this);
2✔
233
}
2✔
234

235
Preset ProcessModel::savePreset() const noexcept
4✔
236
{
237
  Preset p;
4✔
238
  p.name = this->metadata().getName();
4✔
239
  p.key.key = this->concreteKey();
4✔
240

241
  JSONReader r;
4✔
242
  saveFixedControls(r, *this);
4✔
243
  p.data = r.toByteArray();
4✔
244
  return p;
4✔
245
}
4✔
246

247
std::vector<Preset> ProcessModel::builtinPresets() const noexcept
×
248
{
UNCOV
249
  return {};
×
250
}
251

252
void ProcessModel::ancestorStartDateChanged() { }
×
253

254
void ProcessModel::ancestorTempoChanged() { }
×
255

UNCOV
256
void ProcessModel::forEachControl(
×
257
    smallfun::function<void(ControlInlet&, const ossia::value&)> f) const
258
{
259
  for(const auto& inlet : m_inlets)
×
260
  {
261
    if(auto ctrl = qobject_cast<Process::ControlInlet*>(inlet))
×
262
    {
UNCOV
263
      f(*ctrl, ctrl->value());
×
264
    }
×
265
  }
266
}
×
267

268
void ProcessModel::setCreatingControls(bool ok) { }
×
269

270
bool ProcessModel::creatingControls() const noexcept
×
271
{
UNCOV
272
  return this->flags() & ProcessFlags::CreateControls;
×
273
}
274

275
void ProcessModel::setLoops(bool b)
6✔
276
{
277
  if(b != m_loops)
6✔
278
  {
279
    m_loops = b;
4✔
280
    loopsChanged(b);
4✔
281
  }
4✔
282
}
6✔
283

284
void ProcessModel::setStartOffset(TimeVal b)
1✔
285
{
286
  if(b != m_startOffset)
1✔
287
  {
288
    m_startOffset = b;
1✔
289
    startOffsetChanged(b);
1✔
290
  }
1✔
291
}
1✔
292

293
void ProcessModel::setLoopDuration(TimeVal b)
×
294
{
UNCOV
295
  if(b.msec() < 0.1)
×
296
    b = TimeVal::fromMsecs(0.1);
×
297

298
  if(b != m_loopDuration)
×
299
  {
300
    m_loopDuration = b;
×
301
    loopDurationChanged(b);
×
UNCOV
302
  }
×
UNCOV
303
}
×
304

305
QPointF ProcessModel::position() const noexcept
340✔
306
{
307
  return m_position;
340✔
308
}
309

310
QSizeF ProcessModel::size() const noexcept
225✔
311
{
312
  return m_size;
225✔
313
}
314

315
void ProcessModel::setPosition(const QPointF& v)
97✔
316
{
317
  if(v != m_position)
97✔
318
  {
319
    m_position = v;
95✔
320
    positionChanged(v);
95✔
321
  }
95✔
322
}
97✔
323

324
void ProcessModel::setSize(const QSizeF& v)
22✔
325
{
326
  if(v != m_size)
22✔
327
  {
328
    m_size = v;
22✔
329
    sizeChanged(v);
22✔
330
  }
22✔
331
}
22✔
332

333
FoldMode ProcessModel::foldMode() const noexcept
693✔
334
{
335
  return m_foldMode;
693✔
336
}
337

338
void ProcessModel::setFoldMode(FoldMode v)
6✔
339
{
340
  if(v != m_foldMode)
6✔
341
  {
342
    m_foldMode = v;
6✔
343
    foldModeChanged(v);
6✔
344
  }
6✔
345
}
6✔
346

347
bool ProcessModel::folded() const noexcept
23✔
348
{
349
  switch(m_foldMode)
23✔
350
  {
351
    case FoldMode::Folded:
352
      return true;
5✔
353
    case FoldMode::Unfolded:
354
      return false;
2✔
355
    case FoldMode::Auto:
16✔
356
    default:
357
      return std::ssize(m_inlets) > MaxUnpaginatedControls;
16✔
358
  }
359
}
23✔
360

361
double ProcessModel::getSlotHeight() const noexcept
1,984✔
362
{
363
  return m_slotHeight;
1,984✔
364
}
365

366
void ProcessModel::setSlotHeight(double v) noexcept
59✔
367
{
368
  m_slotHeight = v;
59✔
369
  slotHeightChanged(v);
59✔
370
}
59✔
371

372
void ProcessModel::setExecuting(bool e)
35✔
373
{
374
  m_executing = e;
35✔
375
}
35✔
376

377
std::optional<Process::MagneticInfo>
378
ProcessModel::magneticPosition(const QObject* o, const TimeVal t) const noexcept
×
379
{
380
  return {};
×
381
}
382

383
ProcessModel* parentProcess(QObject* obj) noexcept
3✔
384
{
385
  if(obj)
3✔
386
    obj = obj->parent();
3✔
387

388
  while(obj && !qobject_cast<ProcessModel*>(obj))
3✔
389
  {
390
    obj = obj->parent();
×
391
  }
392

393
  if(obj)
3✔
394
    return static_cast<ProcessModel*>(obj);
3✔
UNCOV
395
  return nullptr;
×
396
}
3✔
397

UNCOV
398
const ProcessModel* parentProcess(const QObject* obj) noexcept
×
399
{
UNCOV
400
  if(obj)
×
UNCOV
401
    obj = obj->parent();
×
402

UNCOV
403
  while(obj && !qobject_cast<const ProcessModel*>(obj))
×
404
  {
UNCOV
405
    obj = obj->parent();
×
406
  }
407

UNCOV
408
  if(obj)
×
UNCOV
409
    return static_cast<const ProcessModel*>(obj);
×
UNCOV
410
  return nullptr;
×
UNCOV
411
}
×
412

UNCOV
413
QString processLocalTreeAddress(const ProcessModel& proc)
×
414
{
UNCOV
415
  if(auto lt = findComponent<LocalTree::ProcessComponent>(proc.components()))
×
416
  {
UNCOV
417
    return QString::fromStdString(
×
UNCOV
418
        lt->node().get_device().get_name() + ":" + lt->node().osc_address());
×
419
  }
UNCOV
420
  return {};
×
UNCOV
421
}
×
422
}
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