예제 #1
0
        public void SetResult(T value)
        {
            isRunning = true;

            if (singleHandler != null)
            {
                try
                {
                    singleHandler.OnNext(value);
                }
                catch (Exception ex)
                {
#if UNITY_2018_3_OR_NEWER
                    UnityEngine.Debug.LogException(ex);
#else
                    Console.WriteLine(ex);
#endif
                }
            }

            if (handlers != null)
            {
                for (int i = 0; i < handlers.Length; i++)
                {
                    if (handlers[i] != null)
                    {
                        try
                        {
                            handlers[i].OnNext(value);
                        }
                        catch (Exception ex)
                        {
                            handlers[i] = null;
#if UNITY_2018_3_OR_NEWER
                            UnityEngine.Debug.LogException(ex);
#else
                            Console.WriteLine(ex);
#endif
                        }
                    }
                }
            }

            isRunning = false;

            if (waitHandler != null)
            {
                var h = waitHandler;
                waitHandler = null;
                Add(h);
            }

            if (waitQueue != null)
            {
                while (waitQueue.Count != 0)
                {
                    Add(waitQueue.Dequeue());
                }
            }
        }
예제 #2
0
        private void RunLoop()
        {
            var lastTimestamp = Stopwatch.GetTimestamp();

            while (!_ctsLoop.IsCancellationRequested)
            {
                var begin = Stopwatch.GetTimestamp();

                lock (_lockQueue)
                {
                    _isRunning = true;
                }

                lock (_lockActions)
                {
                    var elapsedTimeFromPreviousFrame = TimeSpan.FromTicks(begin - lastTimestamp);
                    lastTimestamp = begin;

                    var ctx = new LogicLooperActionContext(this, _frame++, elapsedTimeFromPreviousFrame, _ctsAction.Token);

                    var j = _tail - 1;
                    for (var i = 0; i < _actions.Length; i++)
                    {
                        ref var action = ref _actions[i];

                        // Found an action and invoke it.
                        if (action.Action != null)
                        {
                            if (!InvokeAction(ctx, ref action))
                            {
                                action = default;
                            }
                            continue;
                        }

                        // Invoke actions from tail.
                        while (i < j)
                        {
                            ref var actionFromTail = ref _actions[j];

                            j--; // consumed

                            if (actionFromTail.Action != null)
                            {
                                if (!InvokeAction(ctx, ref actionFromTail))
                                {
                                    actionFromTail = default;
                                    continue; // Continue the reverse loop flow.
                                }
                                else
                                {
                                    action         = actionFromTail; // Swap the null element and the action.
                                    actionFromTail = default;
                                    goto NextActionLoop;             // Resume to the regular flow.
                                }
                            }
                        }

                        _tail = i;
                        break;

NextActionLoop:
                        continue;
                    }

                    lock (_lockQueue)
                    {
                        _isRunning = false;

                        while (_registerQueue.Count != 0)
                        {
                            if (_actions.Length == _tail)
                            {
                                Array.Resize(ref _actions, checked (_tail * _growFactor));
                            }
                            _actions[_tail++] = _registerQueue.Dequeue();
                        }
                    }
                }