summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/statemachine')
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp51
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp5
2 files changed, 45 insertions, 11 deletions
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index 5a7a95883b..56f2a15fdb 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -252,26 +252,55 @@ QList<QAbstractState*> QAbstractTransition::targetStates() const
void QAbstractTransition::setTargetStates(const QList<QAbstractState*> &targets)
{
Q_D(QAbstractTransition);
- QVector<QPointer<QAbstractState> > copy(d->targetStates);
- bool sameList = true;
+
+ // Verify if any of the new target states is a null-pointer:
for (int i = 0; i < targets.size(); ++i) {
- QAbstractState *target = targets.at(i);
- if (!target) {
+ if (targets.at(i) == Q_NULLPTR) {
qWarning("QAbstractTransition::setTargetStates: target state(s) cannot be null");
return;
+ }
+ }
+
+ // First clean out any target states that got destroyed, but for which we still have a QPointer
+ // around.
+ for (int i = 0; i < d->targetStates.size(); ) {
+ if (d->targetStates.at(i).isNull()) {
+ d->targetStates.remove(i);
} else {
- sameList &= copy.removeOne(target);
+ ++i;
+ }
+ }
+
+ // Easy check: if both lists are empty, we're done.
+ if (targets.isEmpty() && d->targetStates.isEmpty())
+ return;
+
+ bool sameList = true;
+
+ if (targets.size() != d->targetStates.size()) {
+ // If the sizes of the lists are different, we don't need to be smart: they're different. So
+ // we can just set the new list as the targetStates.
+ sameList = false;
+ } else {
+ QVector<QPointer<QAbstractState> > copy(d->targetStates);
+ for (int i = 0; i < targets.size(); ++i) {
+ sameList &= copy.removeOne(targets.at(i));
+ if (!sameList)
+ break; // ok, we now know the lists are not the same, so stop the loop.
}
+
+ sameList &= copy.isEmpty();
}
- sameList &= copy.isEmpty();
+ if (sameList)
+ return;
- d->targetStates.clear();
- for (int i = 0; i < targets.size(); ++i)
- d->targetStates.append(targets.at(i));
+ d->targetStates.resize(targets.size());
+ for (int i = 0; i < targets.size(); ++i) {
+ d->targetStates[i] = targets.at(i);
+ }
- if (!sameList)
- emit targetStatesChanged(QPrivateSignal());
+ emit targetStatesChanged(QPrivateSignal());
}
/*!
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 3ffe191093..31b079af0c 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -406,6 +406,10 @@ QStateMachinePrivate::~QStateMachinePrivate()
{
qDeleteAll(internalEventQueue);
qDeleteAll(externalEventQueue);
+
+ for (QHash<int, DelayedEvent>::const_iterator it = delayedEvents.begin(), eit = delayedEvents.end(); it != eit; ++it) {
+ delete it.value().event;
+ }
}
QState *QStateMachinePrivate::rootState() const
@@ -1944,6 +1948,7 @@ void QStateMachinePrivate::_q_startDelayedEventTimer(int id, int delay)
e.timerId = q->startTimer(delay);
if (!e.timerId) {
qWarning("QStateMachine::postDelayedEvent: failed to start timer (id=%d, delay=%d)", id, delay);
+ delete e.event;
delayedEvents.erase(it);
delayedEventIdFreeList.release(id);
} else {