Ejemplo n.º 1
0
        public void InsertRoutine(FECgCoroutineSchedule schedule, FCgRoutine pivot, FCgRoutine insert)
        {
            // Detach insert

            // insert is the Tail
            if (insert.Next == null)
            {
                Tails[schedule] = insert.Prev;
            }
            else
            {
                insert.Next.Prev = insert.Prev;
            }
            insert.Prev.Next = insert.Next;

            // Insert insert ahead of pivot

            // pivot is the Head
            if (pivot.Prev == null)
            {
                Heads[schedule] = insert;

                pivot.Prev  = insert;
                insert.Next = pivot;
                insert.Prev = null;
            }
            else
            {
                pivot.Prev.Next = insert;
                insert.Prev     = pivot.Prev;
                insert.Next     = pivot;
                pivot.Prev      = insert;
            }
        }
Ejemplo n.º 2
0
        public void Reset()
        {
            Prev  = null;
            Next  = null;
            State = ECgRoutineState.Free;

            Fiber       = null;
            Name        = "";
            RoutineType = INVALID_TYPE;
            WaitingFor  = null;
            Blocking    = null;
            Parent      = null;
            Children.Clear();
            Owner.UnSet();
            OwnerName = "";
            StopCondition.Clear();
            StopMessages.Clear();

            for (byte i = 0; i < (byte)ECgCoroutineMessage.MAX; ++i)
            {
                Messages_Recieved[(ECgCoroutineMessage)i].Clear();
            }

            Add.Unbind();
            Remove.Unbind();
            StartTime                = 0.0f;
            ElapsedTime              = 0.0f;
            DeltaTime                = 0.0f;
            TickCount                = 0;
            Delay                    = 0.0f;
            bWaitForFrame            = false;
            WaitForFrameCounter      = 0;
            WaitForFrame             = 0;
            WaitForFrameType         = null;
            bWaitForTime             = false;
            WaitForTimeTimer         = 0.0f;
            WaitForTime              = 0.0f;
            WaitForTimeType          = null;
            bWaitForFlag             = false;
            WaitForBoolType          = null;
            WaitForFlagType          = null;
            bWaitForListenMessage    = false;
            WaitForListenMessage     = INVALID_LISTEN_MESSAGE;
            WaitForListenMessageType = null;

            EndReason = ECgCoroutineEndReason.MAX;

            for (byte i = 0; i < INT_SIZE; ++i)
            {
                Ints[i] = 0;
            }

            for (byte i = 0; i < FLOAT_SIZE; ++i)
            {
                Floats[i] = 0.0f;
            }
        }
Ejemplo n.º 3
0
        public void Prep(FCgRoutine r, FCgCoroutinePayload payload)
        {
            r.Start(payload.Fiber, payload.Stop, payload.Owner, payload.OwnerName, payload.StartTime, payload.Add, payload.Remove, payload.RoutineType);
            r.State = ECgRoutineState.Allocating;

            LogTransaction(ECgCoroutineSchedulerCached.Str.Prep, ECgCoroutineTransaction.Allocate, r);

            payload.Reset();
        }
Ejemplo n.º 4
0
        public static bool CoroutineStopCondition_CheckMonoObject(FCgRoutine r)
        {
            MonoBehaviour mb = r.Owner.Get <MonoBehaviour>();

            if (mb != null)
            {
                return(true);
            }
            return(false);
        }
Ejemplo n.º 5
0
        public FCgRoutine Allocate(FCgCoroutinePayload payload)
        {
            FECgCoroutineSchedule schedule = payload.Schedule;

            FCgRoutine r = Allocate_Internal(schedule);

            r.Start(payload.Fiber, payload.Stop, payload.Owner, payload.OwnerName, payload.StartTime, payload.Add, payload.Remove, payload.RoutineType);
            r.State = ECgRoutineState.Allocating;

            LogTransaction(ECgCoroutineSchedulerCached.Str.Allocate, ECgCoroutineTransaction.Allocate, r);

            payload.Reset();

            return(r);
        }
