private void RemoveInternal(T value)
        {
            UnrealBinaryHeapEx <T> collection = GetCollection(value.Owner.Group);

            collection.HeapRemove(value);
            value.comparableCollection = null;
        }
        private void ValueChangedInternal(T value)
        {
            UnrealBinaryHeapEx <T> collection = GetCollection(value.Owner.Group);

            collection.HeapRemove(value);
            collection.HeapPush(value);
        }
示例#3
0
        private void ProcessTime(UnrealBinaryHeapEx <Invoker> invokers)
        {
            // Note: If the the delay is low enough this may loop forever (the timer would need a repeat
            // value lower than the time it takes to get from the end of Process() back to the EndValue check
            // - If this becomes a problem you could stop this from happening by holding onto the last invoker
            //   processed and checking invoker!=lastInvoker
            // - Though if this is a problem it will make the game crawl anyway due to CallCount. A frame will
            //   occasionally get through between the invoker spam if doing the lastInvoker check.

            //Invoker lastInvoker = null;

            while (invokers.Count > 0)
            {
                Invoker invoker = invokers.HeapTop();
                ulong   value   = (ulong)WorldTimeHelper.GetTimeChecked(invoker.OwnerWorld).Ticks;
                if (invoker.EndValue <= value /*&& invoker != lastInvoker*/)
                {
                    invokers.HeapPopDiscard();
                    invoker.Process(value);
                    //lastInvoker = invoker;
                }
                else
                {
                    break;
                }
            }
        }
示例#4
0
        public void Stop()
        {
            if (!Running)
            {
                return;
            }

            if (collection != null)
            {
                collection.HeapRemove(this);
                collection      = null;
                collectionGroup = null;
            }
            IsFirstRun = false;
            Running    = false;
            UpdateTags();

            RemoveInvokerFromInvokersByUObject();
            RemoveInvokerFromInvokersByMethod();

            if (OnStopped != null)
            {
                OnStopped(this);
            }

            if (IsPooled)
            {
                InvokerPool.ReturnObject(this);
            }
        }
示例#5
0
        internal void Process(ulong value)
        {
            cancelInvoke = false;

            int expectedAdditionalCallCount = 0;

            if (IsRepeated)
            {
                expectedAdditionalCallCount = (int)((value - EndValue) / RepeatedValue);
            }
            CallCount = expectedAdditionalCallCount + 1;

            // Clamp the call count to MaxCallCount
            int clampedAdditionalCallCount = expectedAdditionalCallCount;

            if (MaxCallCount > 0)
            {
                clampedAdditionalCallCount = Math.Min(MaxCallCount - 1, clampedAdditionalCallCount);
            }

            // target value may change if IsFirstRun is true
            ulong oldTargetValue = CurrentTargetValue;

            if (!InvokeInternal() || (HasStopAfterValue && HasStopAfterValueCompleted(oldTargetValue, 0)))
            {
                return;
            }

            uint additionalCalls = 0;

            for (; additionalCalls < clampedAdditionalCallCount && !cancelInvoke && Running; ++additionalCalls)
            {
                if (!InvokeInternal() || (HasStopAfterValue && HasStopAfterValueCompleted(oldTargetValue, additionalCalls + 1)))
                {
                    return;
                }
            }

            if (IsRepeated)
            {
                if (RepeatConstantTime && Type == InvokerType.Delay)
                {
                    ulong realTime = (ulong)WorldTimeHelper.GetTimeChecked(OwnerWorld).Ticks;
                    BeginValue = value + (realTime - EndValue);
                }
                else
                {
                    BeginValue += oldTargetValue + (additionalCalls * RepeatedValue);
                }

                collection.HeapPush(this);
            }
            else
            {
                collection      = null;
                collectionGroup = null;
                Stop();
            }
        }
        private bool AddInternal(T value)
        {
            UnrealBinaryHeapEx <T> collection = GetCollection(value.Owner.Group);

            collection.HeapPush(value);
            value.comparableCollection = this;
            return(true);
        }
        private void OnGroupChanged(T instruction, CoroutineGroup oldGroup, CoroutineGroup newGroup)
        {
            UnrealBinaryHeapEx <T> oldCollection = GetCollection(oldGroup);
            UnrealBinaryHeapEx <T> newCollection = GetCollection(newGroup);

            if (oldCollection != null && newCollection != null && oldCollection != newCollection)
            {
                oldCollection.HeapRemove(instruction);
                newCollection.HeapPush(instruction);
            }
        }
