Loading...
Searching...
No Matches
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>
14class QQuickItem;
15
16namespace JS
17{
18class Script;
19class ProcessModel;
20
21struct QmlSource {
22 QmlSource() = default;
23 ~QmlSource() = default;
24 QmlSource(const QmlSource&) = default;
25 QmlSource(QmlSource&&) = default;
26
27 QmlSource(const QString& execution, const QString& ui)
28 : execution{execution}
29 , ui{ui}
30 {
31 }
32
33 QmlSource(const std::vector<QString>& vec)
34 {
35 SCORE_ASSERT(vec.size() == 2);
36 execution = vec[0];
37 ui = vec[1];
38 }
39
40 QmlSource& operator=(const QmlSource&) = default;
41 QmlSource& operator=(QmlSource&&) = default;
42
43 QString execution;
44 QString ui;
45
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) {
59 return lhs.execution == rhs.execution && lhs.ui == rhs.ui;
60 }
61 friend bool operator!=(const QmlSource& lhs, const QmlSource& rhs) {
62 return !(lhs == rhs);
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) {
68 return rhs.size() != 2 || lhs.execution != rhs[0]|| lhs.ui != rhs[1];
69 }
70};
71
72
74{
75 struct Cache
76 {
77 QByteArray key;
78 std::unique_ptr<QQmlComponent> component{};
79 std::unique_ptr<JS::Script> object{};
80 };
81
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
90 static QByteArray key(const QByteArray& str, bool isFile) noexcept;
91
94
95private:
96 std::vector<Cache> m_map;
97
98};
99
100class SCORE_PLUGIN_JS_EXPORT ProcessModel final : public Process::ProcessModel
101{
102 SCORE_SERIALIZE_FRIENDS
103 PROCESS_METADATA_IMPL_NOFLAGS(JS::ProcessModel)
104 W_OBJECT(ProcessModel)
105public:
106 bool hasExternalUI() const noexcept { return bool(m_ui_component); }
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)
114 : Process::ProcessModel{vis, parent}
115 {
116 vis.writeTo(*this);
117 }
118 Process::ProcessFlags flags() const noexcept override;
119 void setExecutionScript(const QString& script);
120 const QString& executionScript() const noexcept { return m_program.execution; }
121 void executionScriptOk() W_SIGNAL(executionScriptOk);
122 void executionScriptChanged(const QString& arg_1) W_SIGNAL(executionScriptChanged, arg_1);
123 const QByteArray& qmlData() const noexcept { return m_qmlData; }
124
125 void setUiScript(const QString& script);
126 const QString& uiScript() const noexcept { return m_program.ui; }
127 void uiScriptOk() W_SIGNAL(uiScriptOk);
128 void uiScriptChanged(const QString& arg_1) W_SIGNAL(uiScriptChanged, arg_1);
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; }
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
149 const QString& rootFile() const noexcept { return m_root; }
150
154 bool followsRootFile() const noexcept { return !m_root.isEmpty() && !m_modified; }
155
156 bool externalSourceOutOfDate() const noexcept override { return m_outOfDate; }
158 refreshFromExternalSource(const score::DocumentContext& ctx) const override;
159
162 static QmlSource readProgramFromFile(const QString& qmlPath) noexcept;
163
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
168 W_SIGNAL(errorMessage, arg_2);
169
170 const QmlSource& program() const noexcept { return m_program; }
171 [[nodiscard]] Process::ScriptChangeResult setProgram(const QmlSource& f);
172 void programChanged() W_SIGNAL(programChanged);
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)
183private:
184 QString effect() const noexcept override;
185 void loadPreset(const Process::Preset& preset) override;
186 Process::Preset savePreset() const noexcept override;
187 bool presetMatches(const Process::Preset& preset) const noexcept override;
188 Process::ScriptChangeResult setQmlData(const QByteArray&, bool isFile);
189
190 QString m_root;
191 QmlSource m_program;
194 void updateFileLink() noexcept;
195
196 QByteArray m_qmlData;
197
198 QQmlComponent* m_ui_component{};
199 mutable QPointer<QQuickItem> m_ui_object{};
200
201 mutable ComponentCache m_cache;
202 JS::JSState m_state;
203 bool m_isFile{};
204 bool m_modified{true};
205 bool m_outOfDate{};
206};
207}
208
209W_REGISTER_ARGTYPE(JS::JSState)
Definition JSProcessModel.hpp:101
bool followsRootFile() const noexcept
Definition JSProcessModel.hpp:154
const QString & rootFile() const noexcept
Path of the .qml this script was taken from; empty if it was written here.
Definition JSProcessModel.hpp:149
bool externalSourceOutOfDate() const noexcept override
Definition JSProcessModel.hpp:156
Definition QmlObjects.hpp:849
The Process class.
Definition score-lib-process/Process/Process.hpp:80
The id_base_t class.
Definition Identifier.hpp:59
The Command class.
Definition Command.hpp:34
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
ProcessFlags
Various settings for processes.
Definition ProcessFlags.hpp:17
Definition JSProcessModel.hpp:76
Definition JSProcessModel.hpp:74
static QByteArray key(const QByteArray &str, bool isFile) noexcept
Definition JSProcessModel.cpp:776
Definition JSProcessModel.hpp:47
Definition JSProcessModel.hpp:21
Definition ScriptProcess.hpp:14
Definition TimeValue.hpp:21
Definition DocumentContext.hpp:18