public void DoAIteration(AsyncPattern[] target) { //To prevent secondary sequential children from trying to copy this object's GCX // which will have already changed when the next loop starts. GenCtx base_gcx = looper.GCX.Copy(); bool done = false; Action loop_done = () => { base_gcx.Dispose(); done = true; }; if (waitChild) { checkIsChildDone = () => done; //On the frame that the child finishes, the waitstep will increment elapsedFrames //even though it should not. However, it is difficult to tell the waitstep whether //the child was finished or not finished before that frame. This is the easiest solution. --elapsedFrames; } else { checkIsChildDone = null; } if (looper.props.childSelect == null) { if (sequential) { void DoNext(int ii) { if (ii >= target.Length || looper.Handoff.cT.Cancelled) { loop_done(); } else { DoAIteration(target[ii], () => DoNext(ii + 1), base_gcx); } } DoNext(0); } else { var loop_fragment_done = WaitingUtils.GetManyCallback(target.Length, loop_done); for (int ii = 0; ii < target.Length; ++ii) { DoAIteration(target[ii], loop_fragment_done, base_gcx); } } } else { DoAIteration(target[(int)looper.props.childSelect(looper.GCX) % target.Length], loop_done, base_gcx); } }
public void DoAIteration(ref float elapsedFrames, IReadOnlyList <StateMachine> target) { //See IPExecution tracker for comments on this code GenCtx base_gcx = looper.GCX.Copy(); bool done = false; Action loop_done = () => { base_gcx.Dispose(); done = true; }; if (waitChild) { checkIsChildDone = () => done; --elapsedFrames; } else { checkIsChildDone = null; } if (looper.props.childSelect == null) { if (sequential) { void DoNext(int ii) { if (ii >= target.Count || looper.Handoff.cT.Cancelled) { loop_done(); } else { DoAIteration(target[ii], () => DoNext(ii + 1), base_gcx); } } DoNext(0); } else { var loop_fragment_done = WaitingUtils.GetManyCallback(target.Count, loop_done); for (int ii = 0; ii < target.Count; ++ii) { DoAIteration(target[ii], loop_fragment_done, base_gcx); } } } else { DoAIteration(target[(int)looper.props.childSelect(looper.GCX) % target.Count], loop_done, base_gcx); } }
public void DoLastAIteration(IReadOnlyList <StateMachine> target) { //Unlike GIR, which hoists its cleanup code into a callback, GTR awaits its last child // and calls its cleanup code in Start. //Therefore, this code follows the wait-child pattern. GenCtx base_gcx = looper.GCX.Copy(); bool done = false; checkIsChildDone = () => done; Action loop_done = () => { base_gcx.Dispose(); done = true; //AllDone called by Start code }; if (looper.props.childSelect == null) { if (sequential) { void DoNext(int ii) { if (ii >= target.Count || looper.Handoff.cT.Cancelled) { loop_done(); } else { DoAIteration(target[ii], () => DoNext(ii + 1), base_gcx); } } DoNext(0); } else { var loop_fragment_done = WaitingUtils.GetManyCallback(target.Count, loop_done); for (int ii = 0; ii < target.Count; ++ii) { DoAIteration(target[ii], loop_fragment_done, base_gcx); } } } else { DoAIteration(target[(int)looper.props.childSelect(looper.GCX) % target.Count], loop_done, base_gcx); } }
public void DoLastAIteration(AsyncPattern[] target) { GenCtx base_gcx = looper.GCX.Copy(); Action loop_done = () => { base_gcx.Dispose(); AllADone(); }; if (looper.props.childSelect == null) { if (sequential) { void DoNext(int ii) { if (ii >= target.Length || looper.Handoff.cT.Cancelled) { loop_done(); } else { DoAIteration(target[ii], () => DoNext(ii + 1), base_gcx); } } DoNext(0); } else { var loop_fragment_done = WaitingUtils.GetManyCallback(target.Length, loop_done); for (int ii = 0; ii < target.Length; ++ii) { DoAIteration(target[ii], loop_fragment_done, base_gcx); } } } else { DoAIteration(target[(int)looper.props.childSelect(looper.GCX) % target.Length], loop_done, base_gcx); } }