示例#8
0
        internal void Reset()
        {
            // There is a lot going on here. We probably don't need to reset everything.

            OnStopped = null;

            Running    = false;
            IsFirstRun = false;
            Tag        = null;
            TagId      = 0;

            OwnerWorld = IntPtr.Zero;
            Owner      = null;
            IsRepeated = false;
            Type       = default(InvokerType);
            Group      = default(CoroutineGroup);

            Value         = 0;
            RepeatedValue = 0;

            HasStopAfterValue = false;
            stopAfterValue    = 0;
            stopAfterEndValue = 0;

            startingValue = 0;
            beginValue    = 0;
            EndValue      = 0;

            RepeatConstantTime = false;
            MaxCallCount       = 0;
            MaxTotalCallCount  = 0;
            totalCallCount     = 0;
            cancelInvoke       = false;

            if (collection != null)
            {
                collection.HeapRemove(this);
                collection = null;
            }
            collectionGroup = null;

            handlerType              = InvokerHandlerType.Default;
            handler                  = null;
            handlerWithObject        = null;
            handlerWithInvoker       = null;
            handlerWithObjectInvoker = null;

            invokersByUObjectIndex = -1;
            invokersByMethodIndex  = -1;
        }
示例#9
0
 private void Process(UnrealBinaryHeapEx <Invoker> invokers, ulong value)
 {
     while (invokers.Count > 0)
     {
         Invoker invoker = invokers.HeapTop();
         if (invoker.EndValue <= value)
         {
             invokers.HeapPopDiscard();
             invoker.Process(value);
         }
         else
         {
             break;
         }
     }
 }
示例#10
0
        private void UpdateValues(bool setStartValue)
        {
            if (!Running)
            {
                return;
            }

            if (setStartValue)
            {
                switch (Type)
                {
                case InvokerType.Delay:
                    BeginValue = startingValue = (ulong)WorldTimeHelper.GetTimeChecked(OwnerWorld).Ticks;
                    break;

                case InvokerType.Ticks:
                    BeginValue = startingValue = EngineLoop.WorldTickCounter;
                    break;

                case InvokerType.Frames:
                    BeginValue = startingValue = EngineLoop.WorldFrameNumber;
                    break;
                }
            }

            InvokerCollectionGroup       newCollectionGroup = GetInvokerGroup(Group);
            UnrealBinaryHeapEx <Invoker> newCollection      = newCollectionGroup == null ? null : newCollectionGroup.GetCollection(Type);

            if (collectionGroup != null && collection != null)
            {
                if (collectionGroup.Group != Group || newCollection != collection)
                {
                    collection.HeapRemove(this);
                    collection      = null;
                    collectionGroup = null;
                }
            }

            if (newCollection != null)
            {
                collectionGroup = newCollectionGroup;
                collection      = newCollection;
                newCollection.HeapPush(this);
            }
        }
        public void Process(CoroutineGroup group)
        {
            UnrealBinaryHeapEx <T> collection = GetCollection(group);

            while (collection.Count > 0)
            {
                T instruction = collection.HeapTop();
                if (instruction.KeepWaiting)
                {
                    return;
                }
                collection.HeapPopDiscard();

                // Return the control over to the main coroutines collection
                instruction.comparableCollection = null;
                Coroutine.ComparableEnd(instruction.Owner);
            }
        }