diff options
-rw-r--r-- | scc/main.cpp | 25 | ||||
-rw-r--r-- | scc/scc.pro | 16 | ||||
-rw-r--r-- | scc/scc.qrc | 6 | ||||
-rw-r--r-- | scc/scc.xslt | 266 |
4 files changed, 313 insertions, 0 deletions
diff --git a/scc/main.cpp b/scc/main.cpp new file mode 100644 index 0000000..4ed1aff --- /dev/null +++ b/scc/main.cpp @@ -0,0 +1,25 @@ +#include <QtCore/QCoreApplication> +#include <QXmlQuery> +#include <QUrl> +#include <QStringList> +#include <QFile> +#include <QFileInfo> +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + QXmlQuery query(QXmlQuery::XSLT20); + QUrl target = QUrl::fromLocalFile(a.arguments()[1]); + query.setFocus(target); + QFile q(":/scc/scc.xslt"); + q.open(QIODevice::ReadOnly); + query.bindVariable("target",QXmlItem(QFileInfo(target.toLocalFile()).baseName())); + query.setQuery(QString(q.readAll())); + QString s; + query.evaluateTo(&s); + s = s.replace("<","<").replace(">",">").replace("&","&"); + QFile f(a.arguments()[2]); + f.open(QIODevice::WriteOnly); + f.write(s.toUtf8()); + return 0; +// return a.exec(); +} diff --git a/scc/scc.pro b/scc/scc.pro new file mode 100644 index 0000000..db41f1e --- /dev/null +++ b/scc/scc.pro @@ -0,0 +1,16 @@ +# ------------------------------------------------- +# Project created by QtCreator 2009-08-02T10:07:01 +# ------------------------------------------------- +QT += network \ + xmlpatterns +QT -= gui +TARGET = scc +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app +SOURCES += main.cpp +OTHER_FILES += scc.xslt \ + test.scxml \ + scc-example.hh \ + xipr.xsl +RESOURCES += scc.qrc diff --git a/scc/scc.qrc b/scc/scc.qrc new file mode 100644 index 0000000..a03d93a --- /dev/null +++ b/scc/scc.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/scc" > + <file>scc.xslt</file> + <file>xipr.xsl</file> + </qresource> +</RCC> diff --git a/scc/scc.xslt b/scc/scc.xslt new file mode 100644 index 0000000..de42521 --- /dev/null +++ b/scc/scc.xslt @@ -0,0 +1,266 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +<xsl:template name="smname"><xsl:choose><xsl:when test="string(/scxml/@name)=''"><xsl:value-of select="$target" /></xsl:when> + <xsl:otherwise><xsl:value-of select="/scxml/@name" /></xsl:otherwise></xsl:choose> +</xsl:template> +<xsl:template mode="stateid" match="*"> + <xsl:choose > + <xsl:when test="name()='scxml'">this</xsl:when> + <xsl:when test="string(@id) != ''" >state_<xsl:value-of select="@id" /></xsl:when> + <xsl:otherwise>state_<xsl:value-of select="generate-id()" /></xsl:otherwise> + </xsl:choose> +</xsl:template> +<xsl:template mode="execContext" match="if"> + if (<xsl:value-of select="@cond" />) { + <xsl:apply-templates mode="execContext" /> + } +</xsl:template> +<xsl:template mode="execContext" match="else"> + } else { +</xsl:template> +<xsl:template mode="execContext" match="elseif"> + } else if (<xsl:value-of select="@cond" />) { +</xsl:template> +<xsl:template mode="execContext" match="log"> + QDebug((QtMsgType)<xsl:if test="string(@level)=''">0</xsl:if><xsl:value-of select="@level" />) << "<xsl:value-of select="@label" />" << <xsl:value-of select="@expr" />; +</xsl:template> +<xsl:template mode="execContext" match="assign"> + <xsl:if test="string(@dataid) != ''"> + set_<xsl:value-of select="@dataid" />(<xsl:value-of select="@expr" />); + </xsl:if> +</xsl:template> +<xsl:template mode="execContext" match="raise|send"> + <xsl:choose> + <xsl:when test="name()='raise' or target='_internal'">postInternalEvent(</xsl:when> + <xsl:otherwise><xsl:if test="string(@id)!=''"> + eventSenders[<xsl:value-of select="@id" />] = </xsl:if>new SCC_EventSender(this,<xsl:if test="string(@delay)=''">0</xsl:if> + <xsl:value-of select="@delay" />, + </xsl:otherwise> + </xsl:choose>new QSignalEvent(<xsl:if + test="string(@target)=''">this</xsl:if><xsl:value-of + select="@target" />,(*metaObject()).indexOfSignal("<xsl:value-of select="replace(@event,'\.','__')" />"),QVariantList()<xsl:for-each + select="param"><xsl:text><![CDATA[<<]]></xsl:text> QVariant(<xsl:value-of select="@expr" /><xsl:value-of select="text()" />) + </xsl:for-each>)); +</xsl:template> +<xsl:template mode="execContext" match="cancel"> + { QObject* obj = eventSenders[<xsl:value-of select="@id" />]; if (obj) { (*obj).cancel(); } +</xsl:template> + +<xsl:template match="/"> +#include "QStateMachine" +#include "QSignalTransition" +<xsl:if test="count(//send[@target!='_internal']) != 0"> +#include "QTimer" +</xsl:if> +<xsl:if test="count(//final)!=0"> + #include "QFinalState" +</xsl:if> +<xsl:if test="count(//history)!=0"> + #include "QHistoryState" +</xsl:if> +#include "QHash" +#include "QSignalEvent" +#include "QEventTransition" +<xsl:if test="count(//log)!=0"> +#include "QDebug" +</xsl:if> +#ifndef __SMCLASS_<xsl:call-template name="smname" />_H +#define __SMCLASS_<xsl:call-template name="smname" />_H +class SMClass_<xsl:call-template name="smname" />; + <xsl:if test="count(//transition[string(@event)='' and string(@cond)=''])!=0"> + class SCC_UnconditionalTransition : public QAbstractTransition + { + public: + SCC_UnconditionalTransition(QState* s) + : QAbstractTransition(s) {} + protected: + void onTransition(QEvent *) {} + bool eventTest(QEvent *) { return true; } + }; + </xsl:if> + <xsl:if test="count(//send[string(@target)!='_internal'])!=0"> + class SCC_EventSender : public QTimer + { + Q_OBJECT + private: + QStateMachine* machine; + QEvent* event; + public: + SCC_EventSender(QStateMachine* m, int delay, QEvent* e) : QTimer(m), machine(m), event(e) + { + setInterval(delay); + setSingleShot(true); + connect(this,SIGNAL(timeout()),this,SLOT(send())); + } + public Q_SLOTS: + void cancel() { stop(); deleteLater(); } + void send() { machine->postEvent(event); } + }; + </xsl:if> + <xsl:if test="count(//transition[string(@cond) != '']) !=0"> +namespace { + <xsl:for-each select="//transition[string(@cond) != '']"> + class Transition_<xsl:value-of select="generate-id()" /> : public Q<xsl:if test="string(@event) != ''">Signal</xsl:if>Transition + { + SMClass_<xsl:call-template name="smname" />* stateMachine; + public: + Transition_<xsl:value-of select="generate-id()" />(QState* parent) + : Q<xsl:if test="string(@event) != ''">Signal</xsl:if>Transition(parent),stateMachine((SMClass_<xsl:call-template name="smname" />*)(*parent).machine()) + { + } + + protected: + bool eventTest(QEvent* e); + }; + + </xsl:for-each> +}; + </xsl:if> +class SMClass_<xsl:call-template name="smname" /> : public QStateMachine +{ + Q_OBJECT +<xsl:for-each select="//datamodel/data"> + Q_PROPERTY(<xsl:value-of select="concat(@type,' ')" /> <xsl:value-of select="@id" /> READ get_<xsl:value-of select="@id" /> WRITE set_<xsl:value-of select="@id" /> NOTIFY <xsl:value-of select="@id" />_changed) +</xsl:for-each> +<xsl:for-each select="//transition/@animation"> + Q_PROPERTY(QAbstractAnimation* <xsl:value-of select="string()" /> READ anim_<xsl:value-of select="string()" /> WRITE setAnim_<xsl:value-of select="string()" />) +</xsl:for-each> + + public: + SMClass_<xsl:call-template name="smname" />(QObject* o) : QStateMachine(o) {} + <xsl:for-each select="//state|//parallel|//initial[count(transition/*)!=0]"> + QState* <xsl:apply-templates mode="stateid" select="current()" />;</xsl:for-each> + <xsl:for-each select="//final"> + QFinalState* <xsl:apply-templates mode="stateid" select="current()" />; + </xsl:for-each> + <xsl:for-each select="//history"> + QHistoryState* <xsl:apply-templates mode="stateid" select="current()" />; + </xsl:for-each> + <xsl:for-each select="//transition[string(@cond) != '']"> + bool testCondition_<xsl:value-of select="generate-id()" />(const QEvent & _event) + { + Q_UNUSED(_event) + return <xsl:if test="string(@cond)=''">true</xsl:if><xsl:value-of select="@cond"/>; + } + </xsl:for-each> + <xsl:for-each select="//datamodel/data"> + <xsl:value-of select="@type" /> get_<xsl:value-of select="@id" />() const + { + return _data.<xsl:value-of select="@id" />; + } + void set_<xsl:value-of select="@id" />(const <xsl:value-of select="@type" /> & value) + { + _data.<xsl:value-of select="@id" /> = value; + emit <xsl:value-of select="@id" />_changed(value); + } + </xsl:for-each> + <xsl:if test="count(//datamodel/data) != 0"> + protected: + struct { + <xsl:for-each select="//datamodel/data"> + <xsl:text> </xsl:text><xsl:value-of select="@type" /><xsl:text> </xsl:text><xsl:value-of select="@id" />;</xsl:for-each> + } _data; + </xsl:if> + <xsl:if test="(count(//datamodel/data)+count(/scxml/script))!=0"> + void initScript() + { +<xsl:for-each select="//datamodel/data"> + <xsl:if test="string(@expr) != ''"> + _data.<xsl:value-of select="@id" /> = <xsl:value-of select="@expr"/><xsl:value-of select="text()"/>; + </xsl:if> +</xsl:for-each> + <xsl:value-of select="/scxml/script/text()" /> + } +</xsl:if> + private Q_SLOTS: + <xsl:for-each select="//transition|//onentry|//onexit"><xsl:if test="count(*) != 0"> + void exec_<xsl:value-of select="generate-id()" />() + { + <xsl:apply-templates mode="execContext" /> + } + </xsl:if></xsl:for-each> + Q_SIGNALS:<xsl:for-each select="distinct-values(//node()[not (starts-with(@event,'done.state.') or contains(@event,':'))]/@event)"> + void event_<xsl:value-of select="replace(string(),'\.','__')" />();</xsl:for-each> + <xsl:for-each select="//datamodel/data"> + void <xsl:value-of select="@id" />_changed(const <xsl:value-of select="@type" /> &); + </xsl:for-each> + <xsl:if test="count(//property)!=0"> + protected: +#ifndef QT_NO_PROPERTIES + virtual void endSelectTransitions(QEvent *event) + { + <xsl:for-each select="//property"> + (*<xsl:apply-templates mode="stateid" select=".." />).assignProperty(<xsl:value-of + select="@object" />,"<xsl:value-of select="@name" />",QVariant(<xsl:value-of select="@expr" />)); + </xsl:for-each> + } +#endif + </xsl:if> +<xsl:if test="count(//send[string(@target)!='internal']) != 0"> + private: + <xsl:text><![CDATA[QHash<QString,SCC_EventSender>]]></xsl:text> _eventSenders; +</xsl:if> + public: + void setupStateMachine() + { + setObjectName("<xsl:call-template name="smname" />"); + <xsl:for-each select="//state|//parallel|//final|//history|//initial"> + <xsl:apply-templates mode="stateid" select="." /> = new <xsl:choose> + <xsl:when test="name()='final'">QFinalState</xsl:when> + <xsl:when test="name()='history'">QHistoryState</xsl:when> + <xsl:otherwise>QState</xsl:otherwise> + </xsl:choose>(<xsl:apply-templates mode="stateid" select=".." />); + (*<xsl:apply-templates mode="stateid" select="." />).setObjectName("<xsl:value-of select="@id" />"); + <xsl:if + test="name()='initial' or @id=../@initial"> + (*<xsl:apply-templates mode="stateid" select=".." />).setInitialState(<xsl:apply-templates mode="stateid" select="." />);</xsl:if> + <xsl:if test="name()='parallel'"> + (*<xsl:apply-templates mode="stateid" select="." />).setChildMode(ParallelStates); + </xsl:if> + <xsl:if test="name()='history'"> + (*<xsl:apply-templates mode="stateid" select="." />).setHistoryType(QHistoryState::<xsl:choose> + <xsl:when test="@type='deep'">Deep</xsl:when> + <xsl:otherwise>Shallow</xsl:otherwise> + </xsl:choose>History); + </xsl:if> + </xsl:for-each> + QAbstractTransition* transition;<xsl:for-each select="//transition"> + transition = new <xsl:choose> + <xsl:when test="string(@cond)!=''">Transition_<xsl:value-of + select="generate-id()" />(</xsl:when> + <xsl:when test="starts-with(@event,'q-event:')">QEventTransition(<xsl:value-of + select="substring-after(@event,'q-event:')" />,</xsl:when> + <xsl:when test="starts-with(@event,'done.state.')">QSignalTransition(state_<xsl:value-of + select="substring-after(@event,'done.state.')" />,SIGNAL(finished()),</xsl:when> + <xsl:when test="string(@event)!=''">QSignalTransition(this,SIGNAL(event_<xsl:value-of select="replace(@event,'\.','__')" />()),</xsl:when> + <xsl:otherwise>SCC_UnconditionalTransition(</xsl:otherwise></xsl:choose><xsl:apply-templates mode="stateid" select=".." />);<xsl:if test="count(*) != 0"> + connect(transition,SIGNAL(triggered()),this,SLOT(exec_<xsl:value-of select="generate-id()" />()));</xsl:if> + <xsl:if test="string(@animation) != ''"> + (*transition).addAnimation(<xsl:value-of select="@animation" />);</xsl:if><xsl:if + test="string(@target) != ''"></xsl:if> + <xsl:choose> + <xsl:when test="string(@target)=''" /> + <xsl:when test="count(tokenize(@target,'\s+'))=1"> + (*transition).setTargetState(state_<xsl:value-of select="@target" />);</xsl:when> + <xsl:otherwise>(*transition).setTargetStates(QList<QAbstractState*>()<xsl:for-each + select="tokenize(@target,'\s+')"> << state_<xsl:value-of select="." /></xsl:for-each>);</xsl:otherwise> + </xsl:choose> + </xsl:for-each> + <xsl:for-each select="//onentry|//onexit"><xsl:if test="count(*) != 0"> + connect(<xsl:apply-templates mode="stateid" select=".." />, SIGNAL(<xsl:choose> + <xsl:when test="name()='onentry'">entered</xsl:when> + <xsl:when test="name()='onexit'">exited</xsl:when> + </xsl:choose>()),this,SLOT(exec_<xsl:value-of select="generate-id()" />()));</xsl:if></xsl:for-each> + } +}; + <xsl:for-each select="//transition[string(@cond) != '']"> + bool Transition_<xsl:value-of select="generate-id()" />::eventTest(QEvent* e) + { + return Q<xsl:if test="string(@event) != ''">Signal</xsl:if>Transition::eventTest(e) + && stateMachine->testCondition_<xsl:value-of select="generate-id()" />(e?(*e):QEvent(QEvent::None)); + } + </xsl:for-each> +#endif + </xsl:template> + +</xsl:stylesheet> |