So I am trying to understand a problem with Qt's QStateMachine and I'm hoping someone can help explain why this is happening. I'm very interested in the fundamental understanding of QStateMachine rather than just the fix.
First consider the state machine with states A, and B and event 1. Event 1 brings you from A to B. A is the initial state.
Specifically this is for maintaining neighbors. In device X I get a message where a neighbor Y says hello. This causes neighbor X to malloc a neighbor state machine for this new neighbor Y. This makes the neighbor state machine and then calls QStateMachine::start( ) ;
Now after this state machine is started I need to continue processing this hello message. So at first I was doing:
QStateMachine::start( ) ;
emit event 1 ;
My understanding is this won't work because start is an async call and so the state machine is not in its initial start until after start is done. That leads me to my first question.
1) So the state machine start gets placed in the qapp event queue but isn't emit an async call as well? Won't the event 1 be placed in the event queue after the start and so wouldn't that mean we will be in the initial state? Or is the emit not an async call?
Thinking this was the problem I changed my code a little by connecting a function to the state machine started signal. I then changed my code to queue up the events if the state machine is not started and I process this queue of pending events (and emit them to the state machine) after the started signal is called.
Well it turns out the initial state is STILL not set when I get started signal. e.g. QStateMachine::configuration( ).contains( initialstate ) == false. This leads me to my second and bigger question.
2) Why when the started signal is emitted am I not in the initial state.
The sequence of events here is:
- Create state machine
- Set initial state
- Start state machine
- Receive event 1
- Since not started queue event 1
- Started signal rxed
- Process event 1
- Since is unknown state do nothing
- Receive event 1
- Process event 1
- Now in state A. transition to state B.
The sequence should be:
- Create state machine
- Set initial state
- Start state machine
- Receive event 1
- Since not started queue event 1
- Started signal rxed
- Process event 1
- Now is state A. transition to state B.
- Receive event 1
- Process event 1
- Now is state B. Do nothing.
Or event better I wish I didn't have to queue the event. I wish I could do this:
- Create state machine
- Set initial state
- Start state machine
- Receive event 1
- Process event 1
- Now is state A. transition to state B.
- Receive event 1
- Process event 1
- Now is state B. Do nothing.