1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://www.w3.org/2005/07/scxml" 
3
    xmlns:Qt="http://www.qtsoftware.com scxml-ext">
4
<xsl:template name="smname"><xsl:choose><xsl:when test="string(/s:scxml/@name)=''"><xsl:value-of select="$target" /></xsl:when>
5
 <xsl:otherwise><xsl:value-of select="/sLscxml/@name" /></xsl:otherwise></xsl:choose>
6
</xsl:template>
7
<xsl:template name="comment"><xsl:if test="$comments">
8
        /*
9
            <xsl:element name="{name()}">
10
              <xsl:for-each select="@*"><xsl:attribute name="{name()}">
11
              <xsl:value-of select="string()" /></xsl:attribute></xsl:for-each><xsl:value-of select="text()" /></xsl:element>
12
        */
13
</xsl:if></xsl:template>
14
<xsl:template mode="stateid" match="s:scxml|s:state|s:parallel|s:final|s:initial|s:history" priority="2">
15
    <xsl:choose>
16
        <xsl:when test="name()='scxml'">this</xsl:when>
17
        <xsl:when test="string(@id) != ''" >state_<xsl:value-of select="@id" /></xsl:when>
18
        <xsl:otherwise>state_<xsl:value-of select="generate-id()" /></xsl:otherwise>
19
    </xsl:choose>
20
</xsl:template>
21
<xsl:template mode="execContext" match="s:if">
22
<xsl:call-template name="comment" />
23
              if (<xsl:value-of select="@cond" />) {
24
  <xsl:apply-templates mode="execContext" />
25
              }
26
</xsl:template>
27
<xsl:template mode="execContext" match="s:else">
28
<xsl:call-template name="comment" />
29
              } else {
30
</xsl:template>
31
<xsl:template mode="execContext" match="s:elseif">
32
<xsl:call-template name="comment" />
33
              } else if (<xsl:value-of select="@cond" />) {
34
</xsl:template>
35
<xsl:template mode="execContext" match="s:log">
36
<xsl:call-template name="comment" />
37
                QDebug((QtMsgType)<xsl:if test="string(@level)=''">0</xsl:if><xsl:value-of select="@level" />) <xsl:if test="string(@label)!=''">&lt;&lt; "<xsl:value-of select="@label" />" </xsl:if>&lt;&lt; <xsl:value-of select="@expr" />;
38
</xsl:template>
39
<xsl:template mode="execContext" match="s:assign"><xsl:call-template name="comment" />
40
<xsl:choose>
41
42
    <xsl:when test="string(@dataid) != ''">
43
                set_<xsl:value-of select="@dataid" />(<xsl:value-of select="@expr" />);
44
    </xsl:when>
45
    <xsl:when test="string(@location) != ''">
46
              <xsl:value-of select="@location" /> = (<xsl:value-of select="@expr" />);
47
    </xsl:when>
48
</xsl:choose>
49
</xsl:template>
50
<xsl:template mode="execContext" match="s:raise|s:send">
51
<xsl:call-template name="comment" />
52
            <xsl:choose>
53
                <xsl:when test="name()='raise' or @target='_internal'">postEvent(</xsl:when>
54
                <xsl:otherwise><xsl:if test="string(@id)!=''">
55
                 _eventSenders["<xsl:value-of select="@id" />"] = </xsl:if>new SCC_EventSender(this,<xsl:if test="string(@delay)=''">0</xsl:if>
56
                    <xsl:value-of select="@delay" />,
57
                            </xsl:otherwise>
58
                    </xsl:choose>
59
                            new QStateMachine::SignalEvent(<xsl:if
60
                        test="string(@target)=''">this</xsl:if><xsl:value-of
61
                        select="@target" />,metaObject()->indexOfSignal(QMetaObject::normalizedSignature("event_<xsl:value-of select="replace(@event,'\.','__')" /><xsl:if test="not(contains(@event,')'))">()</xsl:if>")),QVariantList()<xsl:for-each
62
                        select="s:param"><xsl:text><![CDATA[<<]]></xsl:text> QVariant(<xsl:choose>
63
                          <xsl:when test="string(@expr)!=''"><xsl:value-of select="@expr" /></xsl:when>
64
                          <xsl:when test="string(@name)!=''">get_<xsl:value-of select="@name" />()</xsl:when>
65
                          <xsl:otherwise><xsl:value-of select="text()" /></xsl:otherwise>
66
                        </xsl:choose>)
67
                      </xsl:for-each>)<xsl:if test="name()='raise' or @target='_internal'">,QStateMachine::HighPriority</xsl:if>);
68
</xsl:template>
69
<xsl:template mode="execContext" match="s:cancel">
70
<xsl:call-template name="comment" /><![CDATA[
71
                  {
72
                    QPointer<SCC_EventSender> es = _eventSenders["]]><xsl:value-of select="@id" />"];
73
                    if (es)
74
                      es->cancel();
75
                  }
76
</xsl:template>
77
78
<xsl:template match="/">
79
#ifndef __SMCLASS_<xsl:call-template name="smname" />_H
80
#define __SMCLASS_<xsl:call-template name="smname" />_H
81
#include "QStateMachine"
82
#include "QSignalTransition"
83
#include "QTimer"
84
#include "QMetaMethod"
85
#include "QPointer"
86
#include "QVariant"
87
<xsl:if test="count(//s:final)!=0">
88
89
 #include "QFinalState"
90
</xsl:if>
91
<xsl:if test="count(//s:history)!=0">
92
 #include "QHistoryState"
93
</xsl:if>
94
#include "QHash"
95
#include "QEventTransition"
96
<xsl:if test="count(//s:log)!=0">
97
#include "QDebug"
98
</xsl:if>
99
<xsl:if test="count(//s:transition[string(@Qt:animation)!=''])!=0">
100
#include "QPropertyAnimation"
101
</xsl:if>
102
103
#define In(state) (configuration().contains(state_##state))
104
105
<xsl:value-of select="/s:scxml/Qt:cpp/text()" />
106
107
class SMClass_<xsl:call-template name="smname" />;
108
    <xsl:if test="count(//s:transition[string(@event)='' and string(@cond)=''])!=0">
109
     class SCC_UnconditionalTransition : public QAbstractTransition
110
     {
111
     public:
112
         SCC_UnconditionalTransition(QState* s)
113
             : QAbstractTransition(s) {}
114
     protected:
115
         void onTransition(QEvent *) {}
116
         bool eventTest(QEvent *) { return true; }
117
     };
118
    </xsl:if>
119
    <xsl:if test="count(//s:send[string(@target)!='_internal'])!=0">
120
    <![CDATA[
121
      #define ARG_FROM_VAR(I) \
122
          (acount > I \
123
                ? QGenericArgument(((QStateMachine::SignalEvent*)event)->arguments()[I].typeName(),((QStateMachine::SignalEvent*)event)->arguments()[I].data()) \
124
                : QGenericArgument())
125
                
126
127
      class SCC_EventSender : public QTimer
128
      {
129
          Q_OBJECT
130
          private:
131
            QStateMachine* machine;
132
            QStateMachine::SignalEvent* event;
133
          public:
134
          SCC_EventSender(QStateMachine* m=NULL, int delay=0, QStateMachine::SignalEvent* e=NULL) : QTimer(m), machine(m), event(e)
135
          {
136
            setInterval(delay);
137
            setSingleShot(true);
138
            connect(this,SIGNAL(timeout()),this,SLOT(send()));
139
            start();
140
          }
141
          public Q_SLOTS:
142
            void cancel() { stop(); deleteLater(); }
143
            void send() { 
144
              QVariantList args = event->arguments();
145
              int acount = args.count();
146
              event->sender()->metaObject()->method(event->signalIndex()).invoke(event->sender(),
147
                          ARG_FROM_VAR(0),ARG_FROM_VAR(1),ARG_FROM_VAR(2),ARG_FROM_VAR(3),ARG_FROM_VAR(4),
148
                          ARG_FROM_VAR(5),ARG_FROM_VAR(6),ARG_FROM_VAR(7),ARG_FROM_VAR(8),ARG_FROM_VAR(9));
149
              deleteLater();
150
            }
151
      };
152
    ]]></xsl:if>
153
    <xsl:if test="count(//s:transition[string(@cond) != '' or @event='*']) !=0">
154
namespace {
155
    <xsl:for-each select="//s:transition[string(@cond) != '' or @event='*']">
156
          <xsl:call-template name="comment" />
157
        class Transition_<xsl:value-of select="generate-id()" /> : public QSignalTransition
158
        {
159
            SMClass_<xsl:call-template name="smname" />* stateMachine;
160
            public:
161
                Transition_<xsl:value-of select="generate-id()" />(QState* parent)
162
                    : QSignalTransition(parent->machine(),<xsl:choose><xsl:when test="@event='*'">SIGNAL(destroyed())</xsl:when><xsl:otherwise>SIGNAL(event_<xsl:value-of select="@event" />)</xsl:otherwise></xsl:choose>,parent)
163
                      ,stateMachine((SMClass_<xsl:call-template name="smname" />*)parent->machine())
164
                {
165
                }
166
167
            protected:
168
                bool eventTest(QEvent* e);
169
        };
170
171
    </xsl:for-each>
172
};
173
    </xsl:if>
174
class SMClass_<xsl:call-template name="smname" /> : public QStateMachine
175
{
176
    Q_OBJECT
177
<xsl:for-each select="//s:datamodel/s:data">
178
 <xsl:call-template name="comment" />
179
    Q_PROPERTY(<xsl:value-of select="concat(@Qt: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)
180
</xsl:for-each>
181
<xsl:for-each select="//s:transition/Qt:animation">
182
 <xsl:call-template name="comment" />
183
    Q_PROPERTY(QPropertyAnimation* <xsl:value-of select="string()" /> READ anim_<xsl:value-of select="string()" /> WRITE setAnim_<xsl:value-of select="string()" />)
184
</xsl:for-each>
185
186
    public:
187
        SMClass_<xsl:call-template name="smname" />(QObject* o = NULL)
188
            : QStateMachine(o)
189
              {
190
<xsl:for-each select="//s:datamodel/s:data[string-length(concat(string(text()),string(@expr)))!=0]">
191
          <xsl:call-template name="comment" />
192
    <xsl:if test="string(@expr) != ''">
193
            _data.<xsl:value-of select="@id" /> = <xsl:value-of select="@expr"/><xsl:value-of select="text()"/>;
194
    </xsl:if>
195
</xsl:for-each>
196
              }
197
    <xsl:for-each select="//s:state|//s:parallel|//s:initial">
198
          <xsl:call-template name="comment" />
199
        QState* <xsl:apply-templates mode="stateid" select="." />;</xsl:for-each>
200
    <xsl:for-each select="//s:final">
201
          <xsl:call-template name="comment" />
202
        QFinalState* <xsl:apply-templates mode="stateid" select="." />;
203
    </xsl:for-each>
204
    <xsl:for-each select="//s:history">
205
          <xsl:call-template name="comment" />
206
        QHistoryState* <xsl:apply-templates mode="stateid" select="." />;
207
    </xsl:for-each>
208
    <xsl:for-each select="//s:transition[string(@cond) != '']">
209
          <xsl:call-template name="comment" />
210
        inline bool testCondition_<xsl:value-of select="generate-id()" />()
211
        {
212
            return <xsl:if test="string(@cond)=''">true</xsl:if><xsl:value-of select="@cond"/>;
213
        }
214
    </xsl:for-each>
215
    <xsl:for-each select="//s:datamodel/s:data">
216
          <xsl:call-template name="comment" />
217
        <xsl:text>        </xsl:text><xsl:value-of select="@Qt:type" /> get_<xsl:value-of select="@id" />() const
218
        {
219
            return _data.<xsl:value-of select="@id" />;
220
        }
221
    </xsl:for-each>
222
      <xsl:if test="count(//s:datamodel/s:data) != 0"><![CDATA[
223
    protected:
224
        struct {
225
    ]]><xsl:for-each select="//s:datamodel/s:data">
226
          <xsl:call-template name="comment" />
227
            <xsl:text>              </xsl:text><xsl:value-of select="@Qt:type" /><xsl:text> </xsl:text><xsl:value-of select="@id" />;
228
            </xsl:for-each>
229
        } _data;
230
           </xsl:if>
231
        struct {
232
          QString name;
233
          QVariantList data;
234
        } _event;
235
        QString _name;
236
             <xsl:if test="(count(//s:datamodel/s:data)+count(/s:scxml/s:script))!=0">
237
    public Q_SLOTS:
238
</xsl:if>
239
<xsl:for-each select="//s:datamodel/s:data">
240
          <xsl:call-template name="comment" />
241
        void set_<xsl:value-of select="@id" />(<xsl:value-of select="@Qt:type" /> const &amp; value)
242
        {
243
            _data.<xsl:value-of select="@id" /> = value;
244
            emit <xsl:value-of select="@id" />_changed(value);
245
        }
246
    </xsl:for-each>
247
    private Q_SLOTS:
248
#ifndef QT_NO_PROPERTIES
249
        void assignProperties()
250
        {
251
        <xsl:for-each select="//Qt:property">
252
          <xsl:call-template name="comment" />
253
<xsl:text>        </xsl:text><xsl:apply-templates mode="stateid" select=".." />->assignProperty(<xsl:value-of
254
                    select="@object" />,"<xsl:value-of select="@property" />",QVariant(<xsl:value-of select="@value" />));
255
        </xsl:for-each>
256
#endif
257
        }
258
     <xsl:for-each select="//s:transition|//s:onentry|//s:onexit"><xsl:if test="count(*) != 0">
259
          <xsl:for-each select="..|."><xsl:call-template name="comment" /></xsl:for-each>
260
        void exec_<xsl:value-of select="generate-id()" />()
261
        {
262
            <xsl:apply-templates mode="execContext" />
263
        }
264
    </xsl:if></xsl:for-each>
265
   Q_SIGNALS:<xsl:for-each select="distinct-values(//node()[not (starts-with(@event,'done.state.') or @event='*' or contains(@event,':'))]/@event)">
266
        void event_<xsl:value-of select="replace(string(),'\.','__')" /><xsl:if test="not(contains(string(),')'))">()</xsl:if>;</xsl:for-each>
267
    <xsl:for-each select="//s:datamodel/s:data">
268
          <xsl:call-template name="comment" />
269
        void <xsl:value-of select="@id" />_changed(<xsl:value-of select="@Qt:type" /> const &amp;);
270
    </xsl:for-each>
271
      <xsl:text><![CDATA[
272
    protected:
273
    virtual void beginSelectTransitions(QEvent *event)
274
    {
275
        if (event && !event->type() == QEvent::None) {
276
          switch (event->type()) {
277
            case QEvent::StateMachineSignal: {
278
              QStateMachine::SignalEvent* e = (QStateMachine::SignalEvent*)event;
279
              _event.data = e->arguments();
280
              _event.name = e->sender()->metaObject()->method(e->signalIndex()).signature();
281
              if (e->sender() == this)
282
                _event.name = _event.name.mid(6);
283
            } break;
284
            default:
285
            break;
286
          }
287
        } else {
288
          _event.name = "";
289
          _event.data.clear();
290
        }
291
 ]]>        
292
        assignProperties();
293
    }
294
</xsl:text>
295
<xsl:if test="count(//s:send[string(@target)!='internal']) != 0">
296
    private:
297
        <xsl:text><![CDATA[QHash<QString,QPointer<SCC_EventSender> >]]></xsl:text> _eventSenders;
298
</xsl:if>
299
    protected:
300
    public:
301
        void setupStateMachine()
302
        {
303
            _name = "<xsl:call-template name="smname" />";
304
            setObjectName(_name);
305
            <xsl:for-each select="//s:state|//s:parallel|//s:final|//s:history|//s:initial">
306
            <xsl:call-template name="comment" />
307
            <xsl:text>            </xsl:text><xsl:apply-templates mode="stateid" select="." /> = new <xsl:choose>
308
                    <xsl:when test="name()='final'">QFinalState</xsl:when>
309
                    <xsl:when test="name()='history'">QHistoryState</xsl:when>
310
                    <xsl:otherwise>QState</xsl:otherwise>
311
                </xsl:choose>(<xsl:apply-templates mode="stateid" select=".." />);
312
            <xsl:if test="string(@id)!=''"><xsl:apply-templates mode="stateid" select="." />->setObjectName("<xsl:value-of select="@id" />");</xsl:if>
313
            <xsl:if
314
               test="name()='initial' or @id=../@initial">
315
            <xsl:apply-templates mode="stateid" select=".." />->setInitialState(<xsl:apply-templates mode="stateid" select="." />);
316
            </xsl:if>
317
               <xsl:if test="name()='parallel'">
318
                    <xsl:apply-templates mode="stateid" select="." />->setChildMode(ParallelStates);
319
            </xsl:if>
320
               <xsl:if test="name()='history'">
321
             <xsl:apply-templates mode="stateid" select="." />->setHistoryType(QHistoryState::<xsl:choose>
322
                       <xsl:when test="@type='deep'">Deep</xsl:when>
323
                       <xsl:otherwise>Shallow</xsl:otherwise>
324
                       </xsl:choose>History);
325
            </xsl:if>
326
            </xsl:for-each>
327
            QAbstractTransition* transition;<xsl:for-each select="//s:transition[../name()!='history']">
328
          <xsl:call-template name="comment" />
329
            transition = new <xsl:choose>
330
            <xsl:when test="@event='*' or string(@cond)!=''">Transition_<xsl:value-of
331
             select="generate-id()" />(</xsl:when>
332
             <xsl:when test="starts-with(@event,'q-event:')">QEventTransition(<xsl:value-of
333
              select="substring-after(@event,'q-event:')" />,</xsl:when>
334
             <xsl:when test="starts-with(@event,'done.state.')">QSignalTransition(state_<xsl:value-of
335
              select="substring-after(@event,'done.state.')" />,SIGNAL(finished()),</xsl:when>
336
             <xsl:when test="string(@event)!=''">QSignalTransition(this,SIGNAL(event_<xsl:value-of select="replace(@event,'\.','__')" /><xsl:if test="not(ends-with(@event,')'))">()</xsl:if>),</xsl:when>
337
             <xsl:otherwise>SCC_UnconditionalTransition(</xsl:otherwise></xsl:choose><xsl:apply-templates mode="stateid" select=".." />);<xsl:if test="count(*) != 0">
338
            connect(transition,SIGNAL(triggered()),this,SLOT(exec_<xsl:value-of select="generate-id()" />()));</xsl:if>
339
            <xsl:if test="string(@Qt:animation) != ''">
340
            transition->addAnimation(<xsl:value-of select="@Qt:animation" />);</xsl:if><xsl:if
341
                  test="string(@target) != ''"></xsl:if>
342
            <xsl:choose>
343
                <xsl:when test="string(@target)=''" />
344
                <xsl:when test="count(tokenize(@target,'\s+'))=1">
345
            transition->setTargetState(state_<xsl:value-of select="@target" />);</xsl:when>
346
                <xsl:otherwise>(*transition).setTargetStates(QList&lt;QAbstractState*&gt;()<xsl:for-each
347
                    select="tokenize(@target,'\s+')"> &lt;&lt; state_<xsl:value-of select="." /></xsl:for-each>);</xsl:otherwise>
348
            </xsl:choose>
349
            </xsl:for-each>
350
            <xsl:for-each select="//s:history/s:transition">
351
         <xsl:apply-templates mode="stateid" select=".." />->setDefaultState(state_<xsl:value-of select="@target" />);
352
                  </xsl:for-each>
353
            <xsl:for-each select="//s:onentry|//s:onexit"><xsl:if test="count(*) != 0">
354
            connect(<xsl:apply-templates mode="stateid" select=".." />, SIGNAL(<xsl:choose>
355
                   <xsl:when test="name()='onentry'">entered</xsl:when>
356
                   <xsl:when test="name()='onexit'">exited</xsl:when>
357
                </xsl:choose>()),this,SLOT(exec_<xsl:value-of select="generate-id()" />()));</xsl:if></xsl:for-each>
358
            <xsl:value-of select="/s:scxml/s:script/text()" />
359
        }
360
};
361
    <xsl:for-each select="//s:transition[@event='*' or string(@cond) != '']">
362
      <xsl:call-template name="comment" />
363
        bool Transition_<xsl:value-of select="generate-id()" />::eventTest(QEvent* e)
364
        {
365
            return <xsl:choose><xsl:when test="@event!='*'">Q<xsl:if test="string(@event) != ''">Signal</xsl:if>Transition::eventTest(e)
366
            </xsl:when><xsl:otherwise>(*e).type() != QEvent::None</xsl:otherwise></xsl:choose><xsl:if test="string(@cond)!=''">&amp;&amp; stateMachine-&gt;testCondition_<xsl:value-of 
367
                  select="generate-id()" />()</xsl:if>;
368
        }
369
    </xsl:for-each>
370
#endif
371
    </xsl:template>
372
373
</xsl:stylesheet>