private bool OnMoveNext()
{
// no running for null;
if (_innerRoutine == null)
return false;
// set current to null so that Unity not get same yield value twice;
Current = null;
// loops until the inner routine yield something to Unity;
while (true)
{
// a simple state machine;
switch (_state)
{
// first, goto background;
case RunningState.Init:
GotoState(RunningState.ToBackground);
break;
// running in background, wait a frame;
case RunningState.RunningAsync:
return true;
// runs on main thread;
case RunningState.RunningSync:
MoveNextUnity();
break;
// need switch to background;
case RunningState.ToBackground:
GotoState(RunningState.RunningAsync);
// call the thread launcher;
MoveNextAsync();
return true;
// something was yield returned;
case RunningState.PendingYield:
if (_pendingCurrent == Ninja.JumpBack)
{
// do not break the loop, switch to background;
GotoState(RunningState.ToBackground);
}
else if (_pendingCurrent == Ninja.JumpToUnity)
{
// do not break the loop, switch to main thread;
GotoState(RunningState.RunningSync);
}
else
{
// not from the Ninja, then Unity should get noticed,
// Set to Current property to achieve this;
Current = _pendingCurrent;
// yield from background thread, or main thread?
if (_previousState == RunningState.RunningAsync)
{
// if from background thread,
// go back into background in the next loop;
_pendingCurrent = Ninja.JumpBack;
}
else
{
// otherwise go back to main thread the next loop;
_pendingCurrent = Ninja.JumpToUnity;
}
// end this iteration and Unity get noticed;
return true;
}
break;
// done running, pass false to Unity;
case RunningState.Done:
case RunningState.CancellationRequested:
default:
return false;
}
}
}