Ejemplo n.º 6
0
        public void BroadcastMessage(FECgCoroutineSchedule schedule, ECgCoroutineMessage msgType, string msg, object owner = null)
        {
            int count = RoutinesRunning[schedule].Count;

            for (int i = 0; i < count; ++i)
            {
                FCgRoutine r = RoutinesRunning[schedule][i];

                if (owner != null && owner != r.Owner.Get())
                {
                    continue;
                }

                r.ReceiveMessage(msgType, msg);
            }
        }
Ejemplo n.º 7
0
        private FCgRoutine Allocate_Internal(FECgCoroutineSchedule schedule)
        {
            for (ushort i = 0; i < POOL_SIZE; ++i)
            {
                PoolIndicies[schedule] = (PoolIndicies[schedule] + 1) % POOL_SIZE;

                FCgRoutine r = Pools[schedule][PoolIndicies[schedule]];

                if (r.State != ECgRoutineState.Free)
                {
                    continue;
                }

                return(r);
            }
            Debug.LogError("FCgRoutine.Allocate: No free Routines. Pools[" + schedule.ToString() + "] is exhausted. Look for runaway Coroutines or consider raising the pool size.");
            return(null);
        }
Ejemplo n.º 8
0
        public FCgRoutine Start(FCgCoroutinePayload payload)
        {
            FECgCoroutineSchedule schedule = payload.Schedule;

            FCgRoutine r = Allocate_Internal(schedule);

            if (r == null)
            {
                payload.Reset();
                return(null);
            }

            // If NO Head, Make r the Head
            if (Heads[schedule] == null)
            {
                Heads[schedule] = r;
                Tails[schedule] = r;
            }
            // Add r end of the list, Make r the Tail
            else
            {
                FCgRoutine tail = Tails[schedule];
                tail.Next       = r;
                r.Prev          = tail;
                Tails[schedule] = r;
            }

            RoutinesRunning[schedule].Add(r);

            // TODO: get Time from Manager_Time
            r.Start(payload.Fiber, payload.Stop, payload.Owner, payload.OwnerName, payload.StartTime, payload.Add, payload.Remove, payload.RoutineType);
            r.State = ECgRoutineState.Running;

            LogTransaction(ECgCoroutineSchedulerCached.Str.Start, ECgCoroutineTransaction.Start, r);

            payload.Reset();
            r.Run(0.0f);
            return(r);
        }
Ejemplo n.º 9
0
        public FCgRoutine Start(FECgCoroutineSchedule schedule, FCgRoutine r)
        {
            // If NO Head, Make r the Head
            if (Heads[schedule] == null)
            {
                Heads[schedule] = r;
                Tails[schedule] = r;
            }
            // Add r end of the list, Make r the Tail
            else
            {
                FCgRoutine tail = Tails[schedule];
                tail.Next       = r;
                r.Prev          = tail;
                Tails[schedule] = r;
            }

            RoutinesRunning[schedule].Add(r);
            r.State = ECgRoutineState.Running;
            r.Run(0.0f);
            return(r);
        }
