summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNo'am Rosenthal <noam.rosenthal@nokia.com>2009-11-26 15:02:57 -0800
committerNo'am Rosenthal <noam.rosenthal@nokia.com>2009-11-26 15:02:57 -0800
commit88302167db167becb15b46ad1ef821251aed1769 (patch)
tree5d086543102fd5b4ed482867f532050dc59ed573
parent3d88526d4943bc6273b2d47f608e9d418724e112 (diff)
QmlScxml
-rw-r--r--examples/scc/algotest/algotest.pro (renamed from scc/examples/algotest/algotest.pro)0
-rw-r--r--examples/scc/algotest/main.cpp (renamed from scc/examples/algotest/main.cpp)0
-rw-r--r--examples/scc/algotest/test.scxml (renamed from scc/examples/algotest/test.scxml)0
-rw-r--r--examples/scc/animations/animations.pro (renamed from scc/examples/animations/animations.pro)0
-rw-r--r--examples/scc/animations/animations.scxml (renamed from scc/examples/animations/animations.scxml)0
-rw-r--r--examples/scc/animations/main.cpp (renamed from scc/examples/animations/main.cpp)0
-rw-r--r--examples/scc/examples.pro (renamed from scc/examples/examples.pro)0
-rw-r--r--examples/scc/loginmvc/controller.scxml (renamed from scc/examples/loginmvc/controller.scxml)0
-rw-r--r--examples/scc/loginmvc/frame.ui (renamed from scc/examples/loginmvc/frame.ui)0
-rw-r--r--examples/scc/loginmvc/loginmvc.pro (renamed from scc/examples/loginmvc/loginmvc.pro)0
-rw-r--r--examples/scc/loginmvc/main.cpp (renamed from scc/examples/loginmvc/main.cpp)0
-rw-r--r--qmlscxml/qmlscxml.cpp221
-rw-r--r--qmlscxml/qmlscxml.h62
-rw-r--r--qmlscxml/qmlscxml.pri7
-rw-r--r--src/qscxml.cpp3
15 files changed, 291 insertions, 2 deletions
diff --git a/scc/examples/algotest/algotest.pro b/examples/scc/algotest/algotest.pro
index e5a1eba..e5a1eba 100644
--- a/scc/examples/algotest/algotest.pro
+++ b/examples/scc/algotest/algotest.pro
diff --git a/scc/examples/algotest/main.cpp b/examples/scc/algotest/main.cpp
index 4fe6364..4fe6364 100644
--- a/scc/examples/algotest/main.cpp
+++ b/examples/scc/algotest/main.cpp
diff --git a/scc/examples/algotest/test.scxml b/examples/scc/algotest/test.scxml
index e17f9bf..e17f9bf 100644
--- a/scc/examples/algotest/test.scxml
+++ b/examples/scc/algotest/test.scxml
diff --git a/scc/examples/animations/animations.pro b/examples/scc/animations/animations.pro
index d501c13..d501c13 100644
--- a/scc/examples/animations/animations.pro
+++ b/examples/scc/animations/animations.pro
diff --git a/scc/examples/animations/animations.scxml b/examples/scc/animations/animations.scxml
index 0aabb64..0aabb64 100644
--- a/scc/examples/animations/animations.scxml
+++ b/examples/scc/animations/animations.scxml
diff --git a/scc/examples/animations/main.cpp b/examples/scc/animations/main.cpp
index 296e582..296e582 100644
--- a/scc/examples/animations/main.cpp
+++ b/examples/scc/animations/main.cpp
diff --git a/scc/examples/examples.pro b/examples/scc/examples.pro
index 39b6dbb..39b6dbb 100644
--- a/scc/examples/examples.pro
+++ b/examples/scc/examples.pro
diff --git a/scc/examples/loginmvc/controller.scxml b/examples/scc/loginmvc/controller.scxml
index 8bffc1a..8bffc1a 100644
--- a/scc/examples/loginmvc/controller.scxml
+++ b/examples/scc/loginmvc/controller.scxml
diff --git a/scc/examples/loginmvc/frame.ui b/examples/scc/loginmvc/frame.ui
index 4b57955..4b57955 100644
--- a/scc/examples/loginmvc/frame.ui
+++ b/examples/scc/loginmvc/frame.ui
diff --git a/scc/examples/loginmvc/loginmvc.pro b/examples/scc/loginmvc/loginmvc.pro
index 9af965a..9af965a 100644
--- a/scc/examples/loginmvc/loginmvc.pro
+++ b/examples/scc/loginmvc/loginmvc.pro
diff --git a/scc/examples/loginmvc/main.cpp b/examples/scc/loginmvc/main.cpp
index a8e9ee9..a8e9ee9 100644
--- a/scc/examples/loginmvc/main.cpp
+++ b/examples/scc/loginmvc/main.cpp
diff --git a/qmlscxml/qmlscxml.cpp b/qmlscxml/qmlscxml.cpp
new file mode 100644
index 0000000..2183945
--- /dev/null
+++ b/qmlscxml/qmlscxml.cpp
@@ -0,0 +1,221 @@
+#include "qmlscxml.h"
+#include "qscxml.h"
+#include <QDebug>
+#include "qmlpropertymap.h"
+
+class QmlScxmlEventProxy : public QObject
+{
+ Q_OBJECT
+ QScxml* scxml;
+ QString eventName;
+ public:
+ QmlScxmlEventProxy (const QString & name, QScxml* scx): QObject(scx)
+ ,scxml(scx),eventName(name)
+ {
+ connect(scxml,SIGNAL(eventTriggered(QString)),this,SLOT(onEvent(QString)));
+ }
+
+ Q_SIGNALS:
+ void triggered();
+
+ public Q_SLOTS:
+ void raise()
+ {
+ scxml->postNamedEvent(eventName);
+ }
+
+ void onEvent(const QString & e)
+ {
+ if (e == eventName) {
+ emit triggered();
+ }
+ }
+};
+QmlScxml::QmlScxml(QObject* o) : QObject(o)
+ ,m_states(NULL),m_events(NULL),m_data(NULL),m_cur(NULL),scxml(NULL)
+{
+}
+QmlScxml::~QmlScxml()
+{
+}
+QObject* QmlScxml::states() const
+{
+ return m_states;
+}
+QObject* QmlScxml::events() const
+{
+ return m_events;
+}
+QObject* QmlScxml::data() const
+{
+ return m_data;
+}
+QObject* QmlScxml::current() const
+{
+ return m_cur;
+}
+QUrl QmlScxml::source() const
+{
+ return m_source;
+}
+
+namespace {
+ QString _q_fixName(QString oldName) {
+ QString newName;
+ bool beginWord = false;
+ if (oldName == oldName.toUpper())
+ oldName = oldName.toLower();
+
+ foreach (QChar c, oldName) {
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ newName += beginWord ? c.toUpper() : (newName=="" ? c.toLower() :c);
+ beginWord = false;
+ } else if (newName != "") {
+ if (c >= '0' && c <= '9') {
+ newName += c;
+ } else
+ beginWord = true;
+ }
+ }
+ return newName;
+ }
+};
+void QmlScxml::setSource(const QUrl & u)
+{
+ qDebug() << u;
+ if (u != m_source) {
+ m_source = u;
+ if (scxml) {
+ delete scxml;
+ scxml= NULL;
+ }
+ scxml = QScxml::load(u.toLocalFile(),this);
+ if (scxml) {
+ connect(scxml,SIGNAL(started()),this,SIGNAL(runningChanged()));
+ connect(scxml,SIGNAL(stopped()),this,SIGNAL(runningChanged()));
+ connect(scxml,SIGNAL(finished()),this,SIGNAL(finished()));
+ connect(scxml,SIGNAL(eventTriggered(QString)),this,SIGNAL(trigger(QString)));
+ connect(scxml,SIGNAL(configurationChanged()),this,SLOT(checkConfig()));
+ if (m_states)
+ delete m_states;
+ if (m_events)
+ delete m_events;
+ if (m_data)
+ delete m_data;
+ if (m_cur)
+ delete m_cur;
+ m_idForState.clear();
+ m_states = new QmlPropertyMap(this);
+ m_events = new QmlPropertyMap(this);
+ m_data = new QmlPropertyMap(this);
+ m_cur = new QmlPropertyMap(this);
+ QMap<QString,QVariant> curData = scxml->data();
+ for (QMap<QString,QVariant>::iterator it = curData.begin(); it != curData.end(); ++it) {
+ m_data->insert(it.key(),it.value());
+ }
+
+ connect(m_data,SIGNAL(valueChanged(QString)),this,SLOT(onDataChanged(QString)));
+ QList<QAbstractState*> states = scxml->findChildren<QAbstractState*>();
+ m_oldConfig = scxml->configuration();
+ foreach (QAbstractState* s, states) {
+ QString name = _q_fixName(s->objectName());
+ if (name != "") {
+ m_states->insert(name,QVariant::fromValue<QObject*>(s));
+ m_cur->insert(name,m_oldConfig.contains(s));
+ m_idForState[s] = name;
+ }
+ }
+ QMap<QString,QString> prefixMap;
+ QStringList knownEvents = scxml->knownEventNames();
+ foreach (QString ev, knownEvents) {
+ prefixMap[_q_fixName(ev)] = ev;
+ }
+ for (QMap<QString,QString>::iterator it = prefixMap.begin(); it != prefixMap.end(); ++it) {
+ if (it.key() != "" && it.value() != "") {
+ m_events->insert(it.key(),QVariant::fromValue<QObject*>(new QmlScxmlEventProxy(it.value(),scxml)));
+ }
+ }
+ emit statesChanged(m_states);
+ emit eventsChanged(m_events);
+ emit dataChanged(m_data);
+ emit currentChanged(m_cur);
+ scxml->start();
+ }
+ emit sourceChanged(u);
+ }
+}
+
+void QmlScxml::onDataChanged(const QString & key)
+{
+ m_data->blockSignals(true);
+ scxml->setData(key,(*m_data)[key]);
+ m_data->blockSignals(false);
+}
+void QmlScxml::onDataChanged(const QString & key, const QVariant & value)
+{
+ if (m_data) {
+ (*m_data)[key] = value;
+ }
+}
+
+void QmlScxml::checkConfig()
+{
+ QSet<QAbstractState*> config = scxml->configuration();
+ if (config != m_oldConfig) {
+ QSet<QAbstractState*> intersecting = config & m_oldConfig;
+ QSet<QAbstractState*> toRemove = m_oldConfig - intersecting;
+ QSet<QAbstractState*> toAdd = config - intersecting;
+
+ for (QSet<QAbstractState*>::iterator it = toRemove.begin(); it != toRemove.end(); ++it) {
+ QString name = m_idForState[*it];
+ if (name != "") {
+ (*m_cur)[name] = false;
+ }
+ }
+ for (QSet<QAbstractState*>::iterator it = toAdd.begin(); it != toAdd.end(); ++it) {
+ QString name = m_idForState[*it];
+ if (name != "") {
+ (*m_cur)[name] = true;
+ }
+ }
+ m_oldConfig = config;
+ emit currentChanged(m_cur);
+ }
+}
+
+
+bool QmlScxml::isRunning() const
+{
+ return scxml?scxml->isRunning():false;
+}
+void QmlScxml::setRunning(bool r)
+{
+ if (scxml) {
+ if (r) {
+ scxml->start();
+ } else {
+ scxml->stop();
+ }
+ }
+}
+void QmlScxml::raise(const QString & e)
+{
+ if (scxml) {
+ scxml->postNamedEvent(e);
+ }
+}
+void QmlScxml::stop()
+{
+ if (scxml) {
+ scxml->stop();
+ }
+}
+void QmlScxml::start()
+{
+ if (scxml) {
+ scxml->start();
+ }
+}
+QML_DEFINE_TYPE(Scxml, 1,0, Scxml, QmlScxml);
+
+#include <qmlscxml.moc>
diff --git a/qmlscxml/qmlscxml.h b/qmlscxml/qmlscxml.h
new file mode 100644
index 0000000..b44b45f
--- /dev/null
+++ b/qmlscxml/qmlscxml.h
@@ -0,0 +1,62 @@
+#ifndef QMLSCXML_H
+#define QMLSCXML_H
+
+#include <QObject>
+#include <QSet>
+#include "qml.h"
+
+class QAbstractState;
+class QmlScxml : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(QObject* states READ states NOTIFY statesChanged)
+ Q_PROPERTY(QObject* events READ events NOTIFY eventsChanged)
+ Q_PROPERTY(QObject* data READ data NOTIFY dataChanged)
+ Q_PROPERTY(QObject* current READ current NOTIFY currentChanged)
+ Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
+
+public:
+ QmlScxml(QObject* o = NULL);
+ virtual ~QmlScxml();
+ QObject* states() const;
+ QObject* events() const;
+ QObject* data() const;
+ QObject* current() const;
+ QUrl source() const;
+ void setSource(const QUrl &);
+ bool isRunning() const;
+ void setRunning(bool);
+
+public slots:
+ void raise(const QString &);
+ void stop();
+ void start();
+
+signals:
+ void sourceChanged(const QUrl &);
+ void statesChanged(QObject*);
+ void eventsChanged(QObject*);
+ void dataChanged(QObject*);
+ void currentChanged(QObject*);
+ void trigger(const QString & e);
+ void runningChanged();
+ void finished();
+private slots:
+ void onDataChanged(const QString &, const QVariant &);
+ void onDataChanged(const QString &);
+ void checkConfig();
+private:
+ class QmlPropertyMap* m_states;
+ class QmlPropertyMap* m_events;
+ class QmlPropertyMap* m_data;
+ class QmlPropertyMap* m_cur;
+ QMap<QAbstractState*,QString> m_idForState;
+ QUrl m_source;
+ QSet<QAbstractState*> m_oldConfig;
+ class QScxml* scxml;
+};
+
+QML_DECLARE_TYPE(QmlScxml);
+
+#endif // QMLSCXML_H
diff --git a/qmlscxml/qmlscxml.pri b/qmlscxml/qmlscxml.pri
new file mode 100644
index 0000000..2931219
--- /dev/null
+++ b/qmlscxml/qmlscxml.pri
@@ -0,0 +1,7 @@
+DEPENDPATH += $$PWD
+INCLUDEPATH += $$PWD
+
+# Input
+SOURCES += qmlscxml.cpp
+HEADERS += qmlscxml.h
+include($$PWD/../src/qscxml.pri)
diff --git a/src/qscxml.cpp b/src/qscxml.cpp
index cbb9c7c..d6142e5 100644
--- a/src/qscxml.cpp
+++ b/src/qscxml.cpp
@@ -928,7 +928,6 @@ void QScxml::endMicrostep(QEvent*)
pvt->snapshotStack.remove(0,pvt->snapshotStack.size()-100);
}
pvt->curSnapshot.clear();
- qDebug() << configuration();
emit configurationChanged();
/*
if (e->type() == QScxmlEvent::eventType()) {
@@ -991,7 +990,7 @@ void QScxml::setData(const QString & id, const QVariant & val)
void QScxml::executeScript (const QScriptProgram & s)
{
- qDebug() << "Executing\n--------------------------\n"<<s.sourceCode();
+// qDebug() << "Executing\n--------------------------\n"<<s.sourceCode();
pvt->scriptEng->evaluate (s);
if (pvt->scriptEng->hasUncaughtException()) {
QScxmlEvent* e = new QScxmlEvent("error.illegalvalue",