diff -crBw Qt/6.8.3/Src/qtscxml/src/plugins/ecmascriptdatamodel/qscxmlecmascriptdatamodel.cpp qtscxml/qtscxml/src/plugins/ecmascriptdatamodel/qscxmlecmascriptdatamodel.cpp *** Qt/6.8.3/Src/qtscxml/src/plugins/ecmascriptdatamodel/qscxmlecmascriptdatamodel.cpp 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/plugins/ecmascriptdatamodel/qscxmlecmascriptdatamodel.cpp 2025-04-18 20:47:36.000000000 +0200 *************** *** 176,181 **** --- 176,182 ---- if (!jsEngine) { Q_Q(QScxmlEcmaScriptDataModel); setEngine(new QJSEngine(q->stateMachine())); + engine()->installExtensions( QJSEngine::ConsoleExtension ); } return jsEngine; *************** *** 492,498 **** const QString &context) { Q_D(QScxmlEcmaScriptDataModel); ! Q_ASSERT(hasScxmlProperty(name)); QJSEngine *engine = d->assertEngine(); QJSValue v = engine->toScriptValue( --- 493,502 ---- const QString &context) { Q_D(QScxmlEcmaScriptDataModel); ! if( ! hasScxmlProperty(name) ) { ! d->submitError(QStringLiteral("error.execution"), QStringLiteral("Missing property '%1' in %2").arg(name, context)); ! return false; ! } QJSEngine *engine = d->assertEngine(); QJSValue v = engine->toScriptValue( diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlcompiler.cpp qtscxml/qtscxml/src/scxml/qscxmlcompiler.cpp *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlcompiler.cpp 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlcompiler.cpp 2025-04-01 17:48:26.000000000 +0200 *************** *** 40,46 **** class ScxmlVerifier: public DocumentModel::NodeVisitor { public: ! ScxmlVerifier(std::function errorHandler) : m_errorHandler(errorHandler) , m_doc(nullptr) , m_hasErrors(false) --- 40,46 ---- class ScxmlVerifier: public DocumentModel::NodeVisitor { public: ! ScxmlVerifier(std::function errorHandler) : m_errorHandler(errorHandler) , m_doc(nullptr) , m_hasErrors(false) *************** *** 418,428 **** { m_hasErrors = true; if (m_errorHandler) ! m_errorHandler(location, message); } private: ! std::function m_errorHandler; DocumentModel::ScxmlDocument *m_doc; bool m_hasErrors; QHash m_stateById; --- 418,428 ---- { m_hasErrors = true; if (m_errorHandler) ! m_errorHandler(m_doc->fileName, location, message); } private: ! std::function m_errorHandler; DocumentModel::ScxmlDocument *m_doc; bool m_hasErrors; QHash m_stateById; *************** *** 1317,1324 **** if (!m_doc) return false; ! auto handler = [this](const DocumentModel::XmlLocation &location, const QString &msg) { ! this->addError(location, msg); }; if (ScxmlVerifier(handler).verify(m_doc.get())) --- 1317,1324 ---- if (!m_doc) return false; ! auto handler = [this](const QString& fileName, const DocumentModel::XmlLocation &location, const QString &msg) { ! this->addError(fileName, location, msg); }; if (ScxmlVerifier(handler).verify(m_doc.get())) *************** *** 2049,2055 **** } } } else { ! addError(scriptI->xmlLocation, QStringLiteral("neither src nor any content has been given in the script tag")); } return flushInstruction(); --- 2049,2055 ---- } } } else { ! addError(m_doc->fileName, scriptI->xmlLocation, QStringLiteral("neither src nor any content has been given in the script tag")); } return flushInstruction(); *************** *** 2328,2336 **** m_errors.append(QScxmlError(m_fileName, m_reader->lineNumber(), m_reader->columnNumber(), msg)); } ! void QScxmlCompilerPrivate::addError(const DocumentModel::XmlLocation &location, const QString &msg) { ! m_errors.append(QScxmlError(m_fileName, location.line, location.column, msg)); } DocumentModel::AbstractState *QScxmlCompilerPrivate::currentParent() const --- 2328,2336 ---- m_errors.append(QScxmlError(m_fileName, m_reader->lineNumber(), m_reader->columnNumber(), msg)); } ! void QScxmlCompilerPrivate::addError(const QString& fileName, const DocumentModel::XmlLocation &location, const QString &msg) { ! m_errors.append(QScxmlError(fileName, location.line, location.column, msg)); } DocumentModel::AbstractState *QScxmlCompilerPrivate::currentParent() const *************** *** 2349,2355 **** QString idStr = attributes.value(QLatin1String("id")).toString(); if (!idStr.isEmpty()) { if (m_allIds.contains(idStr)) { ! addError(xmlLocation(), QStringLiteral("duplicate id '%1'").arg(idStr)); } else { m_allIds.insert(idStr); *id = idStr; --- 2349,2355 ---- QString idStr = attributes.value(QLatin1String("id")).toString(); if (!idStr.isEmpty()) { if (m_allIds.contains(idStr)) { ! addError(m_doc->fileName, xmlLocation(), QStringLiteral("duplicate id '%1'").arg(idStr)); } else { m_allIds.insert(idStr); *id = idStr; diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlcompiler_p.h qtscxml/qtscxml/src/scxml/qscxmlcompiler_p.h *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlcompiler_p.h 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlcompiler_p.h 2025-04-01 17:48:56.000000000 +0200 *************** *** 544,550 **** QList errors() const; void addError(const QString &msg); ! void addError(const DocumentModel::XmlLocation &location, const QString &msg); QScxmlStateMachine *instantiateStateMachine() const; void instantiateDataModel(QScxmlStateMachine *stateMachine) const; --- 544,550 ---- QList errors() const; void addError(const QString &msg); ! void addError(const QString&, const DocumentModel::XmlLocation &location, const QString &msg); QScxmlStateMachine *instantiateStateMachine() const; void instantiateDataModel(QScxmlStateMachine *stateMachine) const; diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlexecutablecontent.cpp qtscxml/qtscxml/src/scxml/qscxmlexecutablecontent.cpp *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlexecutablecontent.cpp 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlexecutablecontent.cpp 2025-04-11 17:12:28.000000000 +0200 *************** *** 5,10 **** --- 5,11 ---- #include "qscxmlexecutablecontent_p.h" #include "qscxmlcompiler_p.h" #include "qscxmlevent_p.h" + #include "qscxmlstatemachine_p.h" QT_BEGIN_NAMESPACE *************** *** 409,415 **** qCDebug(scxmlLog) << label << ":" << str; QMetaObject::invokeMethod(stateMachine, "log", ! Qt::QueuedConnection, Q_ARG(QString, label), Q_ARG(QString, str)); return ip; --- 410,416 ---- qCDebug(scxmlLog) << label << ":" << str; QMetaObject::invokeMethod(stateMachine, "log", ! Qt::DirectConnection, Q_ARG(QString, label), Q_ARG(QString, str)); return ip; *************** *** 450,457 **** QString eventName = QStringLiteral("done.state.") + extraData.toString(); QScxmlEventBuilder event(stateMachine, eventName, doneData); auto e = event(); ! e->setEventType(QScxmlEvent::InternalEvent); ! qCDebug(qscxmlLog) << stateMachine << "submitting event" << eventName; stateMachine->submitEvent(e); return ip; } --- 451,458 ---- QString eventName = QStringLiteral("done.state.") + extraData.toString(); QScxmlEventBuilder event(stateMachine, eventName, doneData); auto e = event(); ! e->setEventType( stateMachine->isInvoked() ? QScxmlEvent::InternalEvent : QScxmlEvent::ExternalEvent); ! qCDebug(qscxmlLog) << stateMachine << "submitting event" << eventName << stateMachine->isInvoked(); stateMachine->submitEvent(e); return ip; } diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlinvokableservice.cpp qtscxml/qtscxml/src/scxml/qscxmlinvokableservice.cpp *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlinvokableservice.cpp 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlinvokableservice.cpp 2025-04-06 03:05:00.000000000 +0200 *************** *** 295,300 **** --- 295,302 ---- QScxmlInvokableServiceFactory *factory) : QScxmlInvokableService(parentStateMachine, factory), m_stateMachine(stateMachine) { + + connect( stateMachine, &QScxmlStateMachine::log, parentStateMachine, &QScxmlStateMachine::log/*, Qt::DirectConnection*/ ); QScxmlStateMachinePrivate::get(stateMachine)->m_parentStateMachine = parentStateMachine; } *************** *** 355,360 **** --- 357,367 ---- QScxmlStateMachinePrivate::get(m_stateMachine)->postEvent(event); } + void QScxmlScxmlService::routeEvent(QScxmlEvent *event ) + { + QScxmlStateMachinePrivate::get(m_stateMachine)->routeEvent(event, false ); + } + QScxmlStateMachine *QScxmlScxmlService::stateMachine() const { return m_stateMachine; diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlinvokableservice.h qtscxml/qtscxml/src/scxml/qscxmlinvokableservice.h *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlinvokableservice.h 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlinvokableservice.h 2025-03-31 15:30:16.000000000 +0200 *************** *** 32,37 **** --- 32,38 ---- virtual QString id() const = 0; virtual QString name() const = 0; virtual void postEvent(QScxmlEvent *event) = 0; + virtual void routeEvent(QScxmlEvent *event) = 0; }; class QScxmlInvokableServiceFactoryPrivate; diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlinvokableservice_p.h qtscxml/qtscxml/src/scxml/qscxmlinvokableservice_p.h *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlinvokableservice_p.h 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlinvokableservice_p.h 2025-03-31 19:01:26.000000000 +0200 *************** *** 63,68 **** --- 63,69 ---- QString id() const override; QString name() const override; void postEvent(QScxmlEvent *event) override; + void routeEvent(QScxmlEvent *event) override; QScxmlStateMachine *stateMachine() const; private: diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlstatemachine.cpp qtscxml/qtscxml/src/scxml/qscxmlstatemachine.cpp *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlstatemachine.cpp 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlstatemachine.cpp 2025-04-11 18:05:12.000000000 +0200 *************** *** 412,418 **** return m_executionEngine->execute(m_tableData.value()->initialSetup()); } ! void QScxmlStateMachinePrivate::routeEvent(QScxmlEvent *event) { Q_Q(QScxmlStateMachine); --- 412,419 ---- return m_executionEngine->execute(m_tableData.value()->initialSetup()); } ! ! void QScxmlStateMachinePrivate::routeEvent(QScxmlEvent *event, bool FirstCall ) { Q_Q(QScxmlStateMachine); *************** *** 441,448 **** --- 442,452 ---- << "to child" << service->id(); service->postEvent(new QScxmlEvent(*event)); } + service->routeEvent( event ); } + if( FirstCall ){ delete event; + } // else recursive call } else { postEvent(event); } *************** *** 452,458 **** { Q_Q(QScxmlStateMachine); ! if (!event->name().startsWith(QStringLiteral("done.invoke."))) { for (int id = 0, end = static_cast(m_invokedServices.size()); id != end; ++id) { auto service = m_invokedServices[id].service; if (service == nullptr) --- 456,462 ---- { Q_Q(QScxmlStateMachine); ! if (event->name().startsWith(QStringLiteral("done.invoke."))) { for (int id = 0, end = static_cast(m_invokedServices.size()); id != end; ++id) { auto service = m_invokedServices[id].service; if (service == nullptr) *************** *** 528,534 **** const QString &sendId) { Q_Q(QScxmlStateMachine); ! qCDebug(qscxmlLog) << q << "had error" << type << ":" << message; if (!type.startsWith(QStringLiteral("error."))) qCWarning(qscxmlLog) << q << "Message type of error message does not start with 'error.'!"; q->submitEvent(QScxmlEventBuilder::errorEvent(q, type, message, sendId)); --- 532,538 ---- const QString &sendId) { Q_Q(QScxmlStateMachine); ! qCWarning(qscxmlLog) << q << "had error" << type << ":" << message; if (!type.startsWith(QStringLiteral("error."))) qCWarning(qscxmlLog) << q << "Message type of error message does not start with 'error.'!"; q->submitEvent(QScxmlEventBuilder::errorEvent(q, type, message, sendId)); diff -crBw Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlstatemachine_p.h qtscxml/qtscxml/src/scxml/qscxmlstatemachine_p.h *** Qt/6.8.3/Src/qtscxml/src/scxml/qscxmlstatemachine_p.h 2025-03-18 19:32:55.000000000 +0100 --- qtscxml/qtscxml/src/scxml/qscxmlstatemachine_p.h 2025-03-31 19:00:26.000000000 +0200 *************** *** 233,239 **** bool executeInitialSetup(); ! void routeEvent(QScxmlEvent *event); void postEvent(QScxmlEvent *event); void submitDelayedEvent(QScxmlEvent *event); void submitError(const QString &type, const QString &msg, const QString &sendid = QString()); --- 233,239 ---- bool executeInitialSetup(); ! void routeEvent(QScxmlEvent *event, bool FirstCall = true); void postEvent(QScxmlEvent *event); void submitDelayedEvent(QScxmlEvent *event); void submitError(const QString &type, const QString &msg, const QString &sendid = QString());