| 110 | } |
| 111 | |
| 112 | void Tr2StateMachine::FollowTransitions( uint64_t variableDirtyMask ) |
| 113 | { |
| 114 | auto next = m_currentState->Update( variableDirtyMask ); |
| 115 | if( !next ) |
| 116 | { |
| 117 | return; |
| 118 | } |
| 119 | |
| 120 | std::vector<std::pair<Tr2StateMachineState*, uint32_t>> seen; |
| 121 | |
| 122 | for( uint32_t iteration = 0; next; ++iteration ) |
| 123 | { |
| 124 | if( iteration > 10 ) |
| 125 | { |
| 126 | seen.push_back( std::make_pair( m_currentState, 1u ) ); |
| 127 | |
| 128 | auto found = std::find_if( begin( seen ), end( seen ), [next]( const auto& x ) { |
| 129 | return x.first == next; |
| 130 | } ); |
| 131 | if( found != seen.end() ) |
| 132 | { |
| 133 | ++found->second; |
| 134 | if( found->second > 20 ) |
| 135 | { |
| 136 | CCP_LOGERR( "Tr2StateMachine: infinite loop in state machine %s detected", m_name.c_str() ); |
| 137 | return; |
| 138 | } |
| 139 | } |
| 140 | else |
| 141 | { |
| 142 | seen.push_back( { next, 1u } ); |
| 143 | } |
| 144 | } |
| 145 | m_currentState = next; |
| 146 | m_currentState->Start(); |
| 147 | m_stateStartTime = BeOS->GetCurrentFrameTime(); |
| 148 | |
| 149 | next = m_currentState->Update( 0xffffffffffffffffull ); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | void Tr2StateMachine::Start() |
| 154 | { |