summaryrefslogtreecommitdiffstats
path: root/src/corelib/statemachine/qstatemachine_p.h
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-07-05 12:55:20 +0200
committerQt by Nokia <qt-info@nokia.com>2012-07-11 05:17:10 +0200
commit035c933eaa54c789d533a16e3c755914f68cc749 (patch)
tree52295a37726b048b9d4e6329e25fd4dd0da7d5dc /src/corelib/statemachine/qstatemachine_p.h
parent016695c7c79b05392daa09c1b9e07417f764e909 (diff)
statemachine: Revamp property assignments implementation
In the old implementation, property assignments (QState::assignProperty()) were "second-class citizens". Assignments were not really integrated into the state machine algorithm, but rather done as a separate step (QStateMachinePrivate::applyProperties()). While that was convenient for SCXML spec transcription purposes, it resulted in some pretty poor semantics on the user side: * Properties were not assigned until _after_ both the QAbstractState::onEntry() function had been called and the QState::entered() signal had been emitted. * Automatic property restoration (QStateMachine::RestoreProperties) did not play nice with nested states (and parallel states, in particular). The proper fix is to refactor the implementation to make property assignments first-class in the core state machine algorithm (QStateMachinePrivate::microstep()). In practice, this meant splitting some steps. Instead of calling exitStates() straight away, we now first only compute the states to exit (without actually exiting them), and use the resulting set to compute which properties are candidates for restoration. Similarly, instead of calling enterStates(), we first only compute the states to enter (without actually entering them), and use the resulting set to compute which properties are assigned by the entered states. With that in place, the rest was a matter of moving the various chunks of the old applyProperties() logic to the place where they belong in the per-state entry/exit. All existing autotests pass. Added several tests that verify the desired semantics in more detail. Task-number: QTBUG-20362 Change-Id: I7d8c7253b66cae87bb0d09aa504303218e230c65 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
Diffstat (limited to 'src/corelib/statemachine/qstatemachine_p.h')
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 1dc5a266f6..2f57f548b2 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -135,11 +135,18 @@ public:
void microstep(QEvent *event, const QList<QAbstractTransition*> &transitionList);
bool isPreempted(const QAbstractState *s, const QSet<QAbstractTransition*> &transitions) const;
QSet<QAbstractTransition*> selectTransitions(QEvent *event) const;
- void exitStates(QEvent *event, const QList<QAbstractState *> &statesToExit_sorted);
+ void exitStates(QEvent *event, const QList<QAbstractState *> &statesToExit_sorted,
+ const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates);
QList<QAbstractState*> computeStatesToExit(const QList<QAbstractTransition*> &enabledTransitions);
void executeTransitionContent(QEvent *event, const QList<QAbstractTransition*> &transitionList);
- void enterStates(QEvent *event, const QList<QAbstractState*> &statesToEnter_sorted,
- const QSet<QAbstractState*> &statesForDefaultEntry);
+ void enterStates(QEvent *event, const QList<QAbstractState*> &exitedStates_sorted,
+ const QList<QAbstractState*> &statesToEnter_sorted,
+ const QSet<QAbstractState*> &statesForDefaultEntry,
+ QHash<QAbstractState *, QList<QPropertyAssignment> > &propertyAssignmentsForState
+#ifndef QT_NO_ANIMATION
+ , const QList<QAbstractAnimation*> &selectedAnimations
+#endif
+ );
QList<QAbstractState*> computeStatesToEnter(const QList<QAbstractTransition*> &enabledTransitions,
QSet<QAbstractState*> &statesForDefaultEntry);
void addStatesToEnter(QAbstractState *s, QState *root,
@@ -184,17 +191,20 @@ public:
void cancelAllDelayedEvents();
#ifndef QT_NO_PROPERTIES
- void applyProperties(const QList<QAbstractTransition*> &transitionList,
- const QList<QAbstractState*> &exitedStates,
- const QList<QAbstractState*> &enteredStates);
-
typedef QPair<QPointer<QObject>, QByteArray> RestorableId;
- QHash<RestorableId, QVariant> registeredRestorables;
- void registerRestorable(QObject *object, const QByteArray &propertyName);
- void unregisterRestorable(QObject *object, const QByteArray &propertyName);
- bool hasRestorable(QObject *object, const QByteArray &propertyName) const;
- QVariant restorableValue(QObject *object, const QByteArray &propertyName) const;
+ QHash<QAbstractState*, QHash<RestorableId, QVariant> > registeredRestorablesForState;
+ bool hasRestorable(QAbstractState *state, QObject *object, const QByteArray &propertyName) const;
+ QVariant savedValueForRestorable(const QList<QAbstractState*> &exitedStates_sorted,
+ QObject *object, const QByteArray &propertyName) const;
+ void registerRestorable(QAbstractState *state, QObject *object, const QByteArray &propertyName,
+ const QVariant &value);
+ void unregisterRestorables(const QList<QAbstractState*> &states, QObject *object,
+ const QByteArray &propertyName);
QList<QPropertyAssignment> restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const;
+ QHash<RestorableId, QVariant> computePendingRestorables(const QList<QAbstractState*> &statesToExit_sorted) const;
+ QHash<QAbstractState*, QList<QPropertyAssignment> > computePropertyAssignments(
+ const QList<QAbstractState*> &statesToEnter_sorted,
+ QHash<RestorableId, QVariant> &pendingRestorables) const;
#endif
State state;
@@ -233,6 +243,11 @@ public:
QMultiHash<QAbstractState *, QAbstractAnimation *> defaultAnimationsForTarget;
QList<QAbstractAnimation *> selectAnimations(const QList<QAbstractTransition *> &transitionList) const;
+ void terminateActiveAnimations(QAbstractState *state,
+ const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates);
+ void initializeAnimations(QAbstractState *state, const QList<QAbstractAnimation*> &selectedAnimations,
+ const QList<QAbstractState *> &exitedStates_sorted,
+ QHash<QAbstractState *, QList<QPropertyAssignment> > &assignmentsForEnteredStates);
#endif // QT_NO_ANIMATION
QSignalEventGenerator *signalEventGenerator;