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

ossia / score / 35310244323

18 Sep 2026 05:17AM UTC coverage: 39.902% (+2.2%) from 37.724%
35310244323

push

github

jcelerier
tests: include CommandDispatcher where JsLibraryScriptSavingTest uses it

ee4b67af6f added the test with a CommandDispatcher<> but without its header,
relying on it arriving transitively. The Coverage build compiles with clang-19
at gnu++23 and does not get it that way:

  JsLibraryScriptSavingTest.cpp:70:3: error: no template named 'CommandDispatcher'

This has been broken since 2026-09-13 and was hidden behind the boost download
failure, which stopped that job before it ever reached the compile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1e2ZdUQh7Srmv6BGVakrQ

114906 of 287968 relevant lines covered (39.9%)

77906.02 hits per line

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

56.93
/src/plugins/score-lib-process/Process/Dataflow/WidgetInlets.cpp
1
#include <Process/Dataflow/WidgetInlets.hpp>
2

3
#include <score/plugins/SerializableHelpers.hpp>
4
#include <score/tools/FileWatch.hpp>
5

6
#include <ossia/dataflow/port.hpp>
7

8
#include <ossia-qt/invoke.hpp>
9

10
#include <QCoreApplication>
11
#include <QDir>
12
#include <QFileSystemWatcher>
13

14
#include <wobjectimpl.h>
15

