2#include <JS/Qml/QmlObjects.hpp>
3#include <JS/Commands/EditScript.hpp>
4#include <score/command/Dispatchers/CommandDispatcher.hpp>
5#include <score/document/DocumentInterface.hpp>
6#include <Library/LibrarySettings.hpp>
7#include <score/application/ApplicationContext.hpp>
8#include <score/application/GUIApplicationContext.hpp>
10#include <ossia/detail/logger.hpp>
11#include <ossia-qt/invoke.hpp>
12#include <ossia-qt/qml_engine_functions.hpp>
13#include <JS/ConsolePanel.hpp>
17#include <QQmlComponent>
25inline void connectStateCommit(Script* script, ProcessModel* model)
30 script, &Script::commitState, model,
31 [context = QPointer{model}](
const QString& key,
const QJSValue& value) {
32 auto converted = ossia::qt::value_from_js(value);
33 QMetaObject::invokeMethod(
34 qApp, [context, key, value = std::move(converted)] {
37 const auto& state = context->state();
38 if(
auto it = state.find(key); it != state.end() && it->second == value)
41 score::IDocument::documentContext(*context).commandStack};
42 dispatcher.submit<UpdateStateElement>(*context, key, value);
44 Qt::QueuedConnection);
46 Qt::DirectConnection);
50inline void loadJSObjectFromString(
51 const QString& rootPath,
const QByteArray& str, QQmlComponent& comp,
bool is_ui)
53 QString path = rootPath;
54 if(is_ui && path.endsWith(
".qml"))
55 path.insert(path.size() - 4,
".ui");
56 const auto url = QUrl::fromLocalFile(path);
58 if(original.open(QIODevice::ReadOnly) && original.readAll() == str)
68 comp.setData(str, url);
72inline JS::Script* createJSObject(QQmlComponent& c, QQmlContext* context)
74 const auto& errs = c.errors();
77 ossia::logger().error(
78 "Uncaught exception at line {} : {}", errs[0].line(),
79 errs[0].toString().toStdString());
84 auto object = c.create(context);
85 auto obj = qobject_cast<JS::Script*>(
object);
94 const QString& rootPath,
const QString& val, QQmlEngine* engine,
97 if(val.trimmed().startsWith(
"import"))
99 QQmlComponent c{engine};
100 loadJSObjectFromString(rootPath, val.toUtf8(), c,
false);
101 return createJSObject(c, context);
103 else if(QFile::exists(val))
105 QQmlComponent c{engine, QUrl::fromLocalFile(val)};
106 return createJSObject(c, context);
111inline void setupExecFuncs(
auto* self, QObject* context, ossia::qt::qml_engine_functions* m_execFuncs)
114 m_execFuncs, &ossia::qt::qml_engine_functions::system, qApp,
115 [](
const QString& code) {
116 std::thread{[code] { ::system(code.toStdString().c_str()); }}.detach();
117 }, Qt::QueuedConnection);
122 m_execFuncs, &ossia::qt::qml_engine_functions::exec, js_panel,
123 &JS::PanelDelegate::evaluate, Qt::QueuedConnection);
126 m_execFuncs, &ossia::qt::qml_engine_functions::compute, m_execFuncs,
127 [self, context, m_execFuncs, js_panel](
const QString& code,
const QString& cbname) {
132 , context=QPointer{context}
133 , cur = QPointer{self->m_object}
135 , cbname] (
const QVariant& v) {
140 ossia::qt::run_async(m_execFuncs, [self, context, cur, v, cbname] {
143 if(self->m_object != cur)
146 auto mo = self->m_object->metaObject();
147 for(
int i = 0; i < mo->methodCount(); i++)
149 if(mo->method(i).name() == cbname)
151 mo->method(i).invoke(
152 self->m_object, Qt::DirectConnection, QGenericReturnArgument(),
153 QArgument<QVariant>{
"v", v});
160 ossia::qt::run_async(js_panel, [js_panel, code, cb]() {
161 js_panel->compute(code, cb);
163 }, Qt::DirectConnection);
The CommandDispatcher class.
Definition CommandDispatcher.hpp:13
Definition ConsolePanel.hpp:40
Definition QmlObjects.hpp:849