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

ossia / score / 35899133125

23 Sep 2026 05:57PM UTC coverage: 41.488% (+1.2%) from 40.337%
35899133125

push

github

jcelerier
3rdparty: follow the merged libossia

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

123236 of 297041 relevant lines covered (41.49%)

113626.05 hits per line

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

92.31
/src/plugins/score-plugin-js/JS/JSProcessModel.hpp
1
#pragma once
2
#include <Process/Process.hpp>
3
#include <Process/Script/ScriptProcess.hpp>
4

5
#include <JS/JSProcessMetadata.hpp>
6
#include <JS/Qml/QmlObjects.hpp>
7
#include <score/serialization/MapSerialization.hpp>
8
#include <QQmlComponent>
9

10
#include <score_plugin_js_export.h>
11

12
#include <memory>
13
#include <verdigris>
14
class QQuickItem;
15

16
namespace JS
17
{
18
class Script;
19
class ProcessModel;
20

21
struct QmlSource {
22
  QmlSource() = default;
142✔
23
  ~QmlSource() = default;
388✔
24
  QmlSource(const QmlSource&) = default;
120✔
25
  QmlSource(QmlSource&&) = default;
8✔
26

27
  QmlSource(const QString& execution, const QString& ui)
112✔
28
      : execution{execution}
112✔
29
      , ui{ui}
112✔
30
  {
31
  }
112✔
32

33
  QmlSource(const std::vector<QString>& vec)
6✔
34
  {
35
    SCORE_ASSERT(vec.size() == 2);
6✔
36
    execution = vec[0];
6✔
37
    ui = vec[1];
6✔
38
  }
6✔
39

40
  QmlSource& operator=(const QmlSource&) = default;
99✔
41
  QmlSource& operator=(QmlSource&&) = default;
2✔
42

43
  QString execution;
44
  QString ui;
45

46
  struct MemberSpec
47
  {
48
    const QString name;
49
    const QString QmlSource::*pointer;
50
    const std::string_view language{};
51
  };
52

53
  static const inline std::array<MemberSpec, 2> specification{
54
                                                              MemberSpec{QObject::tr("Execution"), &QmlSource::execution, "QML"},
55
                                                              MemberSpec{QObject::tr("GUI"), &QmlSource::ui, "QML"},
56
  };
57

58
  friend bool operator==(const QmlSource& lhs, const QmlSource& rhs) {
31✔
59
    return lhs.execution == rhs.execution && lhs.ui == rhs.ui;
31✔
60
  }
61
  friend bool operator!=(const QmlSource& lhs, const QmlSource& rhs) {
31✔
62
    return !(lhs == rhs);
31✔
63
  }
64
  friend bool operator!=(const QmlSource& lhs, const std::vector<QString>& rhs) {
65
    return rhs.size() != 2 || lhs.execution != rhs[0]|| lhs.ui != rhs[1];
66
  }
67
  friend bool operator!=(const std::vector<QString>& rhs, const QmlSource& lhs) {
6✔
68
    return rhs.size() != 2 || lhs.execution != rhs[0]|| lhs.ui != rhs[1];
6✔
69
  }
70
};
71

72

73
struct ComponentCache
74
{
75
  struct Cache
76
  {
77
    QByteArray key;
78
    std::unique_ptr<QQmlComponent> component{};
79
    std::unique_ptr<JS::Script> object{};
80
  };
81

82
  JS::Script*
83
  getExecution(const JS::ProcessModel& process, const QByteArray& str, bool isFile) noexcept;
84
  QQmlComponent*
85
  getUi(const JS::ProcessModel& process, const QByteArray& str, bool isFile) noexcept;
86
  const Cache* tryGet(const QByteArray& str, bool isFile) const noexcept;
87

88
  //! What identifies a compiled script: the text it came from, read out of the
89
  //! file when `str` names one. Empty if that file cannot be read.
90
  static QByteArray key(const QByteArray& str, bool isFile) noexcept;
91

92
  ComponentCache();
93
  ~ComponentCache();
94

95
private:
96
  std::vector<Cache> m_map;
97

98
};
99

100
class SCORE_PLUGIN_JS_EXPORT ProcessModel final : public Process::ProcessModel
101
{
102
  SCORE_SERIALIZE_FRIENDS
103
  PROCESS_METADATA_IMPL_NOFLAGS(JS::ProcessModel)
1,752✔
104
  W_OBJECT(ProcessModel)
105
public:
106
  bool hasExternalUI() const noexcept { return bool(m_ui_component); }
184✔
107

108
  explicit ProcessModel(
109
      const TimeVal& duration, const QString& data, const Id<Process::ProcessModel>& id,
110
      QObject* parent);
111

112
  template <typename Impl>
113
  explicit ProcessModel(Impl& vis, QObject* parent)
30✔
114
      : Process::ProcessModel{vis, parent}
10✔
115
  {
10✔
116
    vis.writeTo(*this);
10✔
117
  }
10✔
118
  Process::ProcessFlags flags() const noexcept override;
119
  void setExecutionScript(const QString& script);
120
  const QString& executionScript() const noexcept { return m_program.execution; }
12✔
121
  void executionScriptOk() W_SIGNAL(executionScriptOk);
93✔
122
  void executionScriptChanged(const QString& arg_1) W_SIGNAL(executionScriptChanged, arg_1);
83✔
123
  const QByteArray& qmlData() const noexcept { return m_qmlData; }
2✔
124

125
  void setUiScript(const QString& script);
126
  const QString& uiScript() const noexcept { return m_program.ui; }
3✔
127
  void uiScriptOk() W_SIGNAL(uiScriptOk);
11✔
128
  void uiScriptChanged(const QString& arg_1) W_SIGNAL(uiScriptChanged, arg_1);
30✔
129

130
  void setState(const JS::JSState& s);
131
  void updateState(const QString& k, const ossia::value& v);
132
  const JS::JSState& state() const noexcept { return m_state; }
10✔
133
  void stateChanged() W_SIGNAL(stateChanged);
×
134
  void stateElementChanged(const QString& k, const ossia::value& v) W_SIGNAL(stateElementChanged, k, v);
×
135

136
  JS::Script* currentExecutionObject() const noexcept;
137
  QQuickItem* currentUI() const noexcept;
138
  bool isGpu() const noexcept;
139
  bool hasUi() const noexcept;
140
  QWidget* createWindowForUI(const score::DocumentContext& ctx,
141
                             QWidget* parent) const noexcept;
142
  QQuickItem* createItemForUI(const score::DocumentContext& ctx) const noexcept;
143

144
  ~ProcessModel() override;
145

146
  QString rootPath() const noexcept;
147

148
  //! Path of the .qml this script was taken from; empty if it was written here.
149
  const QString& rootFile() const noexcept { return m_root; }
10✔
150

151
  //! True while the program is still exactly what rootFile() holds. The
152
  //! document then saves the path alone, so that a later version of that file
153
  //! -- a library update -- is what the user gets when reopening.
154
  bool followsRootFile() const noexcept { return !m_root.isEmpty() && !m_modified; }
30✔
155

156
  bool externalSourceOutOfDate() const noexcept override { return m_outOfDate; }
6✔
157
  score::Command*
158
  refreshFromExternalSource(const score::DocumentContext& ctx) const override;
159

160
  //! The sources a .qml holds, together with those of its .ui.qml sibling.
161
  //! Members the disk has nothing for come back empty.
162
  static QmlSource readProgramFromFile(const QString& qmlPath) noexcept;
163

164
  //! "foo.qml" -> "foo.ui.qml". Empty if the name is not a .qml at all.
165
  static QString uiPathFor(const QString& qmlPath) noexcept;
166
  bool validate(const std::vector<QString>& str) const noexcept;
167
  void errorMessage(const QString& arg_2) const
29✔
168
      W_SIGNAL(errorMessage, arg_2);
29✔
169

170
  const QmlSource& program() const noexcept { return m_program; }
113✔
171
  [[nodiscard]] Process::ScriptChangeResult setProgram(const QmlSource& f);
172
  void programChanged() W_SIGNAL(programChanged);
23✔
173

174
  void mapExternalFiles(Process::ExternalFileMap& map) override;
175

176
  void uiToExecution(const QVariant& v) W_SIGNAL(uiToExecution, v);
×
177
  void executionToUi(const QVariant& v) W_SIGNAL(executionToUi, v);
×
178

179
  PROPERTY(QString, executionScript READ executionScript WRITE setExecutionScript NOTIFY executionScriptChanged)
180
  PROPERTY(QString, uiScript READ uiScript WRITE setUiScript NOTIFY uiScriptChanged)
181
  PROPERTY(JS::QmlSource, program READ program WRITE setProgram NOTIFY programChanged)
182
  PROPERTY(JS::JSState, state READ state WRITE setState NOTIFY stateChanged)
183
private:
184
  QString effect() const noexcept override;
185
  void loadPreset(const Process::Preset& preset) override;
186
  Process::Preset savePreset() const noexcept override;
187
  Process::ScriptChangeResult setQmlData(const QByteArray&, bool isFile);
188

189
  QString m_root;
190
  QmlSource m_program;
191
  //! Recomputed whenever the program changes: see followsRootFile() and
192
  //! externalSourceOutOfDate().
193
  void updateFileLink() noexcept;
194

195
  QByteArray m_qmlData;
196

197
  QQmlComponent* m_ui_component{};
10✔
198
  mutable QPointer<QQuickItem> m_ui_object{};
10✔
199

200
  mutable ComponentCache m_cache;
201
  JS::JSState m_state;
202
  bool m_isFile{};
10✔
203
  bool m_modified{true};
10✔
204
  bool m_outOfDate{};
10✔
205
};
206
}
207

208
W_REGISTER_ARGTYPE(JS::JSState)
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