16
W_OBJECT_IMPL(Process::ComboBox)
17,821✔
17
W_OBJECT_IMPL(Process::FileChooserBase)
2✔
18
W_OBJECT_IMPL(Process::FileChooser)
861✔
19
W_OBJECT_IMPL(Process::FolderChooser)
3✔
20
W_OBJECT_IMPL(Process::AudioFileChooser)
3✔
21
W_OBJECT_IMPL(Process::VideoFileChooser)
×
22
W_OBJECT_IMPL(Process::ImpulseButton)
120✔
23
namespace Process
24
{
25
Enum::Enum(
160✔
26
    const std::vector<std::string>& dom, std::vector<QString> pixmaps, std::string init,
27
    const QString& name, Id<Port> id, QObject* parent)
28
    : ControlInlet{name, id, parent}
160✔
29
    , pixmaps{std::move(pixmaps)}
160✔
30
{
160✔
31
  for(auto& val : dom)
846✔
32
    values.push_back(QString::fromStdString(val));
686✔
33

34
  displayHandledExplicitly = true;
160✔
35
  setInit(init);
160✔
36
  setValue(init);
160✔
37
  setDomain(State::Domain{ossia::domain_base<std::string>{dom}});
160✔
38
}
160✔
39

40
Enum::Enum(
×
41
    const QStringList& values, std::vector<QString> pixmaps, std::string init,
42
    const QString& name, Id<Port> id, QObject* parent)
43
    : ControlInlet{name, id, parent}
×
44
    , values{values.begin(), values.end()}
×
45
    , pixmaps{std::move(pixmaps)}
×
46
{
×
47
  displayHandledExplicitly = true;
×
48
  setInit(init);
×
49
  setValue(init);
×
50
  ossia::domain_base<std::string> dom;
×
51
  for(auto& val : values)
×
52
    dom.values.push_back(val.toStdString());
×
53
  setDomain(State::Domain{dom});
×
54
}
×
55

56
Enum::~Enum() { }
820✔
57

58
Enum::Enum(DataStream::Deserializer& vis, QObject* parent)
250✔
59
    : ControlInlet{vis, parent}
125✔
60
{
125✔
61
  vis.writeTo(*this);
125✔
62
}
125✔
63
Enum::Enum(JSONObject::Deserializer& vis, QObject* parent)
250✔
64
    : ControlInlet{vis, parent}
125✔
65
{
125✔
66
  vis.writeTo(*this);
125✔
67
}
125✔
68
Enum::Enum(DataStream::Deserializer&& vis, QObject* parent)
×
69
    : ControlInlet{vis, parent}
×
70
{
×
71
  vis.writeTo(*this);
×
72
}
×
73
Enum::Enum(JSONObject::Deserializer&& vis, QObject* parent)
×
74
    : ControlInlet{vis, parent}
×
75
{
×
76
  vis.writeTo(*this);
×
77
}
×
78

79
void Enum::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
80
{
81
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
82
  port.type = ossia::val_type::STRING;
×
83
  port.domain = domain().get();
×
84
}
×
85

86
ComboBox::ComboBox(DataStream::Deserializer& vis, QObject* parent)
352✔
87
    : ControlInlet{vis, parent}
176✔
88
{
176✔
89
  vis.writeTo(*this);
176✔
90
}
×
91
ComboBox::ComboBox(
633✔
92
    std::vector<std::pair<QString, ossia::value>> values, ossia::value init,
93
    const QString& name, Id<Port> id, QObject* parent)
94
    : ControlInlet{name, id, parent}
633✔
95
    , alternatives{std::move(values)}
633✔
96
{
633✔
97
  displayHandledExplicitly = true;
633✔
98
  setInit(init);
633✔
99
  setValue(init);
633✔
100
  std::vector<ossia::value> vals;
633✔
101
  for(auto& v : alternatives)
5,398✔
102
    vals.push_back(v.second);
4,765✔
103
  setDomain(State::Domain{ossia::make_domain(vals)});
633✔
104
}
×
105

106
void ComboBox::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
297✔
107
{
108
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
297✔
109
  port.domain = domain().get();
297✔
110
}
297✔
111

112
void ComboBox::repopulateFromFolder(const QString& folderPath)
6✔
113
{
114
  std::vector<std::pair<QString, ossia::value>> alts;
6✔
115
  if(!folderPath.isEmpty())
6✔
116
  {
117
    QDir dir(folderPath);
5✔
118
    const auto files = fileExtensions.isEmpty()
10✔
119
                           ? dir.entryList(QDir::Files, QDir::Name)
4✔
120
                           : dir.entryList(fileExtensions, QDir::Files, QDir::Name);
1✔
121
    for(const auto& f : files)
13✔
122
      alts.emplace_back(f, f.toStdString()); // value = the file name itself
8✔
123
  }
5✔
124
  if(alts.empty())
6✔
125
    alts.emplace_back(QStringLiteral("-"), std::string("-"));
3✔
126
  setAlternatives(std::move(alts));
6✔
127

128
  // Watch the folder so files created while the document is open (e.g. by an
129
  // upstream process writing its analysis) appear in the list right away.
130
  if(folderPath != m_watchedFolder)
6✔
131
  {
132
    if(m_folderWatcher)
6✔
133
    {
134
      delete m_folderWatcher;
1✔
135
      m_folderWatcher = nullptr;
1✔
136
    }
1✔
137
    m_watchedFolder = folderPath;
6✔
138
    if(!folderPath.isEmpty() && QDir{folderPath}.exists())
11✔
139
    {
140
      m_folderWatcher = new QFileSystemWatcher{{folderPath}, this};
4✔
141
      connect(
4✔
142
          m_folderWatcher, &QFileSystemWatcher::directoryChanged, this,
4✔
143
          [this](const QString& path) { repopulateFromFolder(path); });
4✔
144
    }
4✔
145
  }
6✔
146
}
6✔
147

148
void ComboBox::setAlternatives(std::vector<std::pair<QString, ossia::value>> values)
11✔
149
{
150
  if(values == alternatives)
11✔
151
    return;
5✔
152
  alternatives = std::move(values);
6✔
153

154
  std::vector<ossia::value> vals;
6✔
155
  for(auto& v : alternatives)
22✔
156
    vals.push_back(v.second);
16✔
157
  // Not setDomain(): what changed is the item list, and alternativesChanged
158
  // below says exactly that. Announcing a domain change instead makes the
159
  // effect item rebuild every control of the process, which kills whatever
160
  // edit is in flight -- and for a combo box refilled from the running score,
161
  // that includes the control the user is dragging to refill it.
162
  setDomainWithoutNotifying(State::Domain{ossia::make_domain(vals)});
6✔
163

164
  // Keep the current value if it is still in the list; otherwise fall back to
165
  // the init value when available. A value absent from the list is left
166
  // untouched: for folder-backed comboboxes it may name a file that simply
167
  // does not exist *yet* — it becomes selectable (and shows up as selected)
168
  // once the file appears.
169
  if(!alternatives.empty())
6✔
170
  {
171
    auto in_list = [this](const ossia::value& v) {
16✔
172
      return ossia::find_if(
20✔
173
                 alternatives, [&](const auto& pair) { return pair.second == v; })
31✔
174
             != alternatives.end();
10✔
175
    };
176
    if(!in_list(value()) && in_list(init()))
6✔
177
      setValue(init());
1✔
178
  }
6✔
179

180
  alternativesChanged();
6✔
181
}
11✔
182

183
ComboBox::~ComboBox() { }
1,999✔
184

185
ComboBox::ComboBox(JSONObject::Deserializer& vis, QObject* parent)
402✔
186
    : ControlInlet{vis, parent}
201✔
187
{
201✔
188
  vis.writeTo(*this);
201✔
189
}
×
190
ComboBox::ComboBox(DataStream::Deserializer&& vis, QObject* parent)
×
191
    : ControlInlet{vis, parent}
×
192
{
×
193
  vis.writeTo(*this);
×
194
}
×
195
ComboBox::ComboBox(JSONObject::Deserializer&& vis, QObject* parent)
×
196
    : ControlInlet{vis, parent}
×
197
{
×
198
  vis.writeTo(*this);
×
199
}
×
200

201
HSVSlider::HSVSlider(
28✔
202
    ossia::vec4f init, const QString& name, Id<Port> id, QObject* parent)
203
    : ControlInlet{name, id, parent}
28✔
204
{
28✔
205
  displayHandledExplicitly = true;
28✔
206
  setInit(init);
28✔
207
  setValue(init);
28✔
208
}
28✔
209

210
HSVSlider::~HSVSlider() { }
78✔
211

212
const State::Unit& HSVSlider::unit() const noexcept
40✔
213
{
214
  static const State::Unit u{ossia::unit_t{ossia::rgba_u{}}};
40✔
215
  return u;
40✔
216
}
217

218
void HSVSlider::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
20✔
219
{
220
  // The unit, not just the value type: it is what makes an address declared
221
  // color.rgb (or hsv, or any other colour unit) arrive here as the rgba this
222
  // control reads. Without it value_port::effective_type() is empty and
223
  // adapt_value() has nothing to convert towards.
224
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
20✔
225
  port.type = unit().get();
20✔
226
}
20✔
227

228
FloatSlider::FloatSlider(
1,213✔
229
    float min, float max, float init, const QString& name, Id<Port> id, QObject* parent)
230
    : ControlInlet{name, id, parent}
1,213✔
231
{
1,213✔
232
  displayHandledExplicitly = true;
1,213✔
233
  setInit(init);
1,213✔
234
  setValue(init);
1,213✔
235
  setDomain(ossia::make_domain(min, max));
1,213✔
236
}
1,213✔
237

238
FloatSlider::~FloatSlider() { }
4,348✔
239

240
void FloatSlider::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
155✔
241
{
242
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
155✔
243
  port.type = ossia::val_type::FLOAT;
155✔
244
  port.domain = domain().get();
155✔
245
}
155✔
246

247
FloatKnob::FloatKnob(
645✔
248
    float min, float max, float init, const QString& name, Id<Port> id, QObject* parent)
249
    : ControlInlet{name, id, parent}
645✔
250
{
645✔
251
  displayHandledExplicitly = true;
645✔
252
  setInit(init);
645✔
253
  setValue(init);
645✔
254
  setDomain(ossia::make_domain(min, max));
645✔
255
}
645✔
256

257
FloatKnob::~FloatKnob() { }
3,374✔
258

259
void FloatKnob::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
260
{
261
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
262
  port.type = ossia::val_type::FLOAT;
×
263
  port.domain = domain().get();
×
264
}
×
265

266
LogFloatSlider::LogFloatSlider(
49✔
267
    float min, float max, float init, const QString& name, Id<Port> id, QObject* parent)
268
    : ControlInlet{name, id, parent}
49✔
269
{
49✔
270
  displayHandledExplicitly = true;
49✔
271
  setInit(init);
49✔
272
  setValue(init);
49✔
273
  setDomain(ossia::make_domain(min, max));
49✔
274
}
49✔
275

276
LogFloatSlider::~LogFloatSlider() { }
216✔
277

278
void LogFloatSlider::setupExecution(
×
279
    ossia::inlet& inl, QObject* exec_context) const noexcept
280
{
281
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
282
  port.type = ossia::val_type::FLOAT;
×
283
  port.domain = domain().get();
×
284
}
×
285

286
IntSlider::IntSlider(
209✔
287
    int min, int max, int init, const QString& name, Id<Port> id, QObject* parent)
288
    : ControlInlet{name, id, parent}
209✔
289
{
209✔
290
  displayHandledExplicitly = true;
209✔
291
  setInit(init);
209✔
292
  setValue(init);
209✔
293
  setDomain(ossia::make_domain(min, max));
209✔
294
}
209✔
295

296
IntSlider::~IntSlider() { }
800✔
297

298
void IntSlider::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
59✔
299
{
300
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
59✔
301
  port.type = ossia::val_type::INT;
59✔
302
  port.domain = domain().get();
59✔
303
}
59✔
304

305
IntRangeSlider::IntRangeSlider(
×
306
    int min, int max, ossia::vec2f init, const QString& name, Id<Port> id,
307
    QObject* parent)
308
    : ControlInlet{name, id, parent}
×
309
{
×
310
  displayHandledExplicitly = true;
×
311
  setInit(init);
×
312
  setValue(init);
×
313
  setDomain(ossia::make_domain(min, max));
×
314
}
×
315

316
IntRangeSlider::~IntRangeSlider() { }
×
317

318
void IntRangeSlider::setupExecution(
×
319
    ossia::inlet& inl, QObject* exec_context) const noexcept
320
{
321
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
322
  port.type = ossia::val_type::VEC2F;
×
323
  port.domain = domain().get();
×
324
}
×
325

326
FloatRangeSlider::FloatRangeSlider(
6✔
327
    float min, float max, ossia::vec2f init, const QString& name, Id<Port> id,
328
    QObject* parent)
329
    : ControlInlet{name, id, parent}
6✔
330
{
6✔
331
  displayHandledExplicitly = true;
6✔
332
  setInit(init);
6✔
333
  setValue(init);
6✔
334
  setDomain(ossia::make_domain(min, max));
6✔
335
}
6✔
336

337
FloatRangeSlider::~FloatRangeSlider() { }
36✔
338

339
void FloatRangeSlider::setupExecution(
×
340
    ossia::inlet& inl, QObject* exec_context) const noexcept
341
{
342
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
343
  port.type = ossia::val_type::VEC2F;
×
344
  port.domain = domain().get();
×
345
}
×
346

347
IntRangeSpinBox::IntRangeSpinBox(
×
348
    int min, int max, ossia::vec2f init, const QString& name, Id<Port> id,
349
    QObject* parent)
350
    : ControlInlet{name, id, parent}
×
351
{
×
352
  displayHandledExplicitly = true;
×
353
  setInit(init);
×
354
  setValue(init);
×
355
  setDomain(ossia::make_domain(min, max));
×
356
}
×
357
IntRangeSpinBox::~IntRangeSpinBox() { }
×
358

359
void IntRangeSpinBox::setupExecution(
×
360
    ossia::inlet& inl, QObject* exec_context) const noexcept
361
{
362
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
363
  port.type = ossia::val_type::VEC2F;
×
364
  port.domain = domain().get();
×
365
}
×
366

367
FloatRangeSpinBox::FloatRangeSpinBox(
×
368
    float min, float max, ossia::vec2f init, const QString& name, Id<Port> id,
369
    QObject* parent)
370
    : ControlInlet{name, id, parent}
×
371
{
×
372
  displayHandledExplicitly = true;
×
373
  setInit(init);
×
374
  setValue(init);
×
375
  setDomain(ossia::make_domain(min, max));
×
376
}
×
377

378
FloatRangeSpinBox::~FloatRangeSpinBox() { }
×
379

380
void FloatRangeSpinBox::setupExecution(
×
381
    ossia::inlet& inl, QObject* exec_context) const noexcept
382
{
383
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
384
  port.type = ossia::val_type::VEC2F;
×
385
  port.domain = domain().get();
×
386
}
×
387

388
IntSpinBox::IntSpinBox(
503✔
389
    int min, int max, int init, const QString& name, Id<Port> id, QObject* parent)
390
    : ControlInlet{name, id, parent}
503✔
391
{
503✔
392
  displayHandledExplicitly = true;
503✔
393
  setInit(init);
503✔
394
  setValue(init);
503✔
395
  setDomain(ossia::make_domain(min, max));
503✔
396
}
503✔
397

398
void IntSpinBox::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
29✔
399
{
400
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
29✔
401
  port.type = ossia::val_type::INT;
29✔
402
  port.domain = domain().get();
29✔
403
}
29✔
404

405
IntSpinBox::~IntSpinBox() { }
1,917✔
406

407
FloatSpinBox::FloatSpinBox(
107✔
408
    float min, float max, float init, const QString& name, Id<Port> id, QObject* parent)
409
    : ControlInlet{name, id, parent}
107✔
410
{
107✔
411
  displayHandledExplicitly = true;
107✔
412
  setInit(init);
107✔
413
  setValue(init);
107✔
414
  setDomain(ossia::make_domain(min, max));
107✔
415
}
107✔
416

417
void FloatSpinBox::setupExecution(
12✔
418
    ossia::inlet& inl, QObject* exec_context) const noexcept
419
{
420
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
12✔
421
  port.type = ossia::val_type::FLOAT;
12✔
422
  port.domain = domain().get();
12✔
423
}
12✔
424

425
FloatSpinBox::~FloatSpinBox() { }
546✔
426

427
TimeChooser::TimeChooser(
132✔
428
    float min, float max, float init, const QString& name, Id<Port> id, QObject* parent)
429
    : ControlInlet{name, id, parent}
132✔
430
{
132✔
431
  displayHandledExplicitly = true;
132✔
432
  // The second component is the mode: 0 is a time in seconds, anything else is
433
  // a musical denomination. It starts at 0, which is what the object declaring
434
  // the control says too -- halp::time_chooser_t has `bool sync{false}`.
435
  //
436
  // It used to start synced, and that made every such control's default wrong:
437
  // the value the process declared as its init was read as a number of quarter
438
  // notes and converted to seconds against the tempo, so a control asking for
439
  // two seconds got two quarters instead. Deuterium's sampler carries a
440
  // work-around for exactly this.
441
  setValue(ossia::vec2f{init, 0.f});
132✔
442
  setInit(value());
132✔
443
  setDomain(ossia::make_domain(ossia::vec2f{min, 0.f}, ossia::vec2f{max, 1.f}));
132✔
444
}
132✔
445

446
TimeChooser::~TimeChooser() { }
481✔
447

448
void TimeChooser::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
449
{
450
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
451
  port.type = ossia::val_type::VEC2F;
×
452
  // port.type = ossia::second_u{};
453
  // port.domain = domain().get();
454
}
×
455

456
Toggle::Toggle(bool init, const QString& name, Id<Port> id, QObject* parent)
431✔
457
    : ControlInlet{name, id, parent}
431✔
458
{
431✔
459
  displayHandledExplicitly = true;
431✔
460
  setInit(init);
431✔
461
  setValue(init);
431✔
462
  setDomain(State::Domain{ossia::domain_base<bool>{}});
431✔
463
}
431✔
464

465
void Toggle::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
46✔
466
{
467
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
46✔
468
  port.type = ossia::val_type::BOOL;
46✔
469
  port.domain = domain().get();
46✔
470
}
46✔
471

472
Toggle::~Toggle() { }
1,754✔
473

474
ChooserToggle::ChooserToggle(
×
475
    QStringList alternatives, bool init, const QString& name, Id<Port> id,
476
    QObject* parent)
477
    : ControlInlet{name, id, parent}
×
478
{
×
479
  displayHandledExplicitly = true;
×
480
  setValue(init ? alternatives[1].toStdString() : alternatives[0].toStdString());
×
481
  setInit(value());
×
482
  setDomain(
×
483
      State::Domain{ossia::domain_base<std::string>{
×
484
          {alternatives[0].toStdString(), alternatives[1].toStdString()}}});
×
485
}
×
486

487
void ChooserToggle::setupExecution(
×
488
    ossia::inlet& inl, QObject* exec_context) const noexcept
489
{
490
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
491
  port.type = ossia::val_type::STRING;
×
492
  port.domain = domain().get();
×
493
}
×
494

495
ChooserToggle::~ChooserToggle() { }
×
496

497
QStringList ChooserToggle::alternatives() const noexcept
×
498
{
499
  const auto& dom = *this->domain().get().v.target<ossia::domain_base<std::string>>();
×
500
  auto it = dom.values.begin();
×
501
  auto& s1 = *it;
×
502
  auto& s2 = *(++it);
×
503
  return {QString::fromStdString(s1), QString::fromStdString(s2)};
×
504
}
505

506
LineEdit::LineEdit(QString init, const QString& name, Id<Port> id, QObject* parent)
207✔
507
    : ControlInlet{name, id, parent}
207✔
508
{
207✔
509
  displayHandledExplicitly = true;
207✔
510
  setValue(init.toStdString());
207✔
511
  setInit(value());
207✔
512
}
207✔
513

514
void LineEdit::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
92✔
515
{
516
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
92✔
517
  port.type = ossia::val_type::STRING;
92✔
518
  port.domain = domain().get();
92✔
519
}
92✔
520

521
LineEdit::~LineEdit() { }
717✔
522

523
ProgramEdit::ProgramEdit(QString init, const QString& name, Id<Port> id, QObject* parent)
10✔
524
    : ControlInlet{name, id, parent}
10✔
525
{
10✔
526
  displayHandledExplicitly = true;
10✔
527
  setValue(init.toStdString());
10✔
528
  setInit(value());
10✔
529
}
10✔
530

531
void ProgramEdit::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
532
{
533
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
534
  port.type = ossia::val_type::STRING;
×
535
  port.domain = domain().get();
×
536
}
×
537

538
ProgramEdit::~ProgramEdit() { }
36✔
539

540
FileChooserBase::FileChooserBase(
91✔
541
    QString init, QString filters, const QString& name, Id<Port> id, QObject* parent)
542
    : ControlInlet{name, id, parent}
91✔
543
{
91✔
544
  displayHandledExplicitly = true;
91✔
545
  setValue(init.toStdString());
91✔
546
  setInit(value());
91✔
547
  m_filters = filters;
91✔
548
}
91✔
549

550
void FileChooserBase::setupExecution(
×
551
    ossia::inlet& inl, QObject* exec_context) const noexcept
552
{
553
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
554
  port.type = ossia::val_type::STRING;
×
555
  port.domain = domain().get();
×
556
}
×
557

558
void FileChooserBase::enableFileWatch()
2✔
559
{
560
  auto fun = std::make_shared<std::function<void()>>([ptr = QPointer{this}]() mutable {
2✔
561
    ossia::qt::run_async(qApp, [ptr] {
×
562
      if(ptr)
×
563
      {
564
        // This will trigger a reload
565
        // FIXME make it work with execution value changes
566
        ptr->valueChanged(ptr->value());
×
567
      }
×
568
    });
×
569
  });
×
570

571
  auto& f = score::FileWatch::instance();
2✔
572
  f.add(QString::fromStdString(ossia::convert<std::string>(this->value())), fun);
2✔
573

574
  connect(
2✔
575
      this, &Process::FileChooser::valueChanged, this,
576
      [cur_s = ossia::convert<std::string>(this->value()),
2✔
577
       fun](const ossia::value& v) mutable {
2✔
578
    auto new_s = ossia::convert<std::string>(v);
×
579
    if(new_s != cur_s)
×
580
    {
581
      auto& f = score::FileWatch::instance();
×
582
      f.remove(QString::fromStdString(cur_s), fun);
×
583
      f.add(QString::fromStdString(new_s), fun);
×
584
      cur_s = new_s;
×
585
    }
×
586
      });
×
587

588
  connect(this, &Process::FileChooser::destroying, this, [this, fun] {
4✔
589
    auto& f = score::FileWatch::instance();
2✔
590
    f.remove(QString::fromStdString(ossia::convert<std::string>(this->value())), fun);
2✔
591
  });
2✔
592
}
2✔
593

594
FileChooserBase::~FileChooserBase()
200✔
595
{
200✔
596
  destroying();
200✔
597
}
200✔
598

599
FileChooser::FileChooser(
89✔
600
    QString init, QString filters, const QString& name, Id<Port> id, QObject* parent)
601
    : FileChooserBase{init, filters, name, id, parent}
89✔
602
{
89✔
603
}
89✔
604

605
FileChooser::~FileChooser() { }
387✔
606

607
FileChooser::FileChooser(DataStream::Deserializer& vis, QObject* parent)
51✔
608
    : FileChooserBase{vis, parent}
51✔
609
{
51✔
610
  vis.writeTo(*this);
51✔
611
}
51✔
612
FileChooser::FileChooser(JSONObject::Deserializer& vis, QObject* parent)
54✔
613
    : FileChooserBase{vis, parent}
54✔
614
{
54✔
615
  vis.writeTo(*this);
54✔
616
}
54✔
617
FileChooser::FileChooser(DataStream::Deserializer&& vis, QObject* parent)
×
618
    : FileChooserBase{vis, parent}
×
619
{
×
620
  vis.writeTo(*this);
×
621
}
×
622
FileChooser::FileChooser(JSONObject::Deserializer&& vis, QObject* parent)
×
623
    : FileChooserBase{vis, parent}
×
624
{
×
625
  vis.writeTo(*this);
×
626
}
×
627

628
FolderChooser::FolderChooser(
1✔
629
    QString init, const QString& name, Id<Port> id, QObject* parent)
630
    : Process::ControlInlet{name, id, parent}
1✔
631
{
1✔
632
  displayHandledExplicitly = true;
1✔
633
  setValue(init.toStdString());
1✔
634
  setInit(value());
1✔
635
}
1✔
636

637
void FolderChooser::setupExecution(
×
638
    ossia::inlet& inl, QObject* exec_context) const noexcept
639
{
640
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
641
  port.type = ossia::val_type::STRING;
×
642
  port.domain = domain().get();
×
643
}
×
644

645
FolderChooser::~FolderChooser() { }
6✔
646

647
AudioFileChooser::AudioFileChooser(
2✔
648
    QString init, QString filters, const QString& name, Id<Port> id, QObject* parent)
649
    : FileChooserBase{init, filters, name, id, parent}
2✔
650
{
2✔
651
}
2✔
652

653
AudioFileChooser::~AudioFileChooser() { }
11✔
654

655
AudioFileChooser::AudioFileChooser(DataStream::Deserializer& vis, QObject* parent)
2✔
656
    : FileChooserBase{vis, parent}
2✔
657
{
2✔
658
  vis.writeTo(*this);
2✔
659
}
2✔
660
AudioFileChooser::AudioFileChooser(JSONObject::Deserializer& vis, QObject* parent)
2✔
661
    : FileChooserBase{vis, parent}
2✔
662
{
2✔
663
  vis.writeTo(*this);
2✔
664
}
2✔
665
AudioFileChooser::AudioFileChooser(DataStream::Deserializer&& vis, QObject* parent)
×
666
    : FileChooserBase{vis, parent}
×
667
{
×
668
  vis.writeTo(*this);
×
669
}
×
670
AudioFileChooser::AudioFileChooser(JSONObject::Deserializer&& vis, QObject* parent)
×
671
    : FileChooserBase{vis, parent}
×
672
{
×
673
  vis.writeTo(*this);
×
674
}
×
675

676
static QString toFilters(const QSet<QString>& exts)
×
677
{
678
  QString res;
×
679
  for(const auto& s : exts)
×
680
  {
681
    res += "*.";
×
682
    res += s;
×
683
    res += " ";
×
684
  }
685
  if(!res.isEmpty())
×
686
    res.resize(res.size() - 1);
×
687
  return res;
×
688
}
×
689

690
static QString videoFilesTypes()
×
691
{
692
  // FIXME refactor supported formats with Video process
693
  QSet<QString> files = {"mkv", "mov", "mp4", "h264", "avi", "hap",  "mpg", "mpeg",
×
694
                          "imf", "mxf", "mts", "m2ts", "mj2", "webm", "y4m", "nut", "ts"};
×
695
  return QString{"Videos (%1)"}.arg(toFilters(files));
×
696
}
×
697

698
VideoFileChooser::VideoFileChooser(
×
699
    QString init, QString filters, const QString& name, Id<Port> id, QObject* parent)
700
    : FileChooserBase{init, videoFilesTypes(), name, id, parent}
×
701
{
×
702
}
×
703

704
VideoFileChooser::~VideoFileChooser() { }
×
705

706
VideoFileChooser::VideoFileChooser(DataStream::Deserializer& vis, QObject* parent)
×
707
    : FileChooserBase{vis, parent}
×
708
{
×
709
  vis.writeTo(*this);
×
710
}
×
711
VideoFileChooser::VideoFileChooser(JSONObject::Deserializer& vis, QObject* parent)
×
712
    : FileChooserBase{vis, parent}
×
713
{
×
714
  vis.writeTo(*this);
×
715
}
×
716
VideoFileChooser::VideoFileChooser(DataStream::Deserializer&& vis, QObject* parent)
×
717
    : FileChooserBase{vis, parent}
×
718
{
×
719
  vis.writeTo(*this);
×
720
}
×
721
VideoFileChooser::VideoFileChooser(JSONObject::Deserializer&& vis, QObject* parent)
×
722
    : FileChooserBase{vis, parent}
×
723
{
×
724
  vis.writeTo(*this);
×
725
}
×
726

727
Button::Button(const QString& name, Id<Port> id, QObject* parent)
10✔
728
    : ControlInlet{name, id, parent}
10✔
729
{
10✔
730
  displayHandledExplicitly = true;
10✔
731
  setValue(false);
10✔
732
  setInit(false);
10✔
733
  setDomain(State::Domain{ossia::domain_base<bool>{}});
10✔
734
}
10✔
735

736
void Button::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
737
{
738
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
739
  port.type = ossia::val_type::BOOL;
×
740
  port.domain = domain().get();
×
741
}
×
742

743
Button::~Button() { }
60✔
744

745
ImpulseButton::ImpulseButton(const QString& name, Id<Port> id, QObject* parent)
44✔
746
    : ControlInlet{name, id, parent}
44✔
747
{
44✔
748
  displayHandledExplicitly = true;
44✔
749
  setValue(ossia::impulse{});
44✔
750
  setInit(ossia::impulse{});
44✔
751
  setDomain(State::Domain{ossia::domain_base<ossia::impulse>{}});
44✔
752
}
44✔
753

754
void ImpulseButton::setupExecution(
×
755
    ossia::inlet& inl, QObject* exec_context) const noexcept
756
{
757
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
758
  port.type = ossia::val_type::IMPULSE;
×
759
  port.domain = domain().get();
×
760
}
×
761

762
ImpulseButton::~ImpulseButton() { }
240✔
763

764
XYSlider::XYSlider(ossia::vec2f init, const QString& name, Id<Port> id, QObject* parent)
×
765
    : ControlInlet{name, id, parent}
×
766
{
×
767
  displayHandledExplicitly = true;
×
768
  setValue(init);
×
769
  setInit(init);
×
770
  setDomain(ossia::make_domain(ossia::vec2f{0., 0.}, ossia::vec2f{1., 1.}));
×
771
}
×
772

773
XYSlider::XYSlider(
9✔
774
    ossia::vec2f min, ossia::vec2f max, ossia::vec2f init, const QString& name,
775
    Id<Port> id, QObject* parent)
776
    : ControlInlet{name, id, parent}
9✔
777
{
9✔
778
  displayHandledExplicitly = true;
9✔
779
  setValue(init);
9✔
780
  setInit(init);
9✔
781
  setDomain(ossia::make_domain(min, max));
9✔
782
}
9✔
783

784
void XYSlider::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
785
{
786
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
787
  port.type = ossia::val_type::VEC2F;
×
788
  port.domain = domain().get();
×
789
}
×
790

791
XYSlider::~XYSlider() { }
46✔
792

793
XYZSlider::XYZSlider(
×
794
    ossia::vec3f init, const QString& name, Id<Port> id, QObject* parent)
795
    : ControlInlet{name, id, parent}
×
796
{
×
797
  displayHandledExplicitly = true;
×
798
  setValue(init);
×
799
  setInit(init);
×
800
  setDomain(ossia::make_domain(ossia::vec3f{0., 0., 0.}, ossia::vec3f{1., 1., 1.}));
×
801
}
×
802

803
XYZSlider::XYZSlider(
×
804
    ossia::vec3f min, ossia::vec3f max, ossia::vec3f init, const QString& name,
805
    Id<Port> id, QObject* parent)
806
    : ControlInlet{name, id, parent}
×
807
{
×
808
  displayHandledExplicitly = true;
×
809
  setValue(init);
×
810
  setInit(init);
×
811
  setDomain(ossia::make_domain(min, max));
×
812
}
×
813

814
XYZSlider::~XYZSlider() { }
2✔
815

816
void XYZSlider::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
817
{
818
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
819
  port.type = ossia::val_type::VEC3F;
×
820
  port.domain = domain().get();
×
821
}
×
822

823
XYZSpinboxes::XYZSpinboxes(
×
824
    ossia::vec3f init, const QString& name, Id<Port> id, QObject* parent)
825
    : ControlInlet{name, id, parent}
×
826
{
×
827
  displayHandledExplicitly = true;
×
828
  setValue(init);
×
829
  setInit(init);
×
830
  setDomain(ossia::make_domain(ossia::vec3f{0., 0., 0.}, ossia::vec3f{1., 1., 1.}));
×
831
}
×
832

833
XYSpinboxes::XYSpinboxes(
×
834
    ossia::vec2f init, const QString& name, Id<Port> id, QObject* parent)
835
    : ControlInlet{name, id, parent}
×
836
    , integral{false}
×
837
{
×
838
  displayHandledExplicitly = true;
×
839
  setValue(init);
×
840
  setInit(init);
×
841
}
×
842
XYSpinboxes::XYSpinboxes(
48✔
843
    ossia::vec2f min, ossia::vec2f max, ossia::vec2f init, bool integral,
844
    const QString& name, Id<Port> id, QObject* parent)
845
    : ControlInlet{name, id, parent}
48✔
846
    , integral{integral}
48✔
847
{
48✔
848
  displayHandledExplicitly = true;
48✔
849
  setValue(init);
48✔
850
  setInit(init);
48✔
851
  setDomain(ossia::make_domain(min, max));
48✔
852
}
48✔
853

854
XYSpinboxes::XYSpinboxes(DataStream::Deserializer& vis, QObject* parent)
46✔
855
    : ControlInlet{vis, parent}
46✔
856
{
46✔
857
  vis.writeTo(*this);
46✔
858
}
×
859
XYSpinboxes::XYSpinboxes(JSONObject::Deserializer& vis, QObject* parent)
46✔
860
    : ControlInlet{vis, parent}
46✔
861
{
46✔
862
  vis.writeTo(*this);
46✔
863
}
×
864
XYSpinboxes::XYSpinboxes(DataStream::Deserializer&& vis, QObject* parent)
×
865
    : ControlInlet{vis, parent}
×
866
{
×
867
  vis.writeTo(*this);
×
868
}
×
869
XYSpinboxes::XYSpinboxes(JSONObject::Deserializer&& vis, QObject* parent)
×
870
    : ControlInlet{vis, parent}
×
871
{
×
872
  vis.writeTo(*this);
×
873
}
×
874

875
XYSpinboxes::~XYSpinboxes() { }
280✔
876

877
void XYSpinboxes::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
878
{
879
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
880
  port.type = ossia::val_type::VEC2F;
×
881
  port.domain = domain().get();
×
882
}
×
883

884
XYZSpinboxes::XYZSpinboxes(
428✔
885
    ossia::vec3f min, ossia::vec3f max, ossia::vec3f init, bool integral,
886
    const QString& name, Id<Port> id, QObject* parent)
887
    : ControlInlet{name, id, parent}
428✔
888
    , integral{integral}
428✔
889
{
428✔
890
  displayHandledExplicitly = true;
428✔
891
  setValue(init);
428✔
892
  setInit(init);
428✔
893
  setDomain(ossia::make_domain(min, max));
428✔
894
}
428✔
895

896
XYZSpinboxes::~XYZSpinboxes() { }
1,212✔
897

898
void XYZSpinboxes::setupExecution(
50✔
899
    ossia::inlet& inl, QObject* exec_context) const noexcept
900
{
901
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
50✔
902
  port.type = ossia::val_type::VEC3F;
50✔
903
  port.domain = domain().get();
50✔
904
}
50✔
905

906
MultiSlider::MultiSlider(
34✔
907
    ossia::value init, const QString& name, Id<Port> id, QObject* parent)
908
    : ControlInlet{name, id, parent}
34✔
909
{
34✔
910
  displayHandledExplicitly = true;
34✔
911
  setValue(std::move(init));
34✔
912
  setInit(value());
34✔
913
  setDomain(ossia::make_domain(0., 1.));
34✔
914
}
34✔
915

916
MultiSlider::~MultiSlider() { }
50✔
917

918
ossia::value MultiSlider::getMin() const noexcept
×
919
{
920
  return domain().get().get_min();
×
921
}
922

923
ossia::value MultiSlider::getMax() const noexcept
×
924
{
925
  return domain().get().get_max();
×
926
}
927

928
void MultiSlider::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
929
{
930
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
931
  port.type = ossia::val_type::LIST;
×
932
  port.domain = domain().get();
×
933
}
×
934

935
MultiSliderXY::MultiSliderXY(
1✔
936
    ossia::value init, const QString& name, Id<Port> id, QObject* parent)
937
    : ControlInlet{name, id, parent}
1✔
938
{
1✔
939
  displayHandledExplicitly = true;
1✔
940
  setValue(std::move(init));
1✔
941
  setInit(value());
1✔
942
  setDomain(ossia::make_domain(0., 1.));
1✔
943
}
1✔
944

945
MultiSliderXY::~MultiSliderXY() { }
6✔
946

947
ossia::value MultiSliderXY::getMin() const noexcept
×
948
{
949
  return domain().get().get_min();
×
950
}
951

952
ossia::value MultiSliderXY::getMax() const noexcept
×
953
{
954
  return domain().get().get_max();
×
955
}
956

957
void MultiSliderXY::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
958
{
959
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
960
  port.type = ossia::val_type::LIST;
×
961
  port.domain = domain().get();
×
962
}
×
963

964
PathGeneratorXY::PathGeneratorXY(
1✔
965
    ossia::value init, const QString& name, Id<Port> id, QObject* parent)
966
    : ControlInlet{name, id, parent}
1✔
967
{
1✔
968
  displayHandledExplicitly = true;
1✔
969
  setValue(std::move(init));
1✔
970
  setInit(value());
1✔
971
  setDomain(ossia::make_domain(0., 1.));
1✔
972
}
1✔
973

974
PathGeneratorXY::~PathGeneratorXY() { }
6✔
975

976
ossia::value PathGeneratorXY::getMin() const noexcept
×
977
{
978
  return domain().get().get_min();
×
979
}
980

981
ossia::value PathGeneratorXY::getMax() const noexcept
×
982
{
983
  return domain().get().get_max();
×
984
}
985

986
void PathGeneratorXY::setupExecution(ossia::inlet& inl, QObject* exec_context) const noexcept
×
987
{
988
  auto& port = **safe_cast<ossia::value_inlet*>(&inl);
×
989
  port.type = ossia::val_type::LIST;
×
990
  port.domain = domain().get();
×
991
}
×
992

993
Bargraph::Bargraph(
2✔
994
    float min, float max, float init, const QString& name, Id<Port> id, QObject* parent)
995
    : ControlOutlet{name, id, parent}
2✔
996
{
2✔
997
  displayHandledExplicitly = true;
2✔
998
  setValue(init);
2✔
999
  setDomain(ossia::make_domain(min, max));
2✔
1000
}
2✔
1001

1002
Bargraph::~Bargraph() { }
12✔
1003

1004
}
1005
template <>
1006
SCORE_LIB_PROCESS_EXPORT void
1007
DataStreamReader::read(const Process::FloatSlider& p)
752✔
1008
{
1009
  read((const Process::ControlInlet&)p);
752✔
1010
}
752✔
1011
template <>
1012
SCORE_LIB_PROCESS_EXPORT void
1013
DataStreamWriter::write(Process::FloatSlider& p)
×
1014
{
1015
}
×
1016
template <>
1017
SCORE_LIB_PROCESS_EXPORT void
1018
JSONReader::read(const Process::FloatSlider& p)
834✔
1019
{
1020
  read((const Process::ControlInlet&)p);
834✔
1021
}
834✔
1022
template <>
1023
SCORE_LIB_PROCESS_EXPORT void
1024
JSONWriter::write(Process::FloatSlider& p)
×
1025
{
1026
}
×
1027

