Add AIStateMachine::yield_if_not

This can be used to switch to a specific engine.
If the state machine is not running in the passed engine,
then it performs a yield to that engine, otherwise it keeps
running. Hence, putting this at the top of a state
guarantees that it runs in that engine.

For example:

    case FrontEnd_done:
    {
      // Unlock must be called by the same thread that locked it.
      if (yield_if_not(&gStateMachineThreadEngine))
      {
        break;
      }
      // Here we are running in gStateMachineThreadEngine.
    ...
This commit is contained in:
Aleric Inglewood
2013-10-15 21:47:14 +02:00
parent 9db6bc0557
commit 9114f04ef6
2 changed files with 11 additions and 0 deletions

View File

@@ -1173,6 +1173,16 @@ void AIStateMachine::yield(AIEngine* engine)
mYieldEngine = engine;
}
bool AIStateMachine::yield_if_not(AIEngine* engine)
{
if (engine && multiplex_state_type_rat(mState)->current_engine != engine)
{
yield(engine);
return true;
}
return false;
}
void AIStateMachine::yield_frame(unsigned int frames)
{
DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::yield_frame(" << frames << ") [" << (void*)this << "]");

View File

@@ -237,6 +237,7 @@ class AIStateMachine : public LLThreadSafeRefCount
void yield(AIEngine* engine); // Yield to give CPU to other state machines, but do not go idle. Continue running from engine 'engine'.
void yield_frame(unsigned int frames); // Run from the main-thread engine after at least 'frames' frames have passed.
void yield_ms(unsigned int ms); // Run from the main-thread engine after roughly 'ms' miliseconds have passed.
bool yield_if_not(AIEngine* engine); // Do not really yield, unless the current engine is not 'engine'. Returns true if it switched engine.
public:
// This function can be called from multiplex_imp(), but also by a child state machine and