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

ossia / score / 33560887155

01 Sep 2026 09:24PM UTC coverage: 24.648% (+0.7%) from 23.997%
33560887155

Pull #2179

github

web-flow
Merge ecc0a2ad3 into 50d28933c
Pull Request #2179: Survive a build that does not have every plug-in

408 of 757 new or added lines in 47 files covered. (53.9%)

15 existing lines in 12 files now uncovered.

55851 of 226593 relevant lines covered (24.65%)

61526.39 hits per line

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

53.76
/src/plugins/score-lib-process/Process/OpaqueProcess.cpp
1
#include "OpaqueProcess.hpp"
2

3
#include <Process/Dataflow/PortFactory.hpp>
4

5
#include <score/application/ApplicationContext.hpp>
6
#include <score/serialization/OpaquePayload.hpp>
7
#include <score/serialization/DataStreamVisitor.hpp>
8
#include <score/serialization/JSONVisitor.hpp>
9

10
#include <QIODevice>
11

12
#include <wobjectimpl.h>
13
W_OBJECT_IMPL(Process::OpaqueProcessModel)
77✔
NEW
14
W_OBJECT_IMPL(Process::OpaqueInlet)
×
NEW
15
W_OBJECT_IMPL(Process::OpaqueOutlet)
×
16

17
namespace Process
18
{
19
namespace
20
{
21
const QStringList& portMemberNames() noexcept
2✔
22
{
23
  static const QStringList names{QStringLiteral("Inlets"), QStringLiteral("Outlets")};
2✔
24
  return names;
2✔
25
}
26

27
}
28

29
const QStringList& OpaqueProcessModel::baseMemberNames() noexcept
7✔
30
{
31
  // Written by readFromAbstract, IdentifiedObject, Entity and ProcessModel. A
32
  // serialized process holds these plus whatever its plug-in added; we own the
33
  // former and must not duplicate them, and must preserve the latter.
34
  // OpaqueProcessBaseMembersTest fails if this drifts.
35
  static const QStringList names{
31✔
36
      QStringLiteral("uuid"),       QStringLiteral("ObjectName"),
2✔
37
      QStringLiteral("id"),         QStringLiteral("Metadata"),
2✔
38
      QStringLiteral("Duration"),   QStringLiteral("Height"),
2✔
39
      QStringLiteral("StartOffset"), QStringLiteral("LoopDuration"),
2✔
40
      QStringLiteral("Pos"),        QStringLiteral("Size"),
2✔
41
      QStringLiteral("Loops"),      QStringLiteral("FoldMode")};
2✔
42
  return names;
7✔
43
}
44

45
OpaqueProcessModel::OpaqueProcessModel(
2✔
46
    const UuidKey<ProcessModel>& key, DataStream::Deserializer& vis, QObject* parent)
47
    : ProcessModel{vis, parent}
1✔
48
    , m_key{key}
1✔
49
{
1✔
50
  // The base consumed everything score itself writes, so the rest of this
51
  // object's blob is the plug-in's. deserialize_interface gave each polymorphic
52
  // object its own length-delimited buffer, which is what makes this safe: the
53
  // tail is exactly one process and stops where it should.
54
  m_payload = score::OpaquePayload::fromDataStream(vis);
1✔
55

56
  // No way to find the ports inside an opaque binary blob.
57
  m_portsInPayload = true;
1✔
58
}
59

60
OpaqueProcessModel::OpaqueProcessModel(
12✔
61
    const UuidKey<ProcessModel>& key, JSONObject::Deserializer& vis, QObject* parent)
62
    : ProcessModel{vis, parent}
6✔
63
    , m_key{key}
6✔
64
{
6✔
65
  auto skip = baseMemberNames();
6✔
66

67
  // Rebuild the ports when the plug-in stored them the usual way, so that
68
  // cables to this process still resolve and its controls still hold values.
69
  const bool hasPorts = vis.base.IsObject() && vis.base.HasMember("Inlets")
12✔
70
                        && vis.base.HasMember("Outlets");
6✔
71
  if(hasPorts)
6✔
72
  {
73
    auto& pl = score::AppContext().interfaces<Process::PortFactoryList>();
2✔
74
    writePorts(vis, pl, m_inlets, m_outlets, this);
2✔
75
    m_portsInPayload = false;
2✔
76
    skip += portMemberNames();
2✔
77
  }
2✔
78

79
  m_payload = score::OpaquePayload::fromJson(vis.base, skip);
6✔
NEW
80
}
×
81

82
OpaqueProcessModel::~OpaqueProcessModel() = default;
14✔
83

84
void OpaqueProcessModel::serialize_impl(const VisitorVariant& vis) const noexcept
7✔
85
{
86
  if(vis.identifier == JSONObject::type() && !m_portsInPayload)
7✔
87
  {
88
    // Live ports rather than the ones in the payload: they may have been
89
    // edited, and the payload no longer describes them.
NEW
90
    readPorts(static_cast<JSONObject::Serializer&>(vis.visitor), m_inlets, m_outlets);
×
NEW
91
  }
×
92
  m_payload.write(vis);
7✔
93
}
7✔
94

NEW
95
QString OpaqueProcessModel::missingFactory() const noexcept
×
96
{
NEW
97
  return QString::fromUtf8(score::uuids::toByteArray(m_key.impl()));
×
98
}
99

NEW
100
QString OpaqueProcessModel::prettyShortName() const noexcept
×
101
{
NEW
102
  const auto& name = metadata().getName();
×
NEW
103
  return name.isEmpty() ? QObject::tr("Unavailable") : name;
×
104
}
105

NEW
106
QString OpaqueProcessModel::category() const noexcept
×
107
{
NEW
108
  return QObject::tr("Unavailable");
×
109
}
110

NEW
111
QStringList OpaqueProcessModel::tags() const noexcept
×
112
{
NEW
113
  return {};
×
114
}
115

116
ProcessFlags OpaqueProcessModel::flags() const noexcept
17✔
117
{
118
  // TimeIndependent is not a guess about what we are replacing so much as a
119
  // statement about ourselves: nothing here knows how to rescale a plug-in's
120
  // data, so the parent duration changing must not be taken to change it. Left
121
  // out, the interval rewrote a stand-in's duration on every resize while its
122
  // contents stayed as they were -- and the processes most often standing in
123
  // like this, VST and LV2, declare it themselves.
124
  //
125
  // SupportsTemporal so it can still be shown where it was. Not ControlSurface
126
  // or RequiresCustomData: those promise things we cannot do.
127
  return ProcessFlags::SupportsTemporal | ProcessFlags::TimeIndependent;
17✔
128
}
129
}
130

