summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-08-04 08:33:52 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-08-04 09:02:17 (GMT)
commit4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1 (patch)
treeb34985c5716d98f01b9f36fd4a98f2ac9710099f /src/corelib/statemachine
parenta0df97c03f26a38af17a42fb44ad6910536c8857 (diff)
parent2076f150995e541308b1d8da936b3e12ab68b886 (diff)
downloadQt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.zip
Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.gz
Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: config.tests/unix/openssl/openssl.pri demos/embedded/embedded.pro examples/itemviews/chart/chart.pro examples/network/network.pro examples/painting/painterpaths/painterpaths.pro examples/threads/mandelbrot/mandelbrot.pro qmake/project.cpp src/3rdparty/libtiff/libtiff/tif_config.h src/corelib/arch/arch.pri src/corelib/global/qglobal.cpp src/corelib/kernel/kernel.pri src/corelib/kernel/qcore_unix_p.h src/corelib/kernel/qobject.cpp src/corelib/thread/qthread_unix.cpp src/corelib/tools/qsharedpointer_impl.h src/corelib/tools/tools.pri src/gui/kernel/qaction.h src/gui/kernel/qapplication.cpp src/gui/painting/qregion.h src/gui/widgets/qlineedit.cpp src/gui/widgets/qlineedit_p.h src/network/socket/qnativesocketengine_unix.cpp tests/auto/qdir/tst_qdir.cpp tests/auto/qdiriterator/tst_qdiriterator.cpp tests/auto/qhttp/qhttp.pro tests/auto/qline/qline.pro tests/auto/qnetworkreply/tst_qnetworkreply.cpp tests/auto/qresourceengine/qresourceengine.pro tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qstring/qstring.pro tests/auto/qtcpsocket/qtcpsocket.pro tests/auto/qtcpsocket/tst_qtcpsocket.cpp
Diffstat (limited to 'src/corelib/statemachine')
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp22
-rw-r--r--src/corelib/statemachine/qabstracttransition.h3
-rw-r--r--src/corelib/statemachine/qeventtransition.cpp30
-rw-r--r--src/corelib/statemachine/qeventtransition.h5
-rw-r--r--src/corelib/statemachine/qsignalevent.h6
-rw-r--r--src/corelib/statemachine/qsignaltransition.cpp15
-rw-r--r--src/corelib/statemachine/qsignaltransition.h3
-rw-r--r--src/corelib/statemachine/qstate.cpp6
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp104
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h12
10 files changed, 111 insertions, 95 deletions
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index 0004d3e..3248dcf 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -153,34 +153,12 @@ QAbstractTransition::QAbstractTransition(QState *sourceState)
}
/*!
- Constructs a new QAbstractTransition object with the given \a targets and \a
- sourceState.
-*/
-QAbstractTransition::QAbstractTransition(const QList<QAbstractState*> &targets,
- QState *sourceState)
- : QObject(*new QAbstractTransitionPrivate, sourceState)
-{
- setTargetStates(targets);
-}
-
-/*!
- \internal
-*/
-QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd,
- QState *parent)
- : QObject(dd, parent)
-{
-}
-
-/*!
\internal
*/
QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd,
- const QList<QAbstractState*> &targets,
QState *parent)
: QObject(dd, parent)
{
- setTargetStates(targets);
}
/*!
diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h
index 9ba1f11..8ff3a6e 100644
--- a/src/corelib/statemachine/qabstracttransition.h
+++ b/src/corelib/statemachine/qabstracttransition.h
@@ -72,7 +72,6 @@ class Q_CORE_EXPORT QAbstractTransition : public QObject
Q_PROPERTY(QList<QAbstractState*> targetStates READ targetStates WRITE setTargetStates)
public:
QAbstractTransition(QState *sourceState = 0);
- QAbstractTransition(const QList<QAbstractState*> &targets, QState *sourceState = 0);
virtual ~QAbstractTransition();
QState *sourceState() const;
@@ -104,8 +103,6 @@ protected:
protected:
QAbstractTransition(QAbstractTransitionPrivate &dd, QState *parent);
- QAbstractTransition(QAbstractTransitionPrivate &dd,
- const QList<QAbstractState*> &targets, QState *parent);
private:
Q_DISABLE_COPY(QAbstractTransition)
diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp
index 3933981..813c960 100644
--- a/src/corelib/statemachine/qeventtransition.cpp
+++ b/src/corelib/statemachine/qeventtransition.cpp
@@ -153,22 +153,6 @@ QEventTransition::QEventTransition(QObject *object, QEvent::Type type,
}
/*!
- Constructs a new QEventTransition object associated with events of the given
- \a type for the given \a object. The transition has the given \a targets and
- \a sourceState.
-*/
-QEventTransition::QEventTransition(QObject *object, QEvent::Type type,
- const QList<QAbstractState*> &targets,
- QState *sourceState)
- : QAbstractTransition(*new QEventTransitionPrivate, targets, sourceState)
-{
- Q_D(QEventTransition);
- d->registered = false;
- d->object = object;
- d->eventType = type;
-}
-
-/*!
\internal
*/
QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QState *parent)
@@ -190,20 +174,6 @@ QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object,
}
/*!
- \internal
-*/
-QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object,
- QEvent::Type type, const QList<QAbstractState*> &targets,
- QState *parent)
- : QAbstractTransition(dd, targets, parent)
-{
- Q_D(QEventTransition);
- d->registered = false;
- d->object = object;
- d->eventType = type;
-}
-
-/*!
Destroys this QObject event transition.
*/
QEventTransition::~QEventTransition()
diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h
index b05ffef..0ebca19 100644
--- a/src/corelib/statemachine/qeventtransition.h
+++ b/src/corelib/statemachine/qeventtransition.h
@@ -62,8 +62,6 @@ class Q_CORE_EXPORT QEventTransition : public QAbstractTransition
public:
QEventTransition(QState *sourceState = 0);
QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0);
- QEventTransition(QObject *object, QEvent::Type type,
- const QList<QAbstractState*> &targets, QState *sourceState = 0);
~QEventTransition();
QObject *eventObject() const;
@@ -82,9 +80,6 @@ protected:
QEventTransition(QEventTransitionPrivate &dd, QState *parent);
QEventTransition(QEventTransitionPrivate &dd, QObject *object,
QEvent::Type type, QState *parent);
- QEventTransition(QEventTransitionPrivate &dd, QObject *object,
- QEvent::Type type, const QList<QAbstractState*> &targets,
- QState *parent);
private:
Q_DISABLE_COPY(QEventTransition)
diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h
index c09c5a3..b7ca61f 100644
--- a/src/corelib/statemachine/qsignalevent.h
+++ b/src/corelib/statemachine/qsignalevent.h
@@ -58,16 +58,16 @@ QT_MODULE(Core)
class Q_CORE_EXPORT QSignalEvent : public QEvent
{
public:
- QSignalEvent(const QObject *sender, int signalIndex,
+ QSignalEvent(QObject *sender, int signalIndex,
const QList<QVariant> &arguments);
~QSignalEvent();
- inline const QObject *sender() const { return m_sender; }
+ inline QObject *sender() const { return m_sender; }
inline int signalIndex() const { return m_signalIndex; }
inline QList<QVariant> arguments() const { return m_arguments; }
private:
- const QObject *m_sender;
+ QObject *m_sender;
int m_signalIndex;
QList<QVariant> m_arguments;
};
diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp
index 389e513..7814699 100644
--- a/src/corelib/statemachine/qsignaltransition.cpp
+++ b/src/corelib/statemachine/qsignaltransition.cpp
@@ -159,21 +159,6 @@ QSignalTransition::QSignalTransition(QObject *sender, const char *signal,
}
/*!
- Constructs a new signal transition associated with the given \a signal of
- the given \a sender. The transition has the given \a targets and \a
- sourceState.
-*/
-QSignalTransition::QSignalTransition(QObject *sender, const char *signal,
- const QList<QAbstractState*> &targets,
- QState *sourceState)
- : QAbstractTransition(*new QSignalTransitionPrivate, targets, sourceState)
-{
- Q_D(QSignalTransition);
- d->sender = sender;
- d->signal = signal;
-}
-
-/*!
Destroys this signal transition.
*/
QSignalTransition::~QSignalTransition()
diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h
index 69060ae..415751e 100644
--- a/src/corelib/statemachine/qsignaltransition.h
+++ b/src/corelib/statemachine/qsignaltransition.h
@@ -62,9 +62,6 @@ public:
QSignalTransition(QState *sourceState = 0);
QSignalTransition(QObject *sender, const char *signal,
QState *sourceState = 0);
- QSignalTransition(QObject *sender, const char *signal,
- const QList<QAbstractState*> &targets,
- QState *sourceState = 0);
~QSignalTransition();
QObject *senderObject() const;
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index 2042288..09d0be0 100644
--- a/src/corelib/statemachine/qstate.cpp
+++ b/src/corelib/statemachine/qstate.cpp
@@ -339,7 +339,8 @@ QSignalTransition *QState::addTransition(QObject *sender, const char *signal,
return 0;
}
}
- QSignalTransition *trans = new QSignalTransition(sender, signal, QList<QAbstractState*>() << target);
+ QSignalTransition *trans = new QSignalTransition(sender, signal);
+ trans->setTargetState(target);
addTransition(trans);
return trans;
}
@@ -351,7 +352,8 @@ class UnconditionalTransition : public QAbstractTransition
{
public:
UnconditionalTransition(QAbstractState *target)
- : QAbstractTransition(QList<QAbstractState*>() << target) {}
+ : QAbstractTransition()
+ { setTargetState(target); }
protected:
void onTransition(QEvent *) {}
bool eventTest(QEvent *) { return true; }
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 1780d90..932a239 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -205,6 +205,7 @@ This is
QStateMachinePrivate::QStateMachinePrivate()
{
state = NotRunning;
+ _startState = 0;
processing = false;
processingScheduled = false;
stop = false;
@@ -1138,7 +1139,8 @@ class InitialTransition : public QAbstractTransition
{
public:
InitialTransition(QAbstractState *target)
- : QAbstractTransition(QList<QAbstractState*>() << target) {}
+ : QAbstractTransition()
+ { setTargetState(target); }
protected:
virtual bool eventTest(QEvent *) { return true; }
virtual void onTransition(QEvent *) {}
@@ -1146,6 +1148,20 @@ protected:
} // namespace
+QState *QStateMachinePrivate::startState()
+{
+ Q_Q(QStateMachine);
+ if (_startState == 0)
+ _startState = new StartState(q);
+ return _startState;
+}
+
+void QStateMachinePrivate::removeStartState()
+{
+ delete _startState;
+ _startState = 0;
+}
+
void QStateMachinePrivate::_q_start()
{
Q_Q(QStateMachine);
@@ -1165,11 +1181,19 @@ void QStateMachinePrivate::_q_start()
processingScheduled = true; // we call _q_process() below
emit q->started();
- StartState *start = new StartState(rootState());
- QAbstractTransition *initialTransition = new InitialTransition(initial);
- start->addTransition(initialTransition);
- QList<QAbstractTransition*> transitions;
- transitions.append(initialTransition);
+ QState *start = startState();
+ Q_ASSERT(start != 0);
+
+ QList<QAbstractTransition*> transitions = QStatePrivate::get(start)->transitions();
+
+ // If a transition has already been added, then we skip this step, as the
+ // initial transition in that case has been overridden.
+ if (transitions.isEmpty()) {
+ QAbstractTransition *initialTransition = new InitialTransition(initial);
+ start->addTransition(initialTransition);
+ transitions.append(initialTransition);
+ }
+
QEvent nullEvent(QEvent::None);
executeTransitionContent(&nullEvent, transitions);
QList<QAbstractState*> enteredStates = enterStates(&nullEvent, transitions);
@@ -1177,7 +1201,7 @@ void QStateMachinePrivate::_q_start()
applyProperties(transitions, QList<QAbstractState*>() << start,
enteredStates);
#endif
- delete start;
+ removeStartState();
#ifdef QSTATEMACHINE_DEBUG
qDebug() << q << ": initial configuration:" << configuration;
@@ -1277,6 +1301,68 @@ void QStateMachinePrivate::scheduleProcess()
QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection);
}
+namespace {
+
+class GoToStateTransition : public QAbstractTransition
+{
+public:
+ GoToStateTransition(QAbstractState *target)
+ : QAbstractTransition()
+ { setTargetState(target); }
+protected:
+ void onTransition(QEvent *) { deleteLater(); }
+ bool eventTest(QEvent *) { return true; }
+};
+
+} // namespace
+
+/*!
+ \internal
+
+ Causes this state machine to unconditionally transition to the given
+ \a targetState.
+
+ Provides a backdoor for using the state machine "imperatively"; i.e. rather
+ than defining explicit transitions, you drive the machine's execution by
+ calling this function. It breaks the whole integrity of the
+ transition-driven model, but is provided for pragmatic reasons.
+*/
+void QStateMachinePrivate::goToState(QAbstractState *targetState)
+{
+ if (!targetState) {
+ qWarning("QStateMachine::goToState(): cannot go to null state");
+ return;
+ }
+
+ if (configuration.contains(targetState))
+ return;
+
+ QState *sourceState = 0;
+ if (state == Running) {
+ QSet<QAbstractState*>::const_iterator it;
+ for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) {
+ sourceState = qobject_cast<QState*>(*it);
+ if (sourceState != 0)
+ break;
+ }
+ } else {
+ sourceState = startState();
+ }
+
+ Q_ASSERT(sourceState != 0);
+ // Reuse previous GoToStateTransition in case of several calls to
+ // goToState() in a row.
+ GoToStateTransition *trans = qFindChild<GoToStateTransition*>(sourceState);
+ if (!trans) {
+ trans = new GoToStateTransition(targetState);
+ sourceState->addTransition(trans);
+ } else {
+ trans->setTargetState(targetState);
+ }
+
+ scheduleProcess();
+}
+
void QStateMachinePrivate::registerTransitions(QAbstractState *state)
{
QState *group = qobject_cast<QState*>(state);
@@ -1446,7 +1532,7 @@ void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transitio
}
#endif
-void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int signalIndex,
+void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalIndex,
void **argv)
{
Q_ASSERT(connections[sender].at(signalIndex) != 0);
@@ -2026,7 +2112,7 @@ QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent)
Constructs a new QSignalEvent object with the given \a sender, \a
signalIndex and \a arguments.
*/
-QSignalEvent::QSignalEvent(const QObject *sender, int signalIndex,
+QSignalEvent::QSignalEvent(QObject *sender, int signalIndex,
const QList<QVariant> &arguments)
: QEvent(QEvent::Signal), m_sender(sender),
m_signalIndex(signalIndex), m_arguments(arguments)
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index cae21aa..f0f74d6 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -79,7 +79,7 @@ class QAbstractAnimation;
#endif
class QStateMachine;
-class QStateMachinePrivate : public QStatePrivate
+class Q_CORE_EXPORT QStateMachinePrivate : public QStatePrivate
{
Q_DECLARE_PUBLIC(QStateMachine)
public:
@@ -116,6 +116,9 @@ public:
QState *rootState() const;
+ QState *startState();
+ void removeStartState();
+
void microstep(QEvent *event, const QList<QAbstractTransition*> &transitionList);
bool isPreempted(const QAbstractState *s, const QSet<QAbstractTransition*> &transitions) const;
QSet<QAbstractTransition*> selectTransitions(QEvent *event) const;
@@ -138,6 +141,8 @@ public:
static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other);
static QList<QState*> properAncestors(const QAbstractState *s, const QState *upperBound);
+ void goToState(QAbstractState *targetState);
+
void registerTransitions(QAbstractState *state);
void registerSignalTransition(QSignalTransition *transition);
void unregisterSignalTransition(QSignalTransition *transition);
@@ -147,7 +152,7 @@ public:
#endif
void unregisterTransition(QAbstractTransition *transition);
void unregisterAllTransitions();
- void handleTransitionSignal(const QObject *sender, int signalIndex,
+ void handleTransitionSignal(QObject *sender, int signalIndex,
void **args);
void scheduleProcess();
@@ -162,6 +167,7 @@ public:
#endif
State state;
+ QState *_startState;
bool processing;
bool processingScheduled;
bool stop;
@@ -208,7 +214,7 @@ public:
f_cloneEvent cloneEvent;
};
- static Q_CORE_EXPORT const Handler *handler;
+ static const Handler *handler;
};
QT_END_NAMESPACE