1028
template <>
1029
SCORE_LIB_PROCESS_EXPORT void
1030
DataStreamReader::read(const Process::FloatKnob& p)
1,050✔
1031
{
1032
  read((const Process::ControlInlet&)p);
1,050✔
1033
}
1,050✔
1034
template <>
1035
SCORE_LIB_PROCESS_EXPORT void
1036
DataStreamWriter::write(Process::FloatKnob& p)
×
1037
{
1038
}
×
1039
template <>
1040
SCORE_LIB_PROCESS_EXPORT void
1041
JSONReader::read(const Process::FloatKnob& p)
1,034✔
1042
{
1043
  read((const Process::ControlInlet&)p);
1,034✔
1044
}
1,034✔
1045
template <>
1046
SCORE_LIB_PROCESS_EXPORT void
1047
JSONWriter::write(Process::FloatKnob& p)
×
1048
{
1049
}
×
1050

1051
template <>
1052
SCORE_LIB_PROCESS_EXPORT void
1053
DataStreamReader::read(const Process::LogFloatSlider& p)
58✔
1054
{
1055
  read((const Process::ControlInlet&)p);
58✔
1056
}
58✔
1057
template <>
1058
SCORE_LIB_PROCESS_EXPORT void
1059
DataStreamWriter::write(Process::LogFloatSlider& p)
×
1060
{
1061
}
×
1062
template <>
1063
SCORE_LIB_PROCESS_EXPORT void
1064
JSONReader::read(const Process::LogFloatSlider& p)
58✔
1065
{
1066
  read((const Process::ControlInlet&)p);
58✔
1067
}
58✔
1068
template <>
1069
SCORE_LIB_PROCESS_EXPORT void
1070
JSONWriter::write(Process::LogFloatSlider& p)
×
1071
{
1072
}
×
1073

