summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine/qstatemachine.cpp
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-06-23 09:20:34 (GMT)
committerEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-06-23 09:23:45 (GMT)
commit6769af5510b963e10dc045630e1ab07fd16ba6d1 (patch)
treea421e6f74a6e2f327225ad7177c680cca874d5a2 /src/corelib/statemachine/qstatemachine.cpp
parentce8eaf11405f8acd607f29af5b7daeb57b4abb6d (diff)
downloadQt-6769af5510b963e10dc045630e1ab07fd16ba6d1.zip
Qt-6769af5510b963e10dc045630e1ab07fd16ba6d1.tar.gz
Qt-6769af5510b963e10dc045630e1ab07fd16ba6d1.tar.bz2
Remove default error state
Having an implicit default error state in the graph which the user has not added is unintuitive and ugly. Rather than have a default error state, we stop execution of the machine and print an error message when the machine has run-time errors. If a user wishes to prevent errors from stopping the machine, you can set one or more error states explicitly.
Diffstat (limited to 'src/corelib/statemachine/qstatemachine.cpp')
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp92
1 files changed, 30 insertions, 62 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 682dd97..bf3ee31 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -156,16 +156,14 @@ QT_BEGIN_NAMESPACE
transitions, e.g., \l{QSignalTransition}s as in this example. See
the QState class description for further details.
- If an error is encountered, the machine will enter the
- \l{errorState}{error state}, which is a special state created by
- the machine. The types of errors possible are described by the
+ If an error is encountered, the machine will look for an
+ \l{errorState}{error state}, and if one is available, it will
+ enter this state. The types of errors possible are described by the
\l{QStateMachine::}{Error} enum. After the error state is entered,
the type of the error can be retrieved with error(). The execution
- of the state graph will not stop when the error state is entered.
- So it is possible to handle the error, for instance, by connecting
- to the \l{QAbstractState::}{entered()} signal of the error state.
- It is also possible to set a custom error state with
- setErrorState().
+ of the state graph will not stop when the error state is entered. If
+ no error state applies to the erroneous state, the machine will stop
+ executing and an error message will be printed to the console.
\omit This stuff will be moved elsewhere
This is
@@ -238,7 +236,6 @@ QStateMachinePrivate::QStateMachinePrivate()
error = QStateMachine::NoError;
globalRestorePolicy = QStateMachine::DoNotRestoreProperties;
rootState = 0;
- initialErrorStateForRoot = 0;
signalEventGenerator = 0;
#ifndef QT_NO_ANIMATION
animationsEnabled = true;
@@ -984,27 +981,25 @@ void QStateMachinePrivate::unregisterRestorable(QObject *object, const QByteArra
QAbstractState *QStateMachinePrivate::findErrorState(QAbstractState *context)
{
- // If the user sets the root state's error state to 0, we return the initial error state
- if (context == 0)
- return initialErrorStateForRoot;
-
// Find error state recursively in parent hierarchy if not set explicitly for context state
QAbstractState *errorState = 0;
-
- QState *s = qobject_cast<QState*>(context);
- if (s)
- errorState = s->errorState();
+ if (context != 0) {
+ QState *s = qobject_cast<QState*>(context);
+ if (s != 0)
+ errorState = s->errorState();
- if (!errorState)
- errorState = findErrorState(context->parentState());
+ if (errorState == 0)
+ errorState = findErrorState(context->parentState());
+ }
return errorState;
}
void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractState *currentContext)
{
+ Q_Q(QStateMachine);
+
error = errorCode;
-
switch (errorCode) {
case QStateMachine::NoInitialStateError:
Q_ASSERT(currentContext != 0);
@@ -1036,16 +1031,19 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
QAbstractState *currentErrorState = findErrorState(currentContext);
// Avoid infinite loop if the error state itself has an error
- if (currentContext == currentErrorState) {
- Q_ASSERT(currentContext != initialErrorStateForRoot); // RootErrorState is broken
- currentErrorState = initialErrorStateForRoot;
- }
+ if (currentContext == currentErrorState)
+ currentErrorState = 0;
- Q_ASSERT(currentErrorState != 0);
Q_ASSERT(currentErrorState != rootState);
-
- QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext);
- addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry);
+
+ if (currentErrorState != 0) {
+ QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext);
+ addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry);
+ } else {
+ qWarning("Unrecoverable error detected in running state machine: %s",
+ qPrintable(errorString));
+ q->stop();
+ }
}
#ifndef QT_NO_ANIMATION
@@ -1148,9 +1146,6 @@ void QStateMachinePrivate::_q_start()
return;
}
QAbstractState *initial = rootState->initialState();
- if (initial == 0)
- setError(QStateMachine::NoInitialStateError, rootState);
-
configuration.clear();
qDeleteAll(internalEventQueue);
internalEventQueue.clear();
@@ -1483,27 +1478,6 @@ QStateMachine::~QStateMachine()
namespace {
-class RootErrorState : public QAbstractState
-{
-public:
- RootErrorState(QState *parent)
- : QAbstractState(parent)
- {
- setObjectName(QString::fromLatin1("DefaultErrorState"));
- }
-
- void onEntry(QEvent *)
- {
- QAbstractStatePrivate *d = QAbstractStatePrivate::get(this);
- QStateMachine *machine = d->machine();
-
- qWarning("Unrecoverable error detected in running state machine: %s",
- qPrintable(machine->errorString()));
- }
-
- void onExit(QEvent *) {}
-};
-
class RootState : public QState
{
public:
@@ -1526,9 +1500,7 @@ QState *QStateMachine::rootState() const
Q_D(const QStateMachine);
if (!d->rootState) {
const_cast<QStateMachinePrivate*>(d)->rootState = new RootState(0);
- const_cast<QStateMachinePrivate*>(d)->initialErrorStateForRoot = new RootErrorState(d->rootState);
d->rootState->setParent(const_cast<QStateMachine*>(this));
- d->rootState->setErrorState(d->initialErrorStateForRoot);
}
return d->rootState;
}
@@ -1552,17 +1524,13 @@ QAbstractState *QStateMachine::errorState() const
If the erroneous state has an error state set, this will be entered by the machine. If no error
state has been set, the state machine will search the parent hierarchy recursively for an
error state. The error state of the root state can thus be seen as a global error state that
- applies for the states for which a more specific error state has not been set.
+ applies for all states for which a more specific error state has not been set.
Before entering the error state, the state machine will set the error code returned by error() and
- error message returned by errorString().
-
- The default error state will print a warning to the console containing the information returned by
- errorString(). By setting a new error state on either the state machine itself, or on specific
- states, you can fine tune error handling in the state machine.
+ error message returned by errorString().
- If the root state's error state is set to 0, or if the error state selected by the machine itself
- contains an error, the default error state will be used.
+ If there is no error state available for the erroneous state, the state machine will print a
+ warning message on the console and stop executing.
\sa QState::setErrorState(), rootState()
*/