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

ossia / score / 32087120990

18 Aug 2026 01:08AM UTC coverage: 20.317%. First build
32087120990

Pull #1978

github

web-flow
Merge c5ee03443 into 0f30d0460
Pull Request #1978: js: experiment with QtQuick-based nodal process

4 of 357 new or added lines in 10 files covered. (1.12%)

43467 of 213941 relevant lines covered (20.32%)

5550.57 hits per line

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

62.21
/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)
8,530✔
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
4,760✔
41
{
42
  static const ossia::flat_map<QString, QIcon> categoryIcon{
5,075✔
43
      {"AI", makeIcon(QStringLiteral(":/icons/ai.png"))},
21✔
44
      {"Analysis", makeIcon(QStringLiteral(":/icons/analysis.png"))},
21✔
45
      {"Audio", makeIcon(QStringLiteral(":/icons/audio.png"))},
21✔
46
      {"Plugins", makeIcon(QStringLiteral(":/icons/filter.png"))},
21✔
47
      {"Midi", makeIcon(QStringLiteral(":/icons/midi.png"))},
21✔
48
      {"Control", makeIcon(QStringLiteral(":/icons/controls.png"))},
21✔
49
      {"Visuals", makeIcon(QStringLiteral(":/icons/gfx.png"))},
21✔
50
      {"Automations", makeIcon(QStringLiteral(":/icons/automation.png"))},
21✔
51
      {"Impro", makeIcon(QStringLiteral(":/icons/controls.png"))},
21✔
52
      {"Script", makeIcon(QStringLiteral(":/icons/script.png"))},
21✔
53
      {"Structure", makeIcon(QStringLiteral(":/icons/structure.png"))},
21✔
54
      {"Network", makeIcon(QStringLiteral(":/icons/sync.png"))},
21✔
55
      {"Monitoring", makeIcon(QStringLiteral(":/icons/ui.png"))},
21✔
56
      {"Spatialization", makeIcon(QStringLiteral(":/icons/spatial.png"))},
21✔
57
      {"Timing", makeIcon(QStringLiteral(":/icons/timing.png"))},
21✔
58
  };
59
  static const QIcon invalid;
4,760✔
60
  if(auto it = categoryIcon.find(category); it != categoryIcon.end())
4,760✔
61
  {
62
    return it->second;
4,675✔
63
  }
64
  if(auto slash_it = category.indexOf("/"); slash_it != -1)
85✔
65
  {
66
    if(auto it = categoryIcon.find(category.mid(0, slash_it)); it != categoryIcon.end())
×
67
    {
68
      return it->second;
×
69
    }
70
  }
×
71
  return invalid;
85✔
72
}
4,760✔
73
ProcessModel::ProcessModel(
1,064✔
74
    TimeVal duration, const Id<ProcessModel>& id, const QString& name, QObject* parent)
75
    : Entity{id, name, parent}