1074
template <>
1075
SCORE_LIB_PROCESS_EXPORT void
1076
DataStreamReader::read(const Process::IntSlider& p)
179✔
1077
{
1078
  read((const Process::ControlInlet&)p);
179✔
1079
}
179✔
1080
template <>
1081
SCORE_LIB_PROCESS_EXPORT void
1082
DataStreamWriter::write(Process::IntSlider& p)
×
1083
{
1084
}
×
1085
template <>
1086
SCORE_LIB_PROCESS_EXPORT void
1087
JSONReader::read(const Process::IntSlider& p)
194✔
1088
{
1089
  read((const Process::ControlInlet&)p);
194✔
1090
}
194✔
1091
template <>
1092
SCORE_LIB_PROCESS_EXPORT void
1093
JSONWriter::write(Process::IntSlider& p)
×
1094
{
1095
}
×
1096

1097
template <>
1098
SCORE_LIB_PROCESS_EXPORT void
1099
DataStreamReader::read(const Process::IntRangeSlider& p)
×
1100
{
1101
  read((const Process::ControlInlet&)p);
×
1102
}
×
1103
template <>
1104
SCORE_LIB_PROCESS_EXPORT void
1105
DataStreamWriter::write(Process::IntRangeSlider& p)
×
1106
{
1107
}
×
1108
template <>
1109
SCORE_LIB_PROCESS_EXPORT void
1110
JSONReader::read(const Process::IntRangeSlider& p)
×
1111
{
1112
  read((const Process::ControlInlet&)p);
×
1113
}
×
1114
template <>
1115
SCORE_LIB_PROCESS_EXPORT void
1116
JSONWriter::write(Process::IntRangeSlider& p)
×
1117
{
1118
}
×
1119
template <>
1120
SCORE_LIB_PROCESS_EXPORT void
1121
DataStreamReader::read(const Process::FloatRangeSlider& p)
12✔
1122
{
1123
  read((const Process::ControlInlet&)p);
12✔
1124
}
12✔
1125
template <>
1126
SCORE_LIB_PROCESS_EXPORT void
1127
DataStreamWriter::write(Process::FloatRangeSlider& p)
×
1128
{
1129
}
×
1130
template <>
1131
SCORE_LIB_PROCESS_EXPORT void
1132
JSONReader::read(const Process::FloatRangeSlider& p)
12✔
1133
{
1134
  read((const Process::ControlInlet&)p);
12✔
1135
}
12✔
1136
template <>
1137
SCORE_LIB_PROCESS_EXPORT void
1138
JSONWriter::write(Process::FloatRangeSlider& p)
×
1139
{
1140
}
×
1141