Ejemplo n.º 10
0
        public void Run(float deltaTime)
        {
            // Check Stop Messages
            int count = Messages_Recieved[ECgCoroutineMessage.Stop].Count;

            for (int i = 0; i < count; ++i)
            {
                if (StopMessages.FindIndex(s => s == Messages_Recieved[ECgCoroutineMessage.Stop][i]) != CgTypes.INDEX_NONE)
                {
                    StopMessages.Clear();
                    End(ECgCoroutineEndReason.StopMessage);
                    break;
                }
            }
            Messages_Recieved[ECgCoroutineMessage.Stop].Clear();

            if (State == ECgRoutineState.End)
            {
                return;
            }
            // Check Stop Condition
            if (StopCondition.Broadcast(this))
            {
                End(ECgCoroutineEndReason.StopCondition);
            }

            if (State == ECgRoutineState.End)
            {
                return;
            }

            DeltaTime    = deltaTime;
            ElapsedTime += deltaTime;
            ++TickCount;

            bool move = true;

            // Check WaitForFrame
            if (bWaitForFrame)
            {
                if (WaitForFrameType != null)
                {
                    WaitForFrame = WaitForFrameType.Get();

                    if (WaitForFrame < 0)
                    {
                        WaitForFrame     = 0;
                        WaitForFrameType = null;

                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'FCgRoutine.FFrameType' is used for WaitForFrame. yield return value must be >= 0.");
                    }
                }

                ++WaitForFrameCounter;

                move = WaitForFrameCounter >= WaitForFrame;

                if (move)
                {
                    WaitForFrame        = 0;
                    bWaitForFrame       = false;
                    WaitForFrameCounter = 0;
                }
            }
            // Check WaitForTime
            if (bWaitForTime)
            {
                if (WaitForTimeType != null)
                {
                    WaitForTime = WaitForTimeType.Get();

                    if (WaitForTime < 0.0f)
                    {
                        WaitForTime     = 0.0f;
                        WaitForTimeType = null;

                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'FCgRoutine.FTimeType' is used for WaitForTime. yield return value must be >= 0.0f.");
                    }
                }

                WaitForTimeTimer += deltaTime;

                move = WaitForTimeTimer >= WaitForTime;

                if (move)
                {
                    WaitForTime      = 0;
                    bWaitForTime     = false;
                    WaitForTimeTimer = 0.0f;
                }
            }
            // Check WaitingFor
            if (bWaitingFor)
            {
                move = WaitingFor.State != ECgRoutineState.Running;

                if (move)
                {
                    WaitingFor.Blocking = null;
                    WaitingFor          = null;
                    bWaitingFor         = false;
                }
            }
            // Check WaitForFlag
            if (bWaitForFlag)
            {
                move = (WaitForBoolType != null && WaitForBoolType.Get()) || (WaitForFlagType != null && WaitForFlagType.IsEqual());

                if (WaitForBoolType != null)
                {
                }

                if (move)
                {
                    WaitForBoolType = null;
                    bWaitForFlag    = false;
                }
            }
            // WaitForListenMessage
            if (bWaitForListenMessage)
            {
                // TODO: Need to overload != operator correctly
                if (!object.ReferenceEquals(WaitForListenMessageType, null))
                {
                    WaitForListenMessage = WaitForListenMessageType.Get();

                    if (WaitForListenMessage == INVALID_LISTEN_MESSAGE)
                    {
                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'FCgRoutine.FListenMessageType' is used for WaitForListenMessage. yield return value must NOT be empty.");
                    }
                }

                move = WaitForListenMessage == INVALID_LISTEN_MESSAGE;// ||

                if (move)
                {
                    WaitForListenMessage  = INVALID_LISTEN_MESSAGE;
                    bWaitForListenMessage = false;
                }
            }

            if (!move)
            {
                return;
            }

            if (Fiber.MoveNext())
            {
                object yieldCommand = Fiber.Current == null ? (object)1 : Fiber.Current;
                Type   type         = yieldCommand.GetType();
                // WaitForFrame
                if (type == typeof(int))
                {
                    WaitForFrame = (int)yieldCommand;

                    if (WaitForFrame < 0)
                    {
                        WaitForFrame = 0;

                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'int' is used for WaitForFrame. yield return value must be >= 0.");
                    }
                    else
                    {
                        bWaitForFrame       = true;
                        WaitForFrameCounter = 0;
                    }
                }
                else
                if (type == typeof(FFrameType))
                {
                    WaitForFrameType = (FFrameType)yieldCommand;

                    if (WaitForFrameType.Get() < 0)
                    {
                        WaitForFrameType = null;

                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'FCgRoutine.FFrameType' is used for WaitForFrame. yield return value must be >= 0.");
                    }
                    else
                    {
                        bWaitForFrame       = true;
                        WaitForFrameCounter = 0;
                    }
                }
                // WaitForTime
                else
                if (type == typeof(float))
                {
                    WaitForTime = (float)yieldCommand;

                    if (WaitForTime < 0.0f)
                    {
                        WaitForTime = 0.0f;

                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'float' is used for WaitForTime. yield return value must be >= 0.0f.");
                    }
                    else
                    {
                        bWaitForTime     = true;
                        WaitForTimeTimer = 0.0f;
                    }
                }
                else
                if (type == typeof(FTimeType))
                {
                    WaitForTimeType = (FTimeType)yieldCommand;

                    if (WaitForTimeType.Get() < 0.0f)
                    {
                        WaitForTimeType = null;

                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'FCgRoutine.FTimeType' is used for WaitForTime. yield return value must be >= 0.0f.");
                    }
                    else
                    {
                        bWaitForTime     = true;
                        WaitForTimeTimer = 0.0f;
                    }
                }
                // WaitingFor
                else
                if (type == typeof(FCgRoutine))
                {
                    WaitingFor          = (FCgRoutine)yieldCommand;
                    WaitingFor.Blocking = this;
                    bWaitingFor         = true;

                    // Fix linkage. Prev / Next
                    InsertRoutine(Schedule, this, WaitingFor);
                }
                // WaitForFlag
                else
                if (type == typeof(FBoolType))
                {
                    WaitForBoolType = (FBoolType)yieldCommand;

                    if (!WaitForBoolType.Get())
                    {
                        bWaitForFlag = true;
                    }
                }
                else
                if (typeof(ICgFlag).IsAssignableFrom(type))
                {
                    WaitForFlagType = (ICgFlag)yieldCommand;

                    if (!WaitForFlagType.IsEqual())
                    {
                        bWaitForFlag = true;
                    }
                }
                // WaitForListenMessage
                else
                if (type == typeof(string))
                {
                    WaitForListenMessage = (string)yieldCommand;

                    if (WaitForListenMessage == INVALID_LISTEN_MESSAGE)
                    {
                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'string' is used for WaitForListenMessage. yield return value must NOT be empty.");
                    }
                    else
                    {
                        bWaitForListenMessage = true;
                    }
                }
                else
                if (type == typeof(FListenMessageType))
                {
                    WaitForListenMessageType = (FListenMessageType)yieldCommand;

                    if (WaitForListenMessageType.Get() == INVALID_LISTEN_MESSAGE)
                    {
                        Debug.LogWarning("FCgRoutine.Run: yield return value of type 'string' is used for WaitForListenMessage. yield return value must NOT be empty.");
                    }
                    else
                    {
                        bWaitForListenMessage = true;
                    }
                }
                // INVALID Type
                else
                {
                    Debug.LogError("FCgRoutine.Run: Invalid Type: " + type.GetType() + " for yield. yield return value must be of type: int, FCgRoutine.FFrameType, float, FCgRoutine.FTimeType, FCgRoutine, FCgRoutine.FBoolType, ICgFlag, string, or FCgRoutine.FListenMessageType.");
                }
            }
            // Finished
            else
            {
                End(ECgCoroutineEndReason.EndOfExecution);
            }
        }