532✔
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
{
1,064✔
82
  ossia::disable_fpe();
532✔
83
  con(metadata(), &score::ModelMetadata::NameChanged, this,
1,064✔
84
      [this] { prettyNameChanged(); });
1,074✔
85
  connect(this, &Process::ProcessModel::resetExecution, this, [this] {
557✔
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);
92
}
×
93

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

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

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

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

114
void ProcessModel::setDurationAndShrink(const TimeVal& newDuration) noexcept
×
115
{
116
  setDuration(newDuration);
×
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✔
126
}
×
127

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

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

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

167
TimeVal ProcessModel::contentDuration() const noexcept
×
168
{
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
1,076✔
179
{
180
  return m_duration;
1,076✔
181
}
182

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

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

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

198
Selection ProcessModel::selectedChildren() const noexcept
×
199
{
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✔
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
{
249
  return {};
×
250
}
251

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

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

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
    {
263
      f(*ctrl, ctrl->value());
×
264
    }
×
265
  }
266
}
×
267

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

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

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

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

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

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

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

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

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

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

333
FoldMode ProcessModel::foldMode() const noexcept
732✔
334
{
335
  return m_foldMode;
732✔
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
33✔
348
{
349
  switch(m_foldMode)
33✔
350
  {
351
    case FoldMode::Folded:
352
      return true;
5✔
353
    case FoldMode::Unfolded:
354
      return false;
2✔
355
    case FoldMode::Auto:
26✔
356
    default:
357
      return std::ssize(m_inlets) > MaxUnpaginatedControls;
26✔
358
  }
359
}
33✔
360

NEW
361
QList<Inlet*> ProcessModel::inletsList() const noexcept
×
362
{
NEW
363
  QList<Inlet*> l;
×
NEW
364
  l.reserve(m_inlets.size());
×
NEW
365
  for(auto* p : m_inlets)
×
NEW
366
    l.push_back(p);
×
NEW
367
  return l;
×
NEW
368
}
×
369

NEW
370
QList<Outlet*> ProcessModel::outletsList() const noexcept
×
371
{
NEW
372
  QList<Outlet*> l;
×
NEW
373
  l.reserve(m_outlets.size());
×
NEW
374
  for(auto* p : m_outlets)
×
NEW
375
    l.push_back(p);
×
NEW
376
  return l;
×
NEW
377
}
×
378

NEW
379
Inlet* ProcessModel::inletAt(int index) const noexcept
×
380
{
NEW
381
  if(index >= 0 && index < (int)m_inlets.size())
×
NEW
382
    return m_inlets[index];
×
NEW
383
  return nullptr;
×
NEW
384
}
×
385

NEW
386
Outlet* ProcessModel::outletAt(int index) const noexcept
×
387
{
NEW
388
  if(index >= 0 && index < (int)m_outlets.size())
×
NEW
389
    return m_outlets[index];
×
NEW
390
  return nullptr;
×
NEW
391
}
×
392

NEW
393
int ProcessModel::inletCount() const noexcept
×
394
{
NEW
395
  return m_inlets.size();
×
396
}
397

NEW
398
int ProcessModel::outletCount() const noexcept
×
399
{
NEW
400
  return m_outlets.size();
×
401
}
402

NEW
403
bool ProcessModel::hasFlag(int flag) const noexcept
×
404
{
NEW
405
  return (flags() & static_cast<ProcessFlags>(flag)) != ProcessFlags{};
×
406
}
407

408
double ProcessModel::getSlotHeight() const noexcept
3,636✔
409
{
410
  return m_slotHeight;
3,636✔
411
}
412

413
void ProcessModel::setSlotHeight(double v) noexcept
89✔
414
{
415
  m_slotHeight = v;
89✔
416
  slotHeightChanged(v);
89✔
417
}
89✔
418

419
void ProcessModel::setExecuting(bool e)
35✔
420
{
421
  m_executing = e;
35✔
422
}
35✔
423

424
std::optional<Process::MagneticInfo>
425
ProcessModel::magneticPosition(const QObject* o, const TimeVal t) const noexcept
×
426
{
427
  return {};
×
428
}
429

430
ProcessModel* parentProcess(QObject* obj) noexcept
3✔
431
{
432
  if(obj)
3✔
433
    obj = obj->parent();
3✔
434

435
  while(obj && !qobject_cast<ProcessModel*>(obj))
3✔
436
  {
437
    obj = obj->parent();
×
438
  }
439

440
  if(obj)
3✔
441
    return static_cast<ProcessModel*>(obj);
3✔
442
  return nullptr;
×
443
}
3✔
444

445
const ProcessModel* parentProcess(const QObject* obj) noexcept
×
446
{
447
  if(obj)
×
448
    obj = obj->parent();
×
449

450
  while(obj && !qobject_cast<const ProcessModel*>(obj))
×
451
  {
452
    obj = obj->parent();
×
453
  }
454

455
  if(obj)
×
456
    return static_cast<const ProcessModel*>(obj);
×
457
  return nullptr;
×
458
}
×
459

460
QString processLocalTreeAddress(const ProcessModel& proc)
×
461
{
462
  if(auto lt = findComponent<LocalTree::ProcessComponent>(proc.components()))
×
463
  {
464
    return QString::fromStdString(
×
465
        lt->node().get_device().get_name() + ":" + lt->node().osc_address());
×
466
  }
467
  return {};
×
468
}
×
469
}
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