1142
template <>
1143
SCORE_LIB_PROCESS_EXPORT void
1144
DataStreamReader::read(const Process::IntRangeSpinBox& p)
×
1145
{
1146
  read((const Process::ControlInlet&)p);
×
1147
}
×
1148
template <>
1149
SCORE_LIB_PROCESS_EXPORT void
1150
DataStreamWriter::write(Process::IntRangeSpinBox& p)
×
1151
{
1152
}
×
1153
template <>
1154
SCORE_LIB_PROCESS_EXPORT void
1155
JSONReader::read(const Process::IntRangeSpinBox& p)
×
1156
{
1157
  read((const Process::ControlInlet&)p);
×
1158
}
×
1159
template <>
1160
SCORE_LIB_PROCESS_EXPORT void
1161
JSONWriter::write(Process::IntRangeSpinBox& p)
×
1162
{
1163
}
×
1164
template <>
1165
SCORE_LIB_PROCESS_EXPORT void
1166
DataStreamReader::read(const Process::FloatRangeSpinBox& p)
×
1167
{
1168
  read((const Process::ControlInlet&)p);
×
1169
}
×
1170
template <>
1171
SCORE_LIB_PROCESS_EXPORT void
1172
DataStreamWriter::write(Process::FloatRangeSpinBox& p)
×
1173
{
1174
}
×
1175
template <>
1176
SCORE_LIB_PROCESS_EXPORT void
1177
JSONReader::read(const Process::FloatRangeSpinBox& p)
×
1178
{
1179
  read((const Process::ControlInlet&)p);
×
1180
}
×
1181
template <>
1182
SCORE_LIB_PROCESS_EXPORT void
1183
JSONWriter::write(Process::FloatRangeSpinBox& p)
×
1184
{
1185
}
×
1186