Ejemplo n.º 11
0
        // Constructor

        public FCgRoutine(int index, FECgCoroutineSchedule schedule, InsertRoutineAheadOf insertRoutine)
        {
            Index    = index;
            Schedule = schedule;

            Prev = null;
            Next = null;

            State = ECgRoutineState.Free;

            Fiber       = null;
            Name        = "";
            RoutineType = INVALID_TYPE;

            bWaitingFor = false;
            WaitingFor  = null;
            Blocking    = null;

            InsertRoutine = insertRoutine;

            Parent   = null;
            Children = new List <FCgRoutine>();

            Owner         = new FCgAttribute();
            OwnerName     = "";
            StopCondition = new FCoroutineStopCondition();

            StopMessages      = new List <string>();
            Messages_Recieved = new Dictionary <ECgCoroutineMessage, List <string> >(new ECgCoroutineMessageEqualityComparer());

            for (byte i = 0; i < (byte)ECgCoroutineMessage.MAX; ++i)
            {
                Messages_Recieved[(ECgCoroutineMessage)i] = new List <string>();
            }

            Add    = new FAddRoutine();
            Remove = new FRemoveRoutine();

            StartTime   = 0.0f;
            ElapsedTime = 0.0f;
            DeltaTime   = 0.0f;
            TickCount   = 0;
            Delay       = 0.0f;

            bWaitForFrame            = false;
            WaitForFrameCounter      = 0;
            WaitForFrame             = 0;
            WaitForFrameType         = null;
            bWaitForTime             = false;
            WaitForTime              = 0.0f;
            WaitForTimeTimer         = 0.0f;
            WaitForTimeType          = null;
            bWaitForFlag             = false;
            WaitForBoolType          = null;
            WaitForFlagType          = null;
            bWaitForListenMessage    = false;
            WaitForListenMessage     = INVALID_LISTEN_MESSAGE;
            WaitForListenMessageType = null;

            EndReason = ECgCoroutineEndReason.MAX;

            Ints   = new int[INT_SIZE];
            Floats = new float[FLOAT_SIZE];
        }
