From 24b3d82efff7709073bb74e1420d16a8b7312997 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 30 Mar 2015 11:30:47 +0200 Subject: QStateMachine: move QState::finished() emision into method. By moving the code for QState::finished() emission into a virtual method which also receives the QFinalState that caused the emission, subclasses can hook in and do some extra processing. Change-Id: Id19947c09e196a0df4edb87d71b74b0600c78867 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine_p.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib/statemachine/qstatemachine_p.h') diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 3a93c47c5b..1c885d1a36 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -188,6 +188,8 @@ public: void processEvents(EventProcessingMode processingMode); void cancelAllDelayedEvents(); + virtual void emitStateFinished(QState *forState, QFinalState *guiltyState); + #ifndef QT_NO_PROPERTIES class RestorableId { QPointer guard; -- cgit v1.2.3 From ab8d20532039674ac749186c1773bc0d33cf19cf Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 16 Mar 2015 11:20:55 +0100 Subject: QStateMachine: move methods out of Private class. Also rename them to match the names in the scxml standard, and add the relevant description from the standard to the methods. Change-Id: I495832358f5836ed6ea04bf43061d42e29f4f743 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine_p.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/corelib/statemachine/qstatemachine_p.h') diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 1c885d1a36..d0cc56bc2a 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -156,8 +156,6 @@ public: static bool isParallel(const QAbstractState *s); bool isCompound(const QAbstractState *s) const; bool isAtomic(const QAbstractState *s) const; - static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other); - static QList properAncestors(const QAbstractState *s, const QState *upperBound); void goToState(QAbstractState *targetState); -- cgit v1.2.3 From e616bd2641b9cf6a18cabeae3f9c425f91bfc4b3 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 17 Mar 2015 13:23:51 +0100 Subject: QStateMachine: fix history state restoration. When a history state is entered that has an actual saved history (so not the initial state), the entry set was calculated wrongly in some cases. See the bug report for the specific case. The fix is to fully implement the standard, so method names in the private class are updated to reflect the names as used in the standard. Note that, as mentioned in the bug report, the algorithm as described in http://www.w3.org/TR/2014/WD-scxml-20140529/ has a bug. What is implemented is the fixed algorithm as described in the current working draft as of Friday March 13, 2015. This draft can be found at: http://www.w3.org/Voice/2013/scxml-irp/SCXML.htm [ChangeLog][QtCore] Fixed an issue where a history state restore would activate too many states, possibly putting the state machine in an invalid state. Change-Id: Ibb5491b2fdcf3a167c223fa8c9c4aad302dbb795 Task-number: QTBUG-44963 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine_p.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/corelib/statemachine/qstatemachine_p.h') diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index d0cc56bc2a..a8f0745730 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -100,7 +100,8 @@ public: static QStateMachinePrivate *get(QStateMachine *q); - QState *findLCA(const QList &states) const; + QState *findLCA(const QList &states, bool onlyCompound = false) const; + QState *findLCCA(const QList &states) const; static bool stateEntryLessThan(QAbstractState *s1, QAbstractState *s2); static bool stateExitLessThan(QAbstractState *s1, QAbstractState *s2); @@ -137,12 +138,17 @@ public: , const QList &selectedAnimations #endif ); - QList computeStatesToEnter(const QList &enabledTransitions, - QSet &statesForDefaultEntry); + QList computeEntrySet(const QList &enabledTransitions, + QSet &statesForDefaultEntry); + QAbstractState *getTransitionDomain(QAbstractTransition *t, + const QList &effectiveTargetStates); + void addDescendantStatesToEnter(QAbstractState *state, + QSet &statesToEnter, + QSet &statesForDefaultEntry); void addStatesToEnter(QAbstractState *s, QState *root, QSet &statesToEnter, QSet &statesForDefaultEntry); - void addAncestorStatesToEnter(QAbstractState *s, QState *root, + void addAncestorStatesToEnter(QAbstractState *s, QAbstractState *ancestor, QSet &statesToEnter, QSet &statesForDefaultEntry); -- cgit v1.2.3 From b2f6406b6f3c6374df2751a4669fbe51f04d09e7 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 18 Mar 2015 12:44:22 +0100 Subject: QStateMachine: remove conflicting transitions after selection. After selecting all (enabled) transitions for a microstep, filter out any conflicting transition. The actual conflict resulution is done by ordering the transitions in order of the states that selected them. For example: if an event would trigger two transitions in a parallel state where one would exit that state and the other would not, this filtering prevents the state machine from selecting both states (as this case is an invalid state of the whole machine). This also fixes the exit set calculation for parallel states when one of its substates is exited and subsequently re-entered in the same transition. Previously, the parallel state was not exited, and subsequent re-entry was ignored (because it was still active). Now it is correctly exited and re-entered. A side-effect of the transition ordering mentioned above is it also fixes the non-deterministic behavior of which of the conflicting transitions is taken. [ChangeLog][QtCore] Fixed an issue where the state machine could end up in an invalid state when transitions from a parallel state were not checked for conflicts. [ChangeLog][QtCore] Fixed a case where a parallel state was not exited and re-entered when one of its substates was exited and subsequently re-entered. [ChangeLog][QtCore] Fixed the non-deterministic behavior of picking a transition from a set of conflicting transitions. Task-number: QTBUG-44783 Change-Id: I2ee72b6a2f552077bfa7aa4d369474ab62f4c2f0 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Kevin Funk --- src/corelib/statemachine/qstatemachine_p.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/corelib/statemachine/qstatemachine_p.h') diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index a8f0745730..a88f95f1f5 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -103,6 +103,7 @@ public: QState *findLCA(const QList &states, bool onlyCompound = false) const; QState *findLCCA(const QList &states) const; + static bool transitionStateEntryLessThan(QAbstractTransition *t1, QAbstractTransition *t2); static bool stateEntryLessThan(QAbstractState *s1, QAbstractState *s2); static bool stateExitLessThan(QAbstractState *s1, QAbstractState *s2); @@ -123,12 +124,13 @@ public: void clearHistory(); QAbstractTransition *createInitialTransition() const; + void removeConflictingTransitions(QList &enabledTransitions); void microstep(QEvent *event, const QList &transitionList); - bool isPreempted(const QAbstractState *s, const QSet &transitions) const; - QSet selectTransitions(QEvent *event) const; + QList selectTransitions(QEvent *event); void exitStates(QEvent *event, const QList &statesToExit_sorted, const QHash > &assignmentsForEnteredStates); - QList computeStatesToExit(const QList &enabledTransitions); + QList computeExitSet(const QList &enabledTransitions); + QSet computeExitSet_Unordered(const QList &enabledTransitions); void executeTransitionContent(QEvent *event, const QList &transitionList); void enterStates(QEvent *event, const QList &exitedStates_sorted, const QList &statesToEnter_sorted, @@ -141,7 +143,7 @@ public: QList computeEntrySet(const QList &enabledTransitions, QSet &statesForDefaultEntry); QAbstractState *getTransitionDomain(QAbstractTransition *t, - const QList &effectiveTargetStates); + const QList &effectiveTargetStates) const; void addDescendantStatesToEnter(QAbstractState *state, QSet &statesToEnter, QSet &statesForDefaultEntry); -- cgit v1.2.3