public PriorityListElement Add(Action call, int priority = Priorities.PRIORITY_DEFAULT) { if (!injected) { Kernel.Instance.Inject(this); injected = true; } // get a priority-list element from the pool PriorityListElement priorityListElem = PriorityListElement.Pool.Spawn(); // set the data priorityListElem.call = executionWrapper.Wrap(call); priorityListElem.priority = priority; elemCache.Add(priorityListElem); isDirty = true; return(priorityListElem); }
public PriorityListElement Add(IObservable <bool> call, int priority = Priorities.PRIORITY_DEFAULT) { if (!injected) { Kernel.Instance.Inject(this); injected = true; } if (actionOnly) { Debug.LogError("You tried to add IObservable queue-element to action-only priority-list (prio:" + priority + ") skipping...."); return(null); } // get a priority-list element from the pool PriorityListElement priorityListElem = PriorityListElement.Pool.Spawn(); // set the data priorityListElem.call = call; priorityListElem.priority = priority; elemCache.Add(priorityListElem); isDirty = true; return(priorityListElem); }
public void RemoveQueueElement(PriorityListElement elem) { elemCache.Remove(elem); }
/// <summary> /// Create an IObservable thate executes the logic sorted by priorities. Same priority is called parallel( Observable.Merge) and lower priority is <br/> /// executed later (Observable.Concat of Priority-Blocks) /// </summary> /// <returns></returns> public IObservable <bool> RxExecute() { if (!injected && Kernel.Instance != null) { Kernel.Instance.Inject(this); injected = true; } if (!isDirty || rxCurrent == null) { // no changes => nothing to do! return(rxCurrent); } // process the list sortedList = elemCache.OrderByDescending(elem => elem.priority).ToList(); // let's use the sorted list as next elemCache. (TODO: Not sure about the sort-algorithm, but that might have some inpact) elemCache = new List <PriorityListElement>(sortedList); if (showExecutingElements) { executingElements = new ReactiveCollection <PriorityListElement>(elemCache); } // the last observable of the rx-chain rxCurrent = null; // as long as there are elements in the priority list while (sortedList.Count > 0) { // start with the highest priority of the list int currentPriority = sortedList[0].priority; List <IObservable <bool> > currentList = new List <IObservable <bool> >(); while (sortedList.Count > 0 && currentPriority == sortedList[0].priority) { // use the execution wrapper to add some logic before/after the call or just keep the default wrapper, that // just return the IObservable<bool> itself PriorityListElement currentElem = sortedList[0]; IObservable <bool> execution = currentElem.call .Take(1) // exactly one element is expected and accepted. .Select(result => { if (executingElements != null) { executingElements.Remove(currentElem); } return(result); }); // remove this element from the execution list currentList.Add(execution); sortedList.RemoveAt(0); } if (currentList.Count > 0) { // TODO: recognize what executions did not finish properly (returned false) IObservable <bool> parallelExecution = Observable.Merge(currentList) .Last(); // only propagate element the last element (that means: no matter if the single listElements returned true/false it will go on if (rxCurrent == null) { rxCurrent = parallelExecution; } else { // start with the new execution once all parallel observables are executed rxCurrent = rxCurrent.Concat(parallelExecution); } } } isDirty = false; return(rxCurrent.Last().Finally(() => { if (executingElements != null) { ClearExecutionElements(); } })); }