From f810a0210c0cdd1ba070f16ebebdec1da7c72b50 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 29 Apr 2009 08:25:03 +0200 Subject: make history state constructible Decided in API review. The intention of QHistoryState not being constructible was so that people wouldn't subclass it and reimplement onEntry()/onExit(), thinking that those functions would actually get called (which they won't). However, we recently added the entered() signal to QAbstractState, so people are going to connect to it and ask why they never get the signal for a QHistoryState. We might as well make QHistoryState constructible and just document that it doesn't make sense to subclass it. --- examples/animation/sub-attaq/boat.cpp | 2 +- examples/statemachine/pauseandresume/main.cpp | 2 +- src/corelib/statemachine/qhistorystate.cpp | 64 ++++++++++++++++++++++---- src/corelib/statemachine/qhistorystate.h | 21 ++++++--- src/corelib/statemachine/qhistorystate_p.h | 5 +- src/corelib/statemachine/qstate.cpp | 26 ----------- src/corelib/statemachine/qstate.h | 7 --- src/corelib/statemachine/qstatemachine.cpp | 6 +-- tests/auto/qstatemachine/tst_qstatemachine.cpp | 4 +- 9 files changed, 78 insertions(+), 59 deletions(-) diff --git a/examples/animation/sub-attaq/boat.cpp b/examples/animation/sub-attaq/boat.cpp index 5721485..f01f1bb 100644 --- a/examples/animation/sub-attaq/boat.cpp +++ b/examples/animation/sub-attaq/boat.cpp @@ -200,7 +200,7 @@ Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) stopState->addTransition(downFireMove); //Finally the launch state should come back to its original state - QHistoryState *historyState = moving->addHistoryState(); + QHistoryState *historyState = new QHistoryState(moving); launchStateLeft->addTransition(historyState); launchStateRight->addTransition(historyState); diff --git a/examples/statemachine/pauseandresume/main.cpp b/examples/statemachine/pauseandresume/main.cpp index e0ebbff..5bacb41 100644 --- a/examples/statemachine/pauseandresume/main.cpp +++ b/examples/statemachine/pauseandresume/main.cpp @@ -73,7 +73,7 @@ public: s1->addTransition(pb, SIGNAL(clicked()), s2); s2->addTransition(pb, SIGNAL(clicked()), s1); - QHistoryState *h = process->addHistoryState(); + QHistoryState *h = new QHistoryState(process); h->setDefaultState(s1); QState *interrupted = new QState(machine->rootState()); diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp index 8143d41..4e3db08 100644 --- a/src/corelib/statemachine/qhistorystate.cpp +++ b/src/corelib/statemachine/qhistorystate.cpp @@ -85,17 +85,38 @@ QT_BEGIN_NAMESPACE \endcode */ +/*! + \property QHistoryState::defaultState + + \brief the default state of this history state +*/ + +/*! + \property QHistoryState::historyType + + \brief the type of history that this history state records +*/ + +/*! + \enum QHistoryState::HistoryType + + This enum specifies the type of history that a QHistoryState records. + + \value ShallowHistory Only the immediate child states of the parent state + are recorded. In this case a transition with the history state as its + target will end up in the immediate child state that the parent was in the + last time it was exited. This is the default. + + \value DeepHistory Nested states are recorded. In this case a transition + with the history state as its target will end up in the most deeply nested + descendant state the parent was in the last time it was exited. +*/ + QHistoryStatePrivate::QHistoryStatePrivate() : defaultState(0) { } -QHistoryState *QHistoryStatePrivate::create(QState::HistoryType type, - QState *parent) -{ - return new QHistoryState(type, parent); -} - QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q) { return q->d_func(); @@ -107,12 +128,19 @@ const QHistoryStatePrivate *QHistoryStatePrivate::get(const QHistoryState *q) } /*! - \internal - + Constructs a new shallow history state with the given \a parent state. +*/ +QHistoryState::QHistoryState(QState *parent) + : QAbstractState(*new QHistoryStatePrivate, parent) +{ + Q_D(QHistoryState); + d->historyType = ShallowHistory; +} +/*! Constructs a new history state of the given \a type, with the given \a parent state. */ -QHistoryState::QHistoryState(QState::HistoryType type, QState *parent) +QHistoryState::QHistoryState(HistoryType type, QState *parent) : QAbstractState(*new QHistoryStatePrivate, parent) { Q_D(QHistoryState); @@ -152,6 +180,24 @@ void QHistoryState::setDefaultState(QAbstractState *state) } /*! + Returns the type of history that this history state records. +*/ +QHistoryState::HistoryType QHistoryState::historyType() const +{ + Q_D(const QHistoryState); + return d->historyType; +} + +/*! + Sets the \a type of history that this history state records. +*/ +void QHistoryState::setHistoryType(HistoryType type) +{ + Q_D(QHistoryState); + d->historyType = type; +} + +/*! \reimp */ void QHistoryState::onEntry() diff --git a/src/corelib/statemachine/qhistorystate.h b/src/corelib/statemachine/qhistorystate.h index 9cd7f0b..c7648bc 100644 --- a/src/corelib/statemachine/qhistorystate.h +++ b/src/corelib/statemachine/qhistorystate.h @@ -43,9 +43,9 @@ #define QHISTORYSTATE_H #ifndef QT_STATEMACHINE_SOLUTION -#include +#include #else -#include "qstate.h" +#include "qabstractstate.h" #endif QT_BEGIN_HEADER @@ -58,12 +58,25 @@ class QHistoryStatePrivate; class Q_CORE_EXPORT QHistoryState : public QAbstractState { Q_OBJECT + Q_PROPERTY(QAbstractState* defaultState READ defaultState WRITE setDefaultState) + Q_PROPERTY(HistoryType historyType READ historyType WRITE setHistoryType) + Q_ENUMS(HistoryType) public: + enum HistoryType { + ShallowHistory, + DeepHistory + }; + + QHistoryState(QState *parent = 0); + QHistoryState(HistoryType type, QState *parent = 0); ~QHistoryState(); QAbstractState *defaultState() const; void setDefaultState(QAbstractState *state); + HistoryType historyType() const; + void setHistoryType(HistoryType type); + protected: void onEntry(); void onExit(); @@ -71,10 +84,6 @@ protected: bool event(QEvent *e); private: - QHistoryState(QState::HistoryType type, - QState *parent = 0); - -private: Q_DISABLE_COPY(QHistoryState) Q_DECLARE_PRIVATE(QHistoryState) }; diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h index 84648b5..2f17496 100644 --- a/src/corelib/statemachine/qhistorystate_p.h +++ b/src/corelib/statemachine/qhistorystate_p.h @@ -67,14 +67,11 @@ class QHistoryStatePrivate : public QAbstractStatePrivate public: QHistoryStatePrivate(); - static QHistoryState *create(QState::HistoryType type, - QState *parent); - static QHistoryStatePrivate *get(QHistoryState *q); static const QHistoryStatePrivate *get(const QHistoryState *q); QAbstractState *defaultState; - QState::HistoryType historyType; + QHistoryState::HistoryType historyType; QList configuration; }; diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 5c3418b..dd3af51 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -75,8 +75,6 @@ QT_BEGIN_NAMESPACE and the state machine needs to know which child state to enter when the parent state is the target of a transition. - The addHistoryState() function adds a history state. - The setErrorState() sets the state's error state. The error state is the state that the state machine will transition to if an error is detected when attempting to enter the state (e.g. because no initial state has been set). @@ -95,21 +93,6 @@ QT_BEGIN_NAMESPACE group state is entered, all its child states are entered in parallel. */ -/*! - \enum QState::HistoryType - - This enum specifies the type of history that a QHistoryState records. - - \value ShallowHistory Only the immediate child states of the parent state - are recorded. In this case a transition with the history state as its - target will end up in the immediate child state that the parent was in the - last time it was exited. This is the default. - - \value DeepHistory Nested states are recorded. In this case a transition - with the history state as its target will end up in the most deeply nested - descendant state the parent was in the last time it was exited. -*/ - QStatePrivate::QStatePrivate() : errorState(0), isParallelGroup(false), initialState(0) { @@ -381,15 +364,6 @@ QList QState::transitions() const } /*! - Creates a history state of the given \a type for this state and returns the - new state. The history state becomes a child of this state. -*/ -QHistoryState *QState::addHistoryState(HistoryType type) -{ - return QHistoryStatePrivate::create(type, this); -} - -/*! \reimp */ void QState::onEntry() diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h index 0dd99dc..33f0709 100644 --- a/src/corelib/statemachine/qstate.h +++ b/src/corelib/statemachine/qstate.h @@ -68,11 +68,6 @@ public: ParallelGroup }; - enum HistoryType { - ShallowHistory, - DeepHistory - }; - QState(QState *parent = 0); QState(Type type, QState *parent = 0); ~QState(); @@ -86,8 +81,6 @@ public: void removeTransition(QAbstractTransition *transition); QList transitions() const; - QHistoryState *addHistoryState(HistoryType type = ShallowHistory); - QAbstractState *initialState() const; void setInitialState(QAbstractState *state); diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 8d5317a..1ee526a 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -415,7 +415,7 @@ QList QStateMachinePrivate::exitStates(const QList::const_iterator it; for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { QAbstractState *s0 = *it; - if (QHistoryStatePrivate::get(h)->historyType == QState::DeepHistory) { + if (QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) { if (isAtomic(s0) && isDescendantOf(s0, s)) QHistoryStatePrivate::get(h)->configuration.append(s0); } else if (s0->parentState() == s) { @@ -423,7 +423,7 @@ QList QStateMachinePrivate::exitStates(const QListhistoryType == QState::DeepHistory) ? "deep" : "shallow") + qDebug() << q_func() << ": recorded" << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") << "history for" << s << "in" << h << ":" << QHistoryStatePrivate::get(h)->configuration; #endif } @@ -479,7 +479,7 @@ QList QStateMachinePrivate::enterStates(const QListhistoryType == QState::DeepHistory) ? "deep" : "shallow") + << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") << "history from" << s << ":" << hconf; #endif } else { diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index db25ad5..1c5f52b 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -823,7 +823,7 @@ void tst_QStateMachine::historyStateHasNowhereToGo() brokenState->setObjectName("brokenState"); brokenState->setInitialState(new QState(brokenState)); - QHistoryState *historyState = brokenState->addHistoryState(); + QHistoryState *historyState = new QHistoryState(brokenState); historyState->setObjectName("historyState"); initialState->addTransition(new EventTransition(QEvent::User, historyState)); @@ -1587,7 +1587,7 @@ void tst_QStateMachine::historyStates() QState *s0 = new QState(root); QState *s00 = new QState(s0); QState *s01 = new QState(s0); - QHistoryState *s0h = s0->addHistoryState(); + QHistoryState *s0h = new QHistoryState(s0); QState *s1 = new QState(root); QFinalState *s2 = new QFinalState(root); -- cgit v0.12