1187
template <>
1188
SCORE_LIB_PROCESS_EXPORT void
1189
DataStreamReader::read(const Process::IntSpinBox& p)
541✔
1190
{
1191
  read((const Process::ControlInlet&)p);
541✔
1192
}
541✔
1193
template <>
1194
SCORE_LIB_PROCESS_EXPORT void
1195
DataStreamWriter::write(Process::IntSpinBox& p)
×
1196
{
1197
}
×
1198
template <>
1199
SCORE_LIB_PROCESS_EXPORT void
1200
JSONReader::read(const Process::IntSpinBox& p)
535✔
1201
{
1202
  read((const Process::ControlInlet&)p);
535✔
1203
}
535✔
1204
template <>
1205
SCORE_LIB_PROCESS_EXPORT void
1206
JSONWriter::write(Process::IntSpinBox& p)
×
1207
{
1208
}
×
1209

1210
template <>
1211
SCORE_LIB_PROCESS_EXPORT void
1212
DataStreamReader::read(const Process::FloatSpinBox& p)
166✔
1213
{
1214
  read((const Process::ControlInlet&)p);
166✔
1215
}
166✔
1216
template <>
1217
SCORE_LIB_PROCESS_EXPORT void
1218
DataStreamWriter::write(Process::FloatSpinBox& p)
×
1219
{
1220
}
×
1221
template <>
1222
SCORE_LIB_PROCESS_EXPORT void
1223
JSONReader::read(const Process::FloatSpinBox& p)
166✔
1224
{
1225
  read((const Process::ControlInlet&)p);
166✔
1226
}
166✔
1227
template <>
1228
SCORE_LIB_PROCESS_EXPORT void
1229
JSONWriter::write(Process::FloatSpinBox& p)
×
1230
{
1231
}
×
1232

1233
template <>
1234
SCORE_LIB_PROCESS_EXPORT void
1235
DataStreamReader::read(const Process::TimeChooser& p)
73✔
1236
{
1237
  read((const Process::ControlInlet&)p);
73✔
1238
}
73✔
1239
template <>
1240
SCORE_LIB_PROCESS_EXPORT void
1241
DataStreamWriter::write(Process::TimeChooser& p)
×
1242
{
1243
}
×
1244
template <>
1245
SCORE_LIB_PROCESS_EXPORT void
1246
JSONReader::read(const Process::TimeChooser& p)
109✔
1247
{
1248
  read((const Process::ControlInlet&)p);
109✔
1249
}
109✔
1250
template <>
1251
SCORE_LIB_PROCESS_EXPORT void
1252
JSONWriter::write(Process::TimeChooser& p)
×
1253
{
1254
}
×
1255

1256
template <>
1257
SCORE_LIB_PROCESS_EXPORT void
1258
DataStreamReader::read(const Process::Toggle& p)
433✔
1259
{
1260
  read((const Process::ControlInlet&)p);
433✔
1261
}
433✔
1262
template <>
1263
SCORE_LIB_PROCESS_EXPORT void
1264
DataStreamWriter::write(Process::Toggle& p)
×
1265
{
1266
}
×
1267
template <>
1268
SCORE_LIB_PROCESS_EXPORT void JSONReader::read(const Process::Toggle& p)
442✔
1269
{
1270
  read((const Process::ControlInlet&)p);
442✔
1271
}
442✔
1272
template <>
1273
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::Toggle& p)
×
1274
{
1275
}
×
1276

1277
template <>
1278
SCORE_LIB_PROCESS_EXPORT void
1279
DataStreamReader::read(const Process::ChooserToggle& p)
×
1280
{
1281
  read((const Process::ControlInlet&)p);
×
1282
}
×
1283
template <>
1284
SCORE_LIB_PROCESS_EXPORT void
1285
DataStreamWriter::write(Process::ChooserToggle& p)
×
1286
{
1287
}
×
1288
template <>
1289
SCORE_LIB_PROCESS_EXPORT void
1290
JSONReader::read(const Process::ChooserToggle& p)
×
1291
{
1292
  read((const Process::ControlInlet&)p);
×
1293
}
×
1294
template <>
1295
SCORE_LIB_PROCESS_EXPORT void
1296
JSONWriter::write(Process::ChooserToggle& p)
×
1297
{
1298
}
×
1299

1300
template <>
1301
SCORE_LIB_PROCESS_EXPORT void
1302
DataStreamReader::read(const Process::LineEdit& p)
152✔
1303
{
1304
  read((const Process::ControlInlet&)p);
152✔
1305
}
152✔
1306
template <>
1307
SCORE_LIB_PROCESS_EXPORT void
1308
DataStreamWriter::write(Process::LineEdit& p)
×
1309
{
1310
}
×
1311
template <>
1312
SCORE_LIB_PROCESS_EXPORT void
1313
JSONReader::read(const Process::LineEdit& p)
148✔
1314
{
1315
  read((const Process::ControlInlet&)p);
148✔
1316
}
148✔
1317
template <>
1318
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::LineEdit& p)
×
1319
{
1320
}
×
1321

1322
template <>
1323
SCORE_LIB_PROCESS_EXPORT void
1324
DataStreamReader::read(const Process::ProgramEdit& p)
8✔
1325
{
1326
  read((const Process::ControlInlet&)p);
8✔
1327
}
8✔
1328
template <>
1329
SCORE_LIB_PROCESS_EXPORT void
1330
DataStreamWriter::write(Process::ProgramEdit& p)
×
1331
{
1332
}
×
1333
template <>
1334
SCORE_LIB_PROCESS_EXPORT void
1335
JSONReader::read(const Process::ProgramEdit& p)
8✔
1336
{
1337
  read((const Process::ControlInlet&)p);
8✔
1338
}
8✔
1339
template <>
1340
SCORE_LIB_PROCESS_EXPORT void
1341
JSONWriter::write(Process::ProgramEdit& p)
×
1342
{
1343
}
×
1344

1345
template <>
1346
SCORE_LIB_PROCESS_EXPORT void
1347
DataStreamReader::read(const Process::FileChooser& p)
100✔
1348
{
1349
  read((const Process::ControlInlet&)p);
100✔
1350
  m_stream << p.filters();
100✔
1351
}
100✔
1352
template <>
1353
SCORE_LIB_PROCESS_EXPORT void
1354
DataStreamWriter::write(Process::FileChooser& p)
51✔
1355
{
1356
  QString f;
51✔
1357
  m_stream >> f;
51✔
1358
  p.setFilters(f);
51✔
1359
}
51✔
1360
template <>
1361
SCORE_LIB_PROCESS_EXPORT void
1362
JSONReader::read(const Process::FileChooser& p)
104✔
1363
{
1364
  read((const Process::ControlInlet&)p);
104✔
1365
  obj["Filters"] = p.filters();
104✔
1366
}
104✔
1367
template <>
1368
SCORE_LIB_PROCESS_EXPORT void
1369
JSONWriter::write(Process::FileChooser& p)
54✔
1370
{
1371
  // tryGet: these three writers are reachable through the deserializing
1372
  // constructors, and documents older than the "Filters" key exist.
1373
  if(auto it = obj.tryGet("Filters"))
54✔
1374
  {
1375
    QString f;
54✔
1376
    f <<= *it;
54✔
1377
    p.setFilters(f);
54✔
1378
  }
54✔
1379
}
54✔
1380

1381
template <>
1382
SCORE_LIB_PROCESS_EXPORT void
1383
DataStreamReader::read(const Process::FolderChooser& p)
2✔
1384
{
1385
  read((const Process::ControlInlet&)p);
2✔
1386
}
2✔
1387
template <>
1388
SCORE_LIB_PROCESS_EXPORT void
1389
DataStreamWriter::write(Process::FolderChooser& p)
×
1390
{
1391
}
×
1392
template <>
1393
SCORE_LIB_PROCESS_EXPORT void
1394
JSONReader::read(const Process::FolderChooser& p)
2✔
1395
{
1396
  read((const Process::ControlInlet&)p);
2✔
1397
}
2✔
1398
template <>
1399
SCORE_LIB_PROCESS_EXPORT void
1400
JSONWriter::write(Process::FolderChooser& p)
×
1401
{
1402
}
×
1403

1404
template <>
1405
SCORE_LIB_PROCESS_EXPORT void
1406
DataStreamReader::read(const Process::AudioFileChooser& p)
3✔
1407
{
1408
  read((const Process::ControlInlet&)p);
3✔
1409
  m_stream << p.filters();
3✔
1410
}
3✔
1411
template <>
1412
SCORE_LIB_PROCESS_EXPORT void
1413
DataStreamWriter::write(Process::AudioFileChooser& p)
2✔
1414
{
1415
  QString f;
2✔
1416
  m_stream >> f;
2✔
1417
  p.setFilters(f);
2✔
1418
}
2✔
1419
template <>
1420
SCORE_LIB_PROCESS_EXPORT void
1421
JSONReader::read(const Process::AudioFileChooser& p)
3✔
1422
{
1423
  read((const Process::ControlInlet&)p);
3✔
1424
  obj["Filters"] = p.filters();
3✔
1425
}
3✔
1426
template <>
1427
SCORE_LIB_PROCESS_EXPORT void
1428
JSONWriter::write(Process::AudioFileChooser& p)
2✔
1429
{
1430
  if(auto it = obj.tryGet("Filters"))
2✔
1431
  {
1432
    QString f;
2✔
1433
    f <<= *it;
2✔
1434
    p.setFilters(f);
2✔
1435
  }
2✔
1436
}
2✔
1437

1438
template <>
1439
SCORE_LIB_PROCESS_EXPORT void DataStreamReader::read(const Process::VideoFileChooser& p)
×
1440
{
1441
  read((const Process::ControlInlet&)p);
×
1442
  m_stream << p.filters();
×
1443
}
×
1444
template <>
1445
SCORE_LIB_PROCESS_EXPORT void DataStreamWriter::write(Process::VideoFileChooser& p)
×
1446
{
1447
  QString f;
×
1448
  m_stream >> f;
×
1449
  p.setFilters(f);
×
1450
}
×
1451
template <>
1452
SCORE_LIB_PROCESS_EXPORT void JSONReader::read(const Process::VideoFileChooser& p)
×
1453
{
1454
  read((const Process::ControlInlet&)p);
×
1455
  obj["Filters"] = p.filters();
×
1456
}
×
1457
template <>
1458
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::VideoFileChooser& p)
×
1459
{
1460
  if(auto it = obj.tryGet("Filters"))
×
1461
  {
1462
    QString f;
×
1463
    f <<= *it;
×
1464
    p.setFilters(f);
×
1465
  }
×
1466
}
×
1467

1468
template <>
1469
SCORE_LIB_PROCESS_EXPORT void
1470
DataStreamReader::read(const Process::Enum& p)
252✔
1471
{
1472
  read((const Process::ControlInlet&)p);
252✔
1473
  m_stream << p.values << p.pixmaps;
252✔
1474
}
252✔
1475
template <>
1476
SCORE_LIB_PROCESS_EXPORT void DataStreamWriter::write(Process::Enum& p)
125✔
1477
{
1478
  m_stream >> p.values >> p.pixmaps;
125✔
1479
}
125✔
1480
template <>
1481
SCORE_LIB_PROCESS_EXPORT void JSONReader::read(const Process::Enum& p)
248✔
1482
{
1483
  read((const Process::ControlInlet&)p);
248✔
1484
  obj["Values"] = p.values;
248✔
1485
  obj["Pixmaps"] = p.pixmaps;
248✔
1486
}
248✔
1487
template <>
1488
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::Enum& p)
125✔
1489
{
1490
  p.values <<= obj["Values"];
125✔
1491
  p.pixmaps <<= obj["Pixmaps"];
125✔
1492
}
125✔
1493

1494
template <>
1495
SCORE_LIB_PROCESS_EXPORT void
1496
DataStreamReader::read(const Process::ComboBox& p)
348✔
1497
{
1498
  read((const Process::ControlInlet&)p);
348✔
1499
  m_stream << p.alternatives << p.folderPortName << p.fileExtensions;
348✔
1500
}
348✔
1501
template <>
1502
SCORE_LIB_PROCESS_EXPORT void
1503
DataStreamWriter::write(Process::ComboBox& p)
176✔
1504
{
1505
  m_stream >> p.alternatives >> p.folderPortName >> p.fileExtensions;
176✔
1506
}
176✔
1507
template <>
1508
SCORE_LIB_PROCESS_EXPORT void
1509
JSONReader::read(const Process::ComboBox& p)
375✔
1510
{
1511
  read((const Process::ControlInlet&)p);
375✔
1512
  obj["Values"] = p.alternatives;
375✔
1513
  // Folder-backed combobox metadata (empty for a plain combobox). Persisted so
1514
  // a loaded document can re-scan the folder and re-establish live refresh;
1515
  // see ProcessModel::init_folder_comboboxes. Extensions are stored as one
1516
  // space-joined string ("*.json *.wav"), like FileChooser's filters.
1517
  obj["FolderPort"] = p.folderPortName;
375✔
1518
  obj["FileExtensions"] = p.fileExtensions.join(QChar(' '));
375✔
1519
}
375✔
1520
template <>
1521
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::ComboBox& p)
201✔
1522
{
1523
  p.alternatives <<= obj["Values"];
201✔
1524
  // Guarded for documents saved before these fields existed.
1525
  if(obj.tryGet("FolderPort"))
201✔
1526
    p.folderPortName <<= obj["FolderPort"];
200✔
1527
  if(obj.tryGet("FileExtensions"))
201✔
1528
  {
1529
    QString exts;
200✔
1530
    exts <<= obj["FileExtensions"];
200✔
1531
    p.fileExtensions
400✔
1532
        = exts.isEmpty() ? QStringList{} : exts.split(QChar(' '), Qt::SkipEmptyParts);
200✔
1533
  }
200✔
1534
}
201✔
1535
template <>
1536
SCORE_LIB_PROCESS_EXPORT void
1537
DataStreamReader::read(const Process::Button& p)
20✔
1538
{
1539
  read((const Process::ControlInlet&)p);
20✔
1540
}
20✔
1541
template <>
1542
SCORE_LIB_PROCESS_EXPORT void
1543
DataStreamWriter::write(Process::Button& p)
×
1544
{
1545
}
×
1546
template <>
1547
SCORE_LIB_PROCESS_EXPORT void JSONReader::read(const Process::Button& p)
20✔
1548
{
1549
  read((const Process::ControlInlet&)p);
20✔
1550
}
20✔
1551
template <>
1552
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::Button& p)
×
1553
{
1554
}
×
1555
template <>
1556
SCORE_LIB_PROCESS_EXPORT void
1557
DataStreamReader::read(const Process::ImpulseButton& p)
76✔
1558
{
1559
  read((const Process::ControlInlet&)p);
76✔
1560
}
76✔
1561
template <>
1562
SCORE_LIB_PROCESS_EXPORT void
1563
DataStreamWriter::write(Process::ImpulseButton& p)
×
1564
{
1565
}
×
1566
template <>
1567
SCORE_LIB_PROCESS_EXPORT void
1568
JSONReader::read(const Process::ImpulseButton& p)
76✔
1569
{
1570
  read((const Process::ControlInlet&)p);
76✔
1571
}
76✔
1572
template <>
1573
SCORE_LIB_PROCESS_EXPORT void
1574
JSONWriter::write(Process::ImpulseButton& p)
×
1575
{
1576
}
×
1577