Ejemplo n.º 12
0
 public virtual bool RemoveRoutine(FCgRoutine r)
 {
     return(false);
 }
Ejemplo n.º 13
0
 public virtual bool AddRoutine(FCgRoutine r)
 {
     return(false);
 }
Ejemplo n.º 14
0
        public void LogTransaction(string functionName, ECgCoroutineTransaction transaction, FCgRoutine r)
        {
            if (!LogTransactions.Log())
            {
                return;
            }

            string transactionAsString = transaction.ToString() + "ing (Reason=" + r.EndReason.ToString() + ")";
            string schedule            = r.Schedule.ToString();

            float currentTime = Time.time;

            string elapsed = "";

            if (transaction == ECgCoroutineTransaction.End)
            {
                float duration = currentTime - r.StartTime;
                elapsed = "Ran for " + r.TickCount + " Ticks and " + duration + " Seconds.";
            }

            if (r.Owner != null)
            {
                Debug.Log(functionName + ": On" + schedule + " " + transactionAsString + " Routine with Coroutine: " + r.Name + " at " + currentTime + ". Using Owner: " + r.OwnerName + ". " + elapsed);
            }
            else
            {
                Debug.Log(functionName + ": On" + schedule + " " + transactionAsString + " Routine with Coroutine: " + r.Name + " at " + currentTime + ". " + elapsed);
            }
        }
Ejemplo n.º 15
0
        public void Update(FECgCoroutineSchedule schedule, float deltaTime)
        {
            // Iterate through List
            FCgRoutine current = Heads[schedule];

            while (current != null)
            {
                if (current.State == ECgRoutineState.Running)
                {
                    current.Run(deltaTime);
                }

                if (current.State == ECgRoutineState.End)
                {
                    // Remove from List, Update Linkage. Prev / Next
                    if (current.Prev != null)
                    {
                        current.Prev.Next = current.Next;

                        if (current.Next != null)
                        {
                            current.Next.Prev = current.Prev;
                        }
                        // Update Tail
                        else
                        {
                            Tails[schedule] = current.Prev;
                        }
                    }
                    // Update Head
                    else
                    {
                        if (current.Next != null)
                        {
                            current.Next.Prev = null;
                            Heads[schedule]   = current.Next;
                        }
                        // Last node in List
                        else
                        {
                            Heads[schedule] = null;
                            Tails[schedule] = null;
                        }
                    }
                    LogTransaction("FCgRoutine.Update", ECgCoroutineTransaction.End, current);

                    FCgRoutine r = current;
                    current = current.Next;
                    r.Reset();
                }
                else
                {
                    current = current.Next;
                }
            }

            // Check RoutinesRunning for any Routines that have Ended
            int count = RoutinesRunning[schedule].Count;

            for (int i = count - 1; i >= 0; --i)
            {
                FCgRoutine r = RoutinesRunning[schedule][i];

                if (r.State == ECgRoutineState.Free)
                {
                    RoutinesRunning[schedule].RemoveAt(i);
                }
                else
                if (r.State == ECgRoutineState.End)
                {
                    if (r.EndReason == ECgCoroutineEndReason.EndOfExecution ||
                        r.EndReason == ECgCoroutineEndReason.Parent)
                    {
                        Debug.LogError("CgCoroutineSchedule.Update: Dangling Routine. Check iteration through List or if Routine was tampered with.");
                    }
                    r.Reset();
                    RoutinesRunning[schedule].RemoveAt(i);
                }
            }
        }