131
namespace Process
132
{
NEW
133
const QStringList& portBaseMemberNames() noexcept
×
134
{
135
  // Written by readFromAbstract, IdentifiedObject and Port. The last four are
136
  // only emitted when set, which is fine: we copy what is there.
NEW
137
  static const QStringList names{
×
NEW
138
      QStringLiteral("uuid"),     QStringLiteral("ObjectName"),
×
NEW
139
      QStringLiteral("id"),       QStringLiteral("Hidden"),
×
NEW
140
      QStringLiteral("Custom"),   QStringLiteral("Exposed"),
×
NEW
141
      QStringLiteral("Description"), QStringLiteral("Address")};
×
NEW
142
  return names;
×
143
}
144

145
namespace
146
{
147
}
148

149
OpaqueInlet::OpaqueInlet(
1✔
150
    const UuidKey<Port>& key, DataStream::Deserializer& vis, QObject* parent)
151
    : Inlet{vis, parent}
1✔
152
    , m_key{key}
1✔
153
    , m_payload{score::OpaquePayload::fromDataStream(vis)}
1✔
154
{
1✔
155
}
1✔
156

NEW
157
OpaqueInlet::OpaqueInlet(
×
158
    const UuidKey<Port>& key, JSONObject::Deserializer& vis, QObject* parent)
NEW
159
    : Inlet{vis, parent}
×
NEW
160
    , m_key{key}
×
NEW
161
    , m_payload{score::OpaquePayload::fromJson(vis.base, portBaseMemberNames())}
×
NEW
162
{
×
NEW
163
}
×
164

165
OpaqueInlet::~OpaqueInlet() = default;
2✔
166

167
void OpaqueInlet::serialize_impl(const VisitorVariant& vis) const noexcept
1✔
168
{
169
  m_payload.write(vis);
1✔
170
}
1✔
171

NEW
172
OpaqueOutlet::OpaqueOutlet(
×
173
    const UuidKey<Port>& key, DataStream::Deserializer& vis, QObject* parent)
NEW
174
    : Outlet{vis, parent}
×
NEW
175
    , m_key{key}
×
NEW
176
    , m_payload{score::OpaquePayload::fromDataStream(vis)}
×
NEW
177
{
×
NEW
178
}
×
179

NEW
180
OpaqueOutlet::OpaqueOutlet(
×
181
    const UuidKey<Port>& key, JSONObject::Deserializer& vis, QObject* parent)
NEW
182
    : Outlet{vis, parent}
×
NEW
183
    , m_key{key}
×
NEW
184
    , m_payload{score::OpaquePayload::fromJson(vis.base, portBaseMemberNames())}
×
NEW
185
{
×
NEW
186
}
×
187

NEW
188
OpaqueOutlet::~OpaqueOutlet() = default;
×
189

NEW
190
void OpaqueOutlet::serialize_impl(const VisitorVariant& vis) const noexcept
×
191
{
NEW
192
  m_payload.write(vis);
×
NEW
193
}
×
194
}
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