| 47 | } |
| 48 | |
| 49 | void CStateMachine::Clock() |
| 50 | { |
| 51 | t_sm_state old_state; |
| 52 | t_sm_event event; |
| 53 | bool state_entry; |
| 54 | |
| 55 | old_state = m_state; |
| 56 | |
| 57 | /* Process state change according to event */ |
| 58 | if (!m_queue.empty()) { |
| 59 | event = m_queue.front(); |
| 60 | m_queue.pop(); |
| 61 | } else { |
| 62 | event = 0; |
| 63 | } |
| 64 | |
| 65 | /* State changes can only happen here */ |
| 66 | wxMutexLocker lock(m_stateMutex); |
| 67 | m_state = next_state( event ); |
| 68 | |
| 69 | ++m_clockCounter; |
| 70 | state_entry = ( m_state != old_state ) || ( m_clockCounter == 1 ); |
| 71 | if( state_entry ) |
| 72 | { |
| 73 | m_clocksInCurrentState = 0; |
| 74 | // Uncomment here to debug the state machine. |
| 75 | // State changes will be printed to stdout. |
| 76 | //printf("%s(%04d): %d -> %d\n", (const char *)unicode2char(m_name), m_clockCounter, old_state, m_state); |
| 77 | } |
| 78 | ++m_clocksInCurrentState; |
| 79 | |
| 80 | /* Process new state entry */ |
| 81 | if( m_state < m_maxStates ) |
| 82 | { |
| 83 | /* It should be ok to call Clock() recursively inside this |
| 84 | * procedure because state change has already happened. Also |
| 85 | * the m_state mutex is recursive. */ |
| 86 | process_state(m_state, state_entry); |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | /* In multithreaded implementations, this must be locked */ |
| 91 | void CStateMachine::Schedule(t_sm_event event) |