Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-30049

QHistoryState does not fully restore configuration when using DeepHistory

    XMLWordPrintable

Details

    Description

      When a transition is taken to a QHistoryState where DeepHistory is used, and the history's recorded state is one or more children deep, the state to become active does not make it's parent states active also. Note that the target state AND the parent state of the history state become active. The issue is if the target state deeper - the target state does not activate it's parent states all the way up the hierarchy.

      Here is a small example (assumes "this" has two signals - gotoOuterState() and returnToHistory())

      QStateMachine *sm = new QStateMachine(this);
      QState *state1 = new QState(sm);
          QState *state2 = new QState(state1);
          QState *state3 = new QState(state2);
          QState *state4 = new QState(state3);
          QState *outerState = new QState(sm);
      
          sm->setInitialState(state1);
          state1->setInitialState(state2);
          state2->setInitialState(state3);
          state3->setInitialState(state4);
      
          QHistoryState *history = new QHistoryState(QHistoryState::DeepHistory, state1);
      
          QAbstractTransition * trans = new QSignalTransition(this, SIGNAL(gotoOuterState()), state1);
          trans->setTargetState(outerState);
      
          state1->addTransition(trans);
      
          QAbstractTransition * trans2 = new QSignalTransition(this, SIGNAL(returnToHistory()), outerState);
          trans2->setTargetState(history);
      
          outerState->addTransition(trans2);
      
          sm->start();
      

      In the example, as the state machine starts, there are four states in the sm->configuration() which is correct since state4 and all its parent states (states 3,2 and 1) are active.
      After emitting "gotoOuterState()" signal and inspecting the sm->configuration() we find only one state in the configuration which again is correct as only outerState is active.
      After emitting "returnToHistory()" signal and inspecting the sm->configuration() again we find only two states in the configuration rather than four. I expect that states1,2,3 and 4 should all be active after the history is taken as a target. Instead, on further investigation, only state1 and state4 is active.

      From http://www.w3.org/TR/scxml/

      Section 3.1.4 Initial, Final, and History States

      paragraph 3:

      Before the state machine exits a compound state, it records the state's active descendants.
      If the 'type' attribute of the <history> state is set to "deep", the state machine saves the state's full active descendant configuration, down to the atomic descendant(s).
      After that, if a transition takes a <history> child of the state as its target, the state machine re-enters not only the parent compound state but also the state(s) in the saved configuration.
      Thus a transition with a deep history state as its target returns to exactly where the state was when it was last exited,
      while a transition with a shallow history state as a target re-enters the previously active child state, but will enter the child's default initial state (if the child is itself compound.)

      It would seem that Qt's implementation of Deep History is incomplete since the restorative behaviour of the configuration on entering a Deep History state is exactly the same as if using Shallow History.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            Unassigned Unassigned
            miketrahearn Mike Trahearn
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes