private FlowRoutine removeAt(int index) { FlowRoutine ret = _array[index]; _count--; if (_count == 0) { return(ret); } var bottom = _array[_count]; bottom.HeapIndex = index; int parentIndex = getParentIndex(index); if (isValidIndex(parentIndex) && _array[parentIndex].HeapValue > bottom.HeapValue) { bubbleUp(bottom); } else { bubbleDown(bottom); } return(ret); }
private void bubbleUp(FlowRoutine element) { while (true) { if (element.HeapIndex == 0) { break; } int parentIndex = getParentIndex(element.HeapIndex); var parent = _array[parentIndex]; if (parent.HeapValue <= element.HeapValue) { break; } parent.HeapIndex = element.HeapIndex; _array[element.HeapIndex] = parent; element.HeapIndex = parentIndex; } _array[element.HeapIndex] = element; }
/// <summary> /// Creates and starts a new Flow Routine that runs the given enumerator. /// </summary> public static void StartNew(IEnumerator <Flow> enumerator) { ensureInstanceExists(); FlowRoutine instance = new FlowRoutine(enumerator); _cachedInstance.stepFlowRoutine(instance); }
private void insertIntoTimeHeap(FlowRoutine instance) { if (!checkNonThreaded(instance)) { return; } FlowHeap heap; switch (instance.State) { case FlowRoutine.FlowRoutineState.Update: heap = _timeUpdateHeap; break; case FlowRoutine.FlowRoutineState.FixedUpdate: heap = _timeFixedUpdateHeap; break; case FlowRoutine.FlowRoutineState.LateUpdate: heap = _timeLateUpdateHeap; break; case FlowRoutine.FlowRoutineState.EndOfFrame: heap = _timeEndOfFrameHeap; break; default: throw new Exception("Unexpected flow state."); } lock (heap) { heap.Insert(instance); } }
private void addIntoQueue(FlowRoutine instance) { if (!checkNonThreaded(instance)) { return; } Queue <FlowRoutine> queue; switch (instance.State) { case FlowRoutine.FlowRoutineState.Update: queue = _intoUpdateQueue; break; case FlowRoutine.FlowRoutineState.FixedUpdate: queue = _intoFixedUpdateQueue; break; case FlowRoutine.FlowRoutineState.LateUpdate: queue = _intoLateUpdateQueue; break; case FlowRoutine.FlowRoutineState.EndOfFrame: queue = _intoEndOfFrameQueue; break; default: throw new Exception("Unexpected flow state."); } lock (queue) { queue.Enqueue(instance); } }
private void bubbleDown(FlowRoutine element) { int elementIndex = element.HeapIndex; float elementValue = element.HeapValue; while (true) { int leftIndex = getChildLeftIndex(elementIndex); int rightIndex = getChildRightIndex(elementIndex); FlowRoutine smallest = element; float smallestValue = elementValue; int smallestIndex = elementIndex; if (isValidIndex(leftIndex)) { var leftChild = _array[leftIndex]; float leftValue = leftChild.HeapValue; if (leftValue < smallestValue) { smallest = leftChild; smallestIndex = leftIndex; smallestValue = leftValue; } } else { break; } if (isValidIndex(rightIndex)) { var rightChild = _array[rightIndex]; float rightValue = rightChild.HeapValue; if (rightValue < smallestValue) { smallest = rightChild; smallestIndex = rightIndex; } } if (smallestIndex == elementIndex) { break; } smallest.HeapIndex = elementIndex; _array[elementIndex] = smallest; elementIndex = smallestIndex; } element.HeapIndex = elementIndex; _array[elementIndex] = element; }
private bool checkNonThreaded(FlowRoutine routine) { if (routine.State == FlowRoutine.FlowRoutineState.Thread) { UnityEngine.Debug.LogError("Cannot use temporal Flow types from within a non-Unity thread! Use one of the Flow.Into values first!"); return(false); } else { return(true); } }
public void Insert(FlowRoutine element) { //if the array isn't big enough, expand it if (_array.Length == _count) { FlowRoutine[] newArray = new FlowRoutine[_array.Length * 2]; Array.Copy(_array, newArray, _array.Length); _array = newArray; } element.HeapIndex = _count; _count++; bubbleUp(element); }
private int getFrame(FlowRoutine instance) { switch (instance.State) { case FlowRoutine.FlowRoutineState.Update: case FlowRoutine.FlowRoutineState.LateUpdate: case FlowRoutine.FlowRoutineState.EndOfFrame: return(Time.frameCount); case FlowRoutine.FlowRoutineState.FixedUpdate: return(_fixedFrameCount); default: throw new Exception(); } }
private float getTime(FlowRoutine instance) { switch (instance.State) { case FlowRoutine.FlowRoutineState.Update: case FlowRoutine.FlowRoutineState.LateUpdate: case FlowRoutine.FlowRoutineState.EndOfFrame: return(Time.time); case FlowRoutine.FlowRoutineState.FixedUpdate: return(Time.fixedTime); default: throw new Exception(); } }
public void Remove(FlowRoutine element) { removeAt(element.HeapIndex); }
private void threadCallback(object context) { FlowRoutine instance = (FlowRoutine)context; stepFlowRoutine(instance); }
private void stepFlowRoutine(FlowRoutine routine) { if (!routine.IsValid) { throw new Exception("Cannot step an invalid flow routine instance!"); } routine.LastYieldTime = _stopwatch.ElapsedTicks; while (routine.MoveNext()) { Flow current = routine.Current; if (current.Type == Flow.CoValueType.WhenElapsed) { if (_stopwatch.ElapsedTicks < routine.LastYieldTime + current.Arg) { continue; } else { addIntoQueue(routine); return; } } switch (current.Type) { case Flow.CoValueType.ForFrames: routine.HeapValue = getFrame(routine) + current.Arg; insertIntoFrameHeap(routine); return; case Flow.CoValueType.ForSeconds: routine.HeapValue = getTime(routine) + current.Arg; insertIntoTimeHeap(routine); return; case Flow.CoValueType.IntoUpdate: lock (_intoUpdateQueue) { _intoUpdateQueue.Enqueue(routine); } return; case Flow.CoValueType.IntoFixedUpdate: lock (_intoFixedUpdateQueue) { _intoFixedUpdateQueue.Enqueue(routine); } return; case Flow.CoValueType.IntoLateUpdate: lock (_intoLateUpdateQueue) { _intoLateUpdateQueue.Enqueue(routine); } return; case Flow.CoValueType.IntoEndOfFrame: lock (_intoLateUpdateQueue) { _intoLateUpdateQueue.Enqueue(routine); } return; case Flow.CoValueType.IntoNewThread: ThreadPool.QueueUserWorkItem(threadCallback, routine); return; case Flow.CoValueType.UntilFrame: routine.HeapValue = current.Arg; insertIntoFrameHeap(routine); return; case Flow.CoValueType.UntilTime: routine.HeapValue = current.Arg; insertIntoTimeHeap(routine); return; default: throw new Exception("Unexpected CoValueType " + current.Type); } } }