4444 * <p>When a state machine is created <code>addState</code> is used to build the
4545 * hierarchy and <code>setInitialState</code> is used to identify which of these
4646 * is the initial state. After construction the programmer calls <code>start</code>
47- * which initializes the state machine and calls <code>enter</code> for all of the initial
48- * state's hierarchy, starting at its eldest parent. For example given the simple
49- * state machine below after start is called mP1.enter will have been called and
50- * then mS1.enter.</p>
47+ * which initializes and starts the state machine. The first action the StateMachine
48+ * is to the invoke <code>enter</code> for all of the initial state's hierarchy,
49+ * starting at its eldest parent. The calls to enter will be done in the context
50+ * of the StateMachines Handler not in the context of the call to start and they
51+ * will be invoked before any messages are processed. For example, given the simple
52+ * state machine below mP1.enter will be invoked and then mS1.enter. Finally,
53+ * messages sent to the state machine will be processed by the current state,
54+ * in our simple state machine below that would initially be mS1.processMessage.</p>
5155<code>
5256 mP1
5357 / \
@@ -621,8 +625,8 @@ private static class SmHandler extends Handler {
621625 /** The debug flag */
622626 private boolean mDbg = false ;
623627
624- /** The quit object */
625- private static final Object mQuitObj = new Object ();
628+ /** The SmHandler object, identifies that message is internal */
629+ private static final Object mSmHandlerObj = new Object ();
626630
627631 /** The current message */
628632 private Message mMsg ;
@@ -726,19 +730,18 @@ public final void handleMessage(Message msg) {
726730 /** Save the current message */
727731 mMsg = msg ;
728732
729- /**
730- * Check that construction was completed
731- */
732- if (!mIsConstructionCompleted ) {
733- Log .e (TAG , "The start method not called, ignore msg: " + msg );
734- return ;
733+ if (mIsConstructionCompleted ) {
734+ /** Normal path */
735+ processMsg (msg );
736+ } else if (!mIsConstructionCompleted &&
737+ (mMsg .what == SM_INIT_CMD ) && (mMsg .obj == mSmHandlerObj )) {
738+ /** Initial one time path. */
739+ mIsConstructionCompleted = true ;
740+ invokeEnterMethods (0 );
741+ } else {
742+ throw new RuntimeException ("StateMachine.handleMessage: " +
743+ "The start method not called, received msg: " + msg );
735744 }
736-
737- /**
738- * Process the message abiding by the hierarchical semantics
739- * and perform any requested transitions.
740- */
741- processMsg (msg );
742745 performTransitions ();
743746
744747 if (mDbg ) Log .d (TAG , "handleMessage: X" );
@@ -852,18 +855,8 @@ private final void completeConstruction() {
852855 mTempStateStack = new StateInfo [maxDepth ];
853856 setupInitialStateStack ();
854857
855- /**
856- * Construction is complete call all enter methods
857- * starting at the first entry.
858- */
859- mIsConstructionCompleted = true ;
860- mMsg = obtainMessage (SM_INIT_CMD );
861- invokeEnterMethods (0 );
862-
863- /**
864- * Perform any transitions requested by the enter methods
865- */
866- performTransitions ();
858+ /** Sending SM_INIT_CMD message to invoke enter methods asynchronously */
859+ sendMessageAtFrontOfQueue (obtainMessage (SM_INIT_CMD , mSmHandlerObj ));
867860
868861 if (mDbg ) Log .d (TAG , "completeConstruction: X" );
869862 }
@@ -1103,14 +1096,14 @@ private SmHandler(Looper looper, StateMachine sm) {
11031096
11041097 /** @see StateMachine#setInitialState(State) */
11051098 private final void setInitialState (State initialState ) {
1106- if (mDbg ) Log .d (TAG , "setInitialState: initialState" + initialState .getName ());
1099+ if (mDbg ) Log .d (TAG , "setInitialState: initialState= " + initialState .getName ());
11071100 mInitialState = initialState ;
11081101 }
11091102
11101103 /** @see StateMachine#transitionTo(IState) */
11111104 private final void transitionTo (IState destState ) {
11121105 mDestState = (State ) destState ;
1113- if (mDbg ) Log .d (TAG , "StateMachine. transitionTo EX destState" + mDestState .getName ());
1106+ if (mDbg ) Log .d (TAG , "transitionTo: destState= " + mDestState .getName ());
11141107 }
11151108
11161109 /** @see StateMachine#deferMessage(Message) */
@@ -1127,12 +1120,12 @@ private final void deferMessage(Message msg) {
11271120 /** @see StateMachine#deferMessage(Message) */
11281121 private final void quit () {
11291122 if (mDbg ) Log .d (TAG , "quit:" );
1130- sendMessage (obtainMessage (SM_QUIT_CMD , mQuitObj ));
1123+ sendMessage (obtainMessage (SM_QUIT_CMD , mSmHandlerObj ));
11311124 }
11321125
11331126 /** @see StateMachine#isQuit(Message) */
11341127 private final boolean isQuit (Message msg ) {
1135- return (msg .what == SM_QUIT_CMD ) && (msg .obj == mQuitObj );
1128+ return (msg .what == SM_QUIT_CMD ) && (msg .obj == mSmHandlerObj );
11361129 }
11371130
11381131 /** @see StateMachine#isDbg() */
0 commit comments