Factorial States Example▲
The statechart for calculating the factorial looks as follows:
In other words, the state machine calculates the factorial of 6 and prints the result.
Sélectionnez
class
Factorial : public
QObject
{
Q_OBJECT
Q_PROPERTY(int
x READ x WRITE setX)
Q_PROPERTY(int
fac READ fac WRITE setFac)
public
:
Factorial(QObject *
parent =
0
)
:
QObject(parent), m_x(-
1
), m_fac(1
)
{
}
int
x() const
{
return
m_x;
}
void
setX(int
x)
{
if
(x ==
m_x)
return
;
m_x =
x;
emit xChanged(x);
}
int
fac() const
{
return
m_fac;
}
void
setFac(int
fac)
{
m_fac =
fac;
}
Q_SIGNALS
:
void
xChanged(int
value);
private
:
int
m_x;
int
m_fac;
}
;
The Factorial class is used to hold the data of the computation, x and fac. It also provides a signal that's emitted whenever the value of x changes.
Sélectionnez
class
FactorialLoopTransition : public
QSignalTransition
{
public
:
FactorialLoopTransition(Factorial *
fact)
:
QSignalTransition(fact, SIGNAL(xChanged(int
))), m_fact(fact)
{}
bool
eventTest(QEvent *
e) override
{
if
(!
QSignalTransition::
eventTest(e))
return
false
;
QStateMachine::
SignalEvent *
se =
static_cast
&
lt;QStateMachine::
SignalEvent*&
gt;(e);
return
se-&
gt;arguments().at(0
).toInt() &
gt; 1
;
}
void
onTransition(QEvent *
e) override
{
QStateMachine::
SignalEvent *
se =
static_cast
&
lt;QStateMachine::
SignalEvent*&
gt;(e);
int
x =
se-&
gt;arguments().at(0
).toInt();
int
fac =
m_fact-&
gt;property("fac"
).toInt();
m_fact-&
gt;setProperty("fac"
, x *
fac);
m_fact-&
gt;setProperty("x"
, x -
1
);
}
private
:
Factorial *
m_fact;
}
;
The FactorialLoopTransition class implements the guard (x > 1) and calculations (fac = x * fac; x = x - 1) of the factorial loop.
Sélectionnez
class
FactorialDoneTransition : public
QSignalTransition
{
public
:
FactorialDoneTransition(Factorial *
fact)
:
QSignalTransition(fact, SIGNAL(xChanged(int
))), m_fact(fact)
{}
bool
eventTest(QEvent *
e) override
{
if
(!
QSignalTransition::
eventTest(e))
return
false
;
QStateMachine::
SignalEvent *
se =
static_cast
&
lt;QStateMachine::
SignalEvent*&
gt;(e);
return
se-&
gt;arguments().at(0
).toInt() &
lt;