summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-07 11:03:59 (GMT)
committerEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-05-07 11:07:59 (GMT)
commitb39781b214e2502e0884bce88aa3ac324f2d0b12 (patch)
treed763aa5bf9b3d291f3d49865f9b5708e3bb02939 /src/corelib/statemachine
parent8da0e32d111bbada65d60fa26e14ca72211517b6 (diff)
downloadQt-b39781b214e2502e0884bce88aa3ac324f2d0b12.zip
Qt-b39781b214e2502e0884bce88aa3ac324f2d0b12.tar.gz
Qt-b39781b214e2502e0884bce88aa3ac324f2d0b12.tar.bz2
Make it impossible to have root state as source or target of transition or as error state
Since the root state has no ancestors, it cannot be source or target in transitions since there will be no LCA for the transition, which is required for the algorithm of enterStates and exitStates. In SCXML the root state cannot be target or source of a transition. By the same logic, it cannot be an error state. The root state will always have a valid machine, since it's added to a machine immediately, which makes this code possible.
Diffstat (limited to 'src/corelib/statemachine')
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp15
-rw-r--r--src/corelib/statemachine/qstate.cpp13
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp2
3 files changed, 26 insertions, 4 deletions
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index 1897aa6..c6a261d 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -180,7 +180,7 @@ QAbstractTransition::QAbstractTransition(const QList<QAbstractState*> &targets,
d_ptr->q_ptr = this;
#endif
Q_D(QAbstractTransition);
- d->targetStates = targets;
+ setTargetStates(targets);
}
/*!
@@ -221,7 +221,7 @@ QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd,
d_ptr->q_ptr = this;
#endif
Q_D(QAbstractTransition);
- d->targetStates = targets;
+ setTargetStates(targets);
}
/*!
@@ -265,7 +265,7 @@ void QAbstractTransition::setTargetState(QAbstractState* target)
if (!target)
d->targetStates.clear();
else
- d->targetStates = QList<QAbstractState*>() << target;
+ setTargetStates(QList<QAbstractState*>() << target);
}
/*!
@@ -284,6 +284,15 @@ QList<QAbstractState*> QAbstractTransition::targetStates() const
void QAbstractTransition::setTargetStates(const QList<QAbstractState*> &targets)
{
Q_D(QAbstractTransition);
+
+ for (int i=0; i<targets.size(); ++i) {
+ QAbstractState *target = targets.at(i);
+ if (target->machine() != 0 && target->machine()->rootState() == target) {
+ qWarning("QAbstractTransition::setTargetStates: root state cannot be target of transition");
+ return;
+ }
+ }
+
d->targetStates = targets;
}
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index 4c9e033..acee27d 100644
--- a/src/corelib/statemachine/qstate.cpp
+++ b/src/corelib/statemachine/qstate.cpp
@@ -280,11 +280,15 @@ QAbstractState *QState::errorState() const
void QState::setErrorState(QAbstractState *state)
{
Q_D(QState);
- if (state != 0 && QAbstractStatePrivate::get(state)->machine() != d->machine()) {
+ if (state != 0 && state->machine() != machine()) {
qWarning("QState::setErrorState: error state cannot belong "
"to a different state machine");
return;
}
+ if (state->machine() != 0 && state->machine()->rootState() == state) {
+ qWarning("QStateMachine::setErrorState: root state cannot be error state");
+ return;
+ }
d->errorState = state;
}
@@ -301,6 +305,13 @@ QAbstractTransition *QState::addTransition(QAbstractTransition *transition)
qWarning("QState::addTransition: cannot add null transition");
return 0;
}
+
+ // machine() will always be non-null for root state
+ if (machine() != 0 && machine()->rootState() == this) {
+ qWarning("QState::addTransition: cannot add transition from root state");
+ return 0;
+ }
+
const QList<QAbstractState*> &targets = QAbstractTransitionPrivate::get(transition)->targetStates;
for (int i = 0; i < targets.size(); ++i) {
QAbstractState *t = targets.at(i);
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 21e564c..110a4f8 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -1011,6 +1011,8 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
}
Q_ASSERT(currentErrorState != 0);
+ Q_ASSERT(currentErrorState != rootState);
+
QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext);
addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry);
}