1578
template <>
1579
SCORE_LIB_PROCESS_EXPORT void
1580
DataStreamReader::read(const Process::HSVSlider& p)
14✔
1581
{
1582
  read((const Process::ControlInlet&)p);
14✔
1583
}
14✔
1584
template <>
1585
SCORE_LIB_PROCESS_EXPORT void
1586
DataStreamWriter::write(Process::HSVSlider& p)
×
1587
{
1588
}
×
1589
template <>
1590
SCORE_LIB_PROCESS_EXPORT void
1591
JSONReader::read(const Process::HSVSlider& p)
10✔
1592
{
1593
  read((const Process::ControlInlet&)p);
10✔
1594
}
10✔
1595
template <>
1596
SCORE_LIB_PROCESS_EXPORT void
1597
JSONWriter::write(Process::HSVSlider& p)
×
1598
{
1599
}
×
1600

1601
template <>
1602
SCORE_LIB_PROCESS_EXPORT void
1603
DataStreamReader::read(const Process::XYSlider& p)
12✔
1604
{
1605
  read((const Process::ControlInlet&)p);
12✔
1606
}
12✔
1607
template <>
1608
SCORE_LIB_PROCESS_EXPORT void
1609
DataStreamWriter::write(Process::XYSlider& p)
×
1610
{
1611
}
×
1612
template <>
1613
SCORE_LIB_PROCESS_EXPORT void
1614
JSONReader::read(const Process::XYSlider& p)
10✔
1615
{
1616
  read((const Process::ControlInlet&)p);
10✔
1617
}
10✔
1618
template <>
1619
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::XYSlider& p)
×
1620
{
1621
}
×
1622

1623
template <>
1624
SCORE_LIB_PROCESS_EXPORT void
1625
DataStreamReader::read(const Process::XYZSlider& p)
×
1626
{
1627
  read((const Process::ControlInlet&)p);
×
1628
}
×
1629
template <>
1630
SCORE_LIB_PROCESS_EXPORT void
1631
DataStreamWriter::write(Process::XYZSlider& p)
×
1632
{
1633
}
×
1634
template <>
1635
SCORE_LIB_PROCESS_EXPORT void
1636
JSONReader::read(const Process::XYZSlider& p)
×
1637
{
1638
  read((const Process::ControlInlet&)p);
×
1639
}
×
1640
template <>
1641
SCORE_LIB_PROCESS_EXPORT void
1642
JSONWriter::write(Process::XYZSlider& p)
×
1643
{
1644
}
×
1645

1646
template <>
1647
SCORE_LIB_PROCESS_EXPORT void
1648
DataStreamReader::read(const Process::XYSpinboxes& p)
92✔
1649
{
1650
  read((const Process::ControlInlet&)p);
92✔
1651
  m_stream << p.integral;
92✔
1652
}
92✔
1653
template <>
1654
SCORE_LIB_PROCESS_EXPORT void
1655
DataStreamWriter::write(Process::XYSpinboxes& p)
46✔
1656
{
1657
  m_stream >> p.integral;
46✔
1658
}
46✔
1659
template <>
1660
SCORE_LIB_PROCESS_EXPORT void
1661
JSONReader::read(const Process::XYSpinboxes& p)
92✔
1662
{
1663
  read((const Process::ControlInlet&)p);
92✔
1664
  obj["Integral"] = p.integral;
92✔
1665
}
92✔
1666
template <>
1667
SCORE_LIB_PROCESS_EXPORT void
1668
JSONWriter::write(Process::XYSpinboxes& p)
46✔
1669
{
1670
  if(auto val = obj.tryGet("Integral"))
46✔
1671
    p.integral = val->toBool();
46✔
1672
}
46✔
1673

1674
template <>
1675
SCORE_LIB_PROCESS_EXPORT void
1676
DataStreamReader::read(const Process::XYZSpinboxes& p)
190✔
1677
{
1678
  read((const Process::ControlInlet&)p);
190✔
1679
}
190✔
1680
template <>
1681
SCORE_LIB_PROCESS_EXPORT void
1682
DataStreamWriter::write(Process::XYZSpinboxes& p)
×
1683
{
1684
}
×
1685
template <>
1686
SCORE_LIB_PROCESS_EXPORT void
1687
JSONReader::read(const Process::XYZSpinboxes& p)
168✔
1688
{
1689
  read((const Process::ControlInlet&)p);
168✔
1690
}
168✔
1691
template <>
1692
SCORE_LIB_PROCESS_EXPORT void
1693
JSONWriter::write(Process::XYZSpinboxes& p)
×
1694
{
1695
}
×
1696

1697
template <>
1698
SCORE_LIB_PROCESS_EXPORT void
1699
DataStreamReader::read(const Process::MultiSlider& p)
9✔
1700
{
1701
  read((const Process::ControlInlet&)p);
9✔
1702
}
9✔
1703
template <>
1704
SCORE_LIB_PROCESS_EXPORT void
1705
DataStreamWriter::write(Process::MultiSlider& p)
×
1706
{
1707
}
×
1708
template <>
1709
SCORE_LIB_PROCESS_EXPORT void
1710
JSONReader::read(const Process::MultiSlider& p)
9✔
1711
{
1712
  read((const Process::ControlInlet&)p);
9✔
1713
}
9✔
1714
template <>
1715
SCORE_LIB_PROCESS_EXPORT void
1716
JSONWriter::write(Process::MultiSlider& p)
×
1717
{
1718
}
×
1719

1720
template <>
1721
SCORE_LIB_PROCESS_EXPORT void
1722
DataStreamReader::read(const Process::MultiSliderXY& p)
2✔
1723
{
1724
  read((const Process::ControlInlet&)p);
2✔
1725
}
2✔
1726
template <>
1727
SCORE_LIB_PROCESS_EXPORT void
1728
DataStreamWriter::write(Process::MultiSliderXY& p)
×
1729
{
1730
}
×
1731
template <>
1732
SCORE_LIB_PROCESS_EXPORT void
1733
JSONReader::read(const Process::MultiSliderXY& p)
2✔
1734
{
1735
  read((const Process::ControlInlet&)p);
2✔
1736
}
2✔
1737
template <>
1738
SCORE_LIB_PROCESS_EXPORT void
1739
JSONWriter::write(Process::MultiSliderXY& p)
×
1740
{
1741
}
×
1742

1743

1744
template <>
1745
SCORE_LIB_PROCESS_EXPORT void
1746
DataStreamReader::read(const Process::PathGeneratorXY& p)
2✔
1747
{
1748
  read((const Process::ControlInlet&)p);
2✔
1749
}
2✔
1750
template <>
1751
SCORE_LIB_PROCESS_EXPORT void
1752
DataStreamWriter::write(Process::PathGeneratorXY& p)
×
1753
{
1754
}
×
1755
template <>
1756
SCORE_LIB_PROCESS_EXPORT void
1757
JSONReader::read(const Process::PathGeneratorXY& p)
2✔
1758
{
1759
  read((const Process::ControlInlet&)p);
2✔
1760
}
2✔
1761
template <>
1762
SCORE_LIB_PROCESS_EXPORT void
1763
JSONWriter::write(Process::PathGeneratorXY& p)
×
1764
{
1765
}
×
1766

1767
template <>
1768
SCORE_LIB_PROCESS_EXPORT void
1769
DataStreamReader::read(const Process::Bargraph& p)
4✔
1770
{
1771
  read((const Process::ControlOutlet&)p);
4✔
1772
}
4✔
1773
template <>
1774
SCORE_LIB_PROCESS_EXPORT void
1775
DataStreamWriter::write(Process::Bargraph& p)
×
1776
{
1777
}
×
1778
template <>
1779
SCORE_LIB_PROCESS_EXPORT void
1780
JSONReader::read(const Process::Bargraph& p)
4✔
1781
{
1782
  read((const Process::ControlOutlet&)p);
4✔
1783
}
4✔
1784
template <>
1785
SCORE_LIB_PROCESS_EXPORT void JSONWriter::write(Process::Bargraph& p)
×
1786
{
1787
}
×
1788

1789
template <>
1790
SCORE_LIB_PROCESS_EXPORT void DataStreamReader::read(const QString& p)
1,052✔
1791
{
1792
  m_stream << p;
1,052✔
1793
}
1,052✔
1794
template <>
1795
SCORE_LIB_PROCESS_EXPORT void DataStreamWriter::write(QString& p)
494✔
1796
{
1797
  m_stream >> p;
494✔
1798
}
494✔
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