summaryrefslogtreecommitdiffstats
path: root/src/qscxml.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qscxml.cpp')
-rw-r--r--src/qscxml.cpp180
1 files changed, 103 insertions, 77 deletions
diff --git a/src/qscxml.cpp b/src/qscxml.cpp
index 3896bda..68412ed 100644
--- a/src/qscxml.cpp
+++ b/src/qscxml.cpp
@@ -70,6 +70,7 @@
#include <QState>
#include <QMetaMethod>
#include <QScriptProgram>
+#include <QScriptClass>
@@ -199,6 +200,8 @@ class QScxmlPrivate
QSet<QString> knownEvents;
+ QScriptClass* scriptClass;
+
static QHash<QString,QScxml*> sessions;
};
QHash<QString,QScxml*> QScxmlPrivate::sessions;
@@ -439,19 +442,41 @@ static QScriptValue invoke(QScriptContext *context, QScriptEngine *engine)
return QScriptValue();
}
+static QScriptValue notifyChange(QScriptContext *context, QScriptEngine * engine)
+{
+ if (context->argumentCount() > 0) {
+ QScriptValue val = context->argument(0);
+ if (val.data().isObject()) {
+ QString key = val.data().property("key").toString();
+ if (key != "") {
+ notifyDataChange(engine,key,val.data().property("value"));
+ }
+ }
+ }
+ return QScriptValue();
+}
+static void notifyDataChange (QScriptEngine* engine, const QString & id, const QScriptValue & v)
+{
+ QScxml* scxml = qobject_cast<QScxml*>(engine->globalObject().property("scxml").toQObject());
+ if (scxml) {
+ scxml->dataChanged(id,v.toVariant());
+ }
+}
+
+
static QScriptValue dataAccess(QScriptContext *context, QScriptEngine * engine)
{
if (context->argumentCount() == 0) {
// getter
- return context->callee().property("value");
+ return context->callee().data().property("value");
} else if (context->argumentCount() == 1) {
// setter
QScriptValue val = context->argument(0);
- context->callee().setProperty("value",val);
- qDebug() << "data set" << val.toVariant() << context->callee().property("key").toString();
+ context->callee().data().setProperty("value",val);
+ val.setData(context->callee().data());
QScxml* scxml = qobject_cast<QScxml*>(engine->globalObject().property("scxml").toQObject());
if (scxml) {
- scxml->dataChanged(context->callee().property("key").toString(),val.toVariant());
+ scxml->dataChanged(context->callee().data().property("key").toString(),val.toVariant());
}
return val;
} else
@@ -494,9 +519,9 @@ void QScxmlPrivate::initScriptEngine(QScxml* thiz)
scxmlObj.setProperty("setTimeout",scriptEng->newFunction(QScxmlFunctions::setTimeout));
scxmlObj.setProperty("clearTimeout",scriptEng->newFunction(QScxmlFunctions::clearTimeout));
scxmlObj.setProperty("connectSignalToEvent",scriptEng->newFunction(QScxmlFunctions::connectSignalToEvent));
+ scxmlObj.setProperty("notifyChange",scriptEng->newFunction(QScxmlFunctions::notifyChange));
QScriptValue dmObj = scriptEng->newObject();
dataObj = scriptEng->newObject();
- dataObj.setProperty("_values",scriptEng->newObject());
glob.setProperty("_data",dataObj);
glob.setProperty("_global",scriptEng->globalObject());
glob.setProperty("scxml",scxmlObj);
@@ -595,9 +620,9 @@ QScxmlTransition::QScxmlTransition (QState* state,QScxml* machine)
{
}
-void QScxmlTransition::setConditionExpression(const QString & c)
+void QScxmlTransition::setConditionExpression(const QString & cond)
{
- prog = QScriptProgram(c,scxml->baseUrl().toLocalFile());
+ prog = QScriptProgram(cond,scxml->baseUrl().toLocalFile());
}
QString QScxmlTransition::conditionExpression() const
@@ -936,10 +961,7 @@ void QScxml::postNamedEvent(const QString & event)
void QScxml::setData(const QString & id, const QVariant & val)
{
- QScriptValue accessor = pvt->dataObj.property(id);
- if (accessor.isFunction()) {
- accessor.setProperty("value",scriptEngine()->newVariant(val));
- }
+ pvt->dataObj.setProperty(id,scriptEngine()->newVariant(val));
}
/*!
@@ -1100,78 +1122,80 @@ QEvent::Type QScxmlEvent::eventType()
static QEvent::Type _t = (QEvent::Type)QEvent::registerEventType(QEvent::User+200);
return _t;
}
-const char SCXML_NAMESPACE [] = "http://www.w3.org/2005/07/scxml";
+namespace {
+ const char SCXML_NAMESPACE [] = "http://www.w3.org/2005/07/scxml";
-struct ScTransitionInfo
-{
-
- QScxmlTransition* transition;
- QStringList targets;
- QString script;
- ScTransitionInfo() : transition(NULL) {}
-};
+ struct ScTransitionInfo
+ {
-class QScxmlScriptExec : public QObject
-{
- Q_OBJECT
- QScriptProgram prog;
- QScxml* scxml;
- public:
- QScxmlScriptExec(const QString & scr, QScxml* scx) :
- prog(QScriptProgram(scr,scx->baseUrl().toLocalFile())),scxml(scx)
- {
- }
- public Q_SLOTS:
- void exec()
- {
- scxml->executeScript(prog);
- }
-};
+ QScxmlTransition* transition;
+ QStringList targets;
+ QString script;
+ ScTransitionInfo() : transition(NULL) {}
+ };
-struct ScStateInfo
-{
- QString initial;
-};
+ class QScxmlScriptExec : public QObject
+ {
+ Q_OBJECT
+ QScriptProgram prog;
+ QScxml* scxml;
+ public:
+ QScxmlScriptExec(const QString & scr, QScxml* scx) :
+ prog(QScriptProgram(scr,scx->baseUrl().toLocalFile())),scxml(scx)
+ {
+ }
+ public Q_SLOTS:
+ void exec()
+ {
+ scxml->executeScript(prog);
+ }
+ };
-struct ScHistoryInfo
-{
- QHistoryState* hstate;
- QString defaultStateID;
-};
+ struct ScStateInfo
+ {
+ QString initial;
+ };
-struct ScExecContext
-{
- QScxml* sm;
- QString script;
- enum {None, StateEntry,StateExit,Transition } type;
- QScxmlTransition* trans;
- QAbstractState* state;
- ScExecContext() : sm(NULL),type(None),trans(NULL),state(NULL)
+ struct ScHistoryInfo
{
- }
+ QHistoryState* hstate;
+ QString defaultStateID;
+ };
- void applyScript()
+ struct ScExecContext
{
- if (!script.isEmpty()) {
- QScxmlScriptExec* exec = new QScxmlScriptExec(script,sm);
- switch(type) {
- case StateEntry:
- QObject::connect(state,SIGNAL(entered()),exec,SLOT(exec()));
- break;
- case StateExit:
- QObject::connect(state,SIGNAL(exited()),exec,SLOT(exec()));
- break;
- case Transition:
- QObject::connect(trans,SIGNAL(triggered()),exec,SLOT(exec()));
- break;
- default:
- delete exec;
- break;
+ QScxml* sm;
+ QString script;
+ enum {None, StateEntry,StateExit,Transition } type;
+ QScxmlTransition* trans;
+ QAbstractState* state;
+ ScExecContext() : sm(NULL),type(None),trans(NULL),state(NULL)
+ {
+ }
+
+ void applyScript()
+ {
+ if (!script.isEmpty()) {
+ QScxmlScriptExec* exec = new QScxmlScriptExec(script,sm);
+ switch(type) {
+ case StateEntry:
+ QObject::connect(state,SIGNAL(entered()),exec,SLOT(exec()));
+ break;
+ case StateExit:
+ QObject::connect(state,SIGNAL(exited()),exec,SLOT(exec()));
+ break;
+ case Transition:
+ QObject::connect(trans,SIGNAL(triggered()),exec,SLOT(exec()));
+ break;
+ default:
+ delete exec;
+ break;
+ }
}
}
- }
+ };
};
class QScxmlLoader
@@ -1436,21 +1460,24 @@ void QScxmlLoader::loadState (
curTransition->setObjectName(QString ("%1 to %2 on %3 if %4").arg(curState->objectName()).arg(inf.targets.join(" ")).arg(curTransition->eventPrefixes().join(" ")).arg(curTransition->conditionExpression()));
}
} else if (r.name().toString().compare("data",Qt::CaseInsensitive) == 0) {
- QScriptValue val = qScriptValueFromValue<QString>(stateMachine->scriptEngine(),"") ;
+ QScriptEngine* engine = stateMachine->scriptEngine();
+ QScriptValue val = qScriptValueFromValue<QString>(engine,"") ;
QString id = r.attributes().value("id").toString();
if (r.attributes().value("src").length())
val = evaluateFile(QFileInfo(filename).dir().absoluteFilePath(r.attributes().value("src").toString()));
else {
if (r.attributes().value("expr").length()) {
- val = stateMachine->scriptEngine()->evaluate(r.attributes().value("expr").toString());
+ val = engine->evaluate(r.attributes().value("expr").toString());
} else {
QString t = r.readElementText();
if (!t.isEmpty())
- val = stateMachine->scriptEngine()->evaluate(t);
+ val = engine->evaluate(t);
}
}
- QScriptValue func = stateMachine->scriptEngine()->newFunction(QScxmlFunctions::dataAccess);
- func.setProperty("key",id);
+ QScriptValue func = engine->newFunction(QScxmlFunctions::dataAccess);
+ QScriptValue accessor = engine->newObject();
+ accessor.setProperty("key",id);
+ func.setData(accessor);
stateMachine->pvt->dataObj.setProperty(id,func,QScriptValue::PropertyGetter|QScriptValue::PropertySetter);
stateMachine->pvt->dataObj.setProperty(id,val);
} else if (r.name().toString().compare("param",Qt::CaseInsensitive) == 0) {
@@ -1532,7 +1559,6 @@ void QScxmlLoader::loadState (
}
}
}
-
QMap<QString,QVariant> QScxml::data() const
{
QMap<QString,QVariant> d;