コード例 #1
0
ファイル: Coroutine.cs プロジェクト: C41-233/Coroutine.Sharp
        private void NextThen()
        {
            var tid = Thread.CurrentThread.ManagedThreadId;

            //等待的事件成功,继续下一步
            waitable.Then(() =>
            {
                if (Status != WaitableStatus.Running)
                {
                    return;
                }

                var fastCall = tid == Thread.CurrentThread.ManagedThreadId;
                var complete = waitable is ICompleteCoroutineWaitable;
                waitable     = null;

                if (complete)
                {
                    Enqueue(Success, fastCall);
                }
                else
                {
                    Enqueue(NextStep, fastCall);
                }
            });
        }
コード例 #2
0
        public bool TryEnqueue(T item, int timeoutMilliseconds = 0)
        {
            if (item == null)
            {
                return(false);
            }

            //The method only throws exception on thread lock timeout
            using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable)
            {
                if (IsDisposing || IsDisposed)
                {
                    return(false);
                }

                if (m_count == m_size)
                {
                    return(false);
                }

                m_items[m_tail++] = item;   // Place the new item immediately after tail, then increment tail pos
                m_tail           %= m_size; // Modulus new tail pos with size so queue items will wrap around
                m_count++;                  // Count will never be more than size after incrementing here

                //Signal that an item has been enqueued to unblock waiting
                //dequeue threads
                syncLock.PulseAll();

                return(true);
            }
        }
コード例 #3
0
ファイル: Coroutine.cs プロジェクト: C41-233/Coroutine.Sharp
        private void NextCatch()
        {
            var tid = Thread.CurrentThread.ManagedThreadId;

            waitable.Catch(e =>
            {
                if (Status != WaitableStatus.Running)
                {
                    return;
                }

                var fastCall = tid == Thread.CurrentThread.ManagedThreadId;
                waitable     = null;

                if (waitable is ICompleteCoroutineWaitable)
                {
                    Enqueue(() => Fail(e), fastCall);
                }
                else
                {
                    //等待的事件失败,继续下一步,由调用者处理异常,coroutine本身未失败
                    Enqueue(NextStep, fastCall);
                }
            });
        }
コード例 #4
0
        public bool TryDequeue(out T item, int timeoutMilliseconds = 0)
        {
            //This method only throws exception on thread lock timeout
            using (IWaitable syncRoot = SyncRoot.Enter(timeoutMilliseconds) as IWaitable)
            {
                if (IsDisposing || IsDisposed)
                {
                    item = null;
                    return(false);
                }

                if (m_count == 0)
                {
                    item = null;
                    return(false);
                }

                item = m_items[m_head];     // Get item at head of queue
                m_items[m_head++] = null;   // Clear item at head of queue then increment head pos
                m_head           %= m_size; // Modulus new head pos with size so queue items will wrap around
                m_count--;                  // Count will never be less than zero after decrementing here

                //Signal that an item has been dequeued to unblock waiting
                //enqueue threads
                syncRoot.PulseAll();

                return(true);
            }
        }
コード例 #5
0
 public static IWaitable Catch(this IWaitable self, Action callback)
 {
     if (callback == null)
     {
         return(self);
     }
     return(self.Catch(e => callback()));
 }
コード例 #6
0
        public static IWaitable <T> Then <T>(this IWaitable <T> self, Action <T> callback)
        {
            Assert.NotNull(self, nameof(self));
            Assert.NotNull(callback, nameof(callback));

            self.Then(() => callback(self.Result));
            return(self);
        }
コード例 #7
0
        public static Exception Throw(this IWaitable self)
        {
            if (self.Exception != null)
            {
                ExceptionDispatchInfo.Capture(self.Exception).Throw();
            }

            return(null);
        }
コード例 #8
0
        public static IWaitable Finally(this IWaitable self, Action callback)
        {
            Assert.NotNull(self, nameof(self));
            Assert.NotNull(callback, nameof(callback));

            self.Then(callback);
            self.Catch(e => callback());
            return(self);
        }
コード例 #9
0
 public static void WaitOnUI(this IWaitable comp, Action task)
 {
     Task.Run(() =>
     {
         comp.StartWait();
         task.Invoke();
         comp.StopWait();
     });
 }
コード例 #10
0
            public void ClearAllCoroutines()
            {
                var list = new IWaitable[waitables.Count];

                waitables.CopyTo(list);
                waitables.Clear();
                foreach (var waitable in list)
                {
                    waitable.Abort();
                }
            }
コード例 #11
0
        public static IWaitable Finally(this IWaitable self, Action callback)
        {
            if (callback == null)
            {
                return(self);
            }

            self.Then(callback);
            self.Catch(callback);
            return(self);
        }
コード例 #12
0
ファイル: Coroutine.cs プロジェクト: C41-233/Coroutine.Sharp
        private void Dispatch(IWaitable waitable)
        {
            this.waitable = waitable;
            if (waitable is IBindCoroutineWaitable bindCoroutineWaitable)
            {
                bindCoroutineWaitable.Bind(container);
            }

            NextThen();
            NextCatch();
        }
コード例 #13
0
        public void Clear()
        {
            using (IWaitable syncLock = SyncRoot.Enter() as IWaitable)
            {
                //Unblock waiting threads
                syncLock.PulseAll();

                m_count = 0;
                m_head  = 0;
                m_tail  = 0;
                m_items = new T[m_size];
            }
        }
コード例 #14
0
ファイル: Coroutine.cs プロジェクト: C41-233/Coroutine.Sharp
        private void Dispose()
        {
            waitable = null;

            if (enumerator is IDisposable disposable)
            {
                disposable.Dispose();
            }
            enumerator = null;

            successCallbacks = null;
            failCallbacks    = null;
        }
コード例 #15
0
ファイル: Coroutine.cs プロジェクト: sunl4nl/Unity-Coroutine
        public bool IsDone(float deltaTime)
        {
            bool isNoNeedWait = true, isMoveOver = true;
            var  current = Enumerator.Current;

            if (current is IWaitable)
            {
                IWaitable waitable = current as IWaitable;
                isNoNeedWait = waitable.IsTickOver(deltaTime);
            }
            if (isNoNeedWait)
            {
                isMoveOver = Enumerator.MoveNext();
            }
            return(!isMoveOver);
        }
コード例 #16
0
        public static void Throw(this IWaitable self)
        {
            Assert.NotNull(self, nameof(self));

            var exception = self.Exception;
            var status    = self.Status;

            if (exception != null)
            {
                ExceptionDispatchInfo.Capture(exception).Throw();
                return;
            }

            if (status == WaitableStatus.Abort)
            {
                throw new WaitableAbortException();
            }
        }
コード例 #17
0
        public void TestAbort2()
        {
            var       i   = 0;
            IWaitable co2 = null;

            var co1 = CoroutineContainer.StartCoroutine(RunFather());

            Assert.AreEqual(0, i);
            CoroutineManager.OneLoop();
            Assert.AreEqual(1, i);
            CoroutineManager.OneLoop();
            Assert.AreEqual(2, i);
            CoroutineManager.OneLoop();
            Assert.AreEqual(3, i);
            co1.Abort();
            Assert.AreEqual(3, i);
            CoroutineManager.OneLoop();
            Assert.AreEqual(3, i);

            Tick();
            Assert.AreEqual(3, i);
            Assert.AreEqual(WaitableStatus.Abort, co1.Status);
            Assert.AreEqual(WaitableStatus.Abort, co2.Status);
            Assert.IsTrue(co1.IsAborted());
            Assert.IsTrue(co2.IsAborted());

            IEnumerable RunFather()
            {
                i++;
                co2 = CoroutineContainer.StartCoroutine(RunChild());
                yield return(co2);

                i++;
            }

            IEnumerable RunChild()
            {
                while (true)
                {
                    i++;
                    yield return(null);
                }
            }
        }
コード例 #18
0
ファイル: Coroutine.cs プロジェクト: C41-233/Coroutine.Sharp
        private void NextStep()
        {
            bool moveNext;

            try
            {
                moveNext = enumerator.MoveNext();
            }
            catch (Exception e)
            {
                //coroutine本身抛出异常,当前coroutine失败
                Fail(e);
                return;
            }

            waitable = null;
            if (!moveNext)
            {
                Success();
                return;
            }

            var current = enumerator.Current;

            switch (current)
            {
            case null:
                Enqueue(NextStep, false);
                break;

            case IEnumerable enumerable:
                Dispatch(container.StartCoroutine(enumerable));
                break;

            case Task task:
                Dispatch(new WaitForTask(task));
                break;

            default:
                Dispatch((IWaitable)current);
                break;
            }
        }
コード例 #19
0
        private void NextStep()
        {
            bool moveNext;

            try
            {
                moveNext = enumerator.MoveNext();
            }
            catch (Exception e)
            {
                //coroutine本身抛出异常,当前coroutine失败
                Fail(e);
                return;
            }

            waitable = null;
            if (!moveNext)
            {
                Success(default);
コード例 #20
0
        public void Enqueue(T item, int timeoutMilliseconds = -1)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item", "item cannot be null");
            }

            if (IsDisposing || IsDisposed)
            {
                throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>));
            }

            using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable)
            {
                //While the queue is full, wait for an empty space
                //Timeout won't be exact if multiple enqueues are blocked on a full queue
                //So a dequeue could be followed by a different enqueue so this will wait
                //for another loop
                while (m_count == m_size)
                {
                    //Wait for a pulse from a dequeue
                    if (!syncLock.Wait(timeoutMilliseconds))
                    {
                        throw new TimeoutException("Enqueue timed out while waiting for available queue space");
                    }

                    //Double check not disposed since waiting for available space
                    if (IsDisposing || IsDisposed)
                    {
                        throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>));
                    }
                }

                m_items[m_tail++] = item;   // Place the new item immediately after tail, then increment tail pos
                m_tail           %= m_size; // Modulus new tail pos with size so queue items will wrap around
                m_count++;                  // Count will never be more than size after incrementing here

                //Signal that an item has been enqueued to unblock waiting
                //dequeue threads
                syncLock.PulseAll();
            }
        }
コード例 #21
0
            public void Clear()
            {
                IWaitable[] list;
                using (spin.Hold())
                {
                    list = new IWaitable[waitables.Count];
                    waitables.CopyTo(list);
                    waitables.Clear();
                }

                foreach (var waitable in list)
                {
                    try
                    {
                        waitable.Abort();
                    }
                    catch (Exception e)
                    {
                        Console.Error.WriteLine(e);
                    }
                }
            }
コード例 #22
0
        public T Peek(int timeoutMilliseconds = -1, bool waitForEnqueue = false)
        {
            using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable)
            {
                if (IsDisposing || IsDisposed)
                {
                    throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>));
                }

                if (m_count == 0)
                {
                    if (waitForEnqueue)
                    {
                        //While queue is empty, wait for an item to enqueue
                        while (m_count == 0)
                        {
                            //Wait for a signal from an enqueue
                            if (!syncLock.Wait(timeoutMilliseconds))
                            {
                                throw new TimeoutException("Dequeue timed out while waiting for queue item to dequeue");
                            }

                            //Double check not disposed since waiting for item to be enqueued
                            if (IsDisposing || IsDisposed)
                            {
                                throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>));
                            }
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Bounded Blocking Queue is empty");
                    }
                }

                T value = m_items[m_head];
                return(value);
            }
        }
コード例 #23
0
        public T Dequeue(int timeoutMilliseconds = -1)
        {
            if (IsDisposing || IsDisposed)
            {
                throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>));
            }

            using (IWaitable syncLock = SyncRoot.Enter(timeoutMilliseconds) as IWaitable)
            {
                //Similar reasoning for here from Enqueue method
                //While queue is empty, wait for an item to enqueue
                while (m_count == 0)
                {
                    //Wait for a signal from an enqueue
                    if (!syncLock.Wait(timeoutMilliseconds))
                    {
                        throw new TimeoutException("Dequeue timed out while waiting for queue item to dequeue");
                    }

                    //Double check not disposed since waiting for item to be enqueued
                    if (IsDisposing || IsDisposed)
                    {
                        throw new ObjectDisposedException(nameof(BoundedBlockingQueue <T>));
                    }
                }

                T value = m_items[m_head];  // Get item at head of queue
                m_items[m_head++] = null;   // Clear item at head of queue then increment head pos
                m_head           %= m_size; // Modulus new head pos with size so queue items will wrap around
                m_count--;                  // Count will never be less than zero after decrementing here

                //Signal that an item has been dequeued to unblock waiting
                //enqueue threads
                syncLock.PulseAll();

                return(value);
            }
        }
コード例 #24
0
ファイル: CWaitCo.cs プロジェクト: voilin585/CosmosEngine
 public static void Wait(IWaitable wait, Action okCallback)
 {
     CCosmosEngine.EngineInstance.StartCoroutine(CoWaitTrue(new[] { wait }, okCallback));
 }
コード例 #25
0
ファイル: CWaitCo.cs プロジェクト: moto2002/CosmosEngine
 public static void Wait(IWaitable wait, Action okCallback)
 {
     CCosmosEngine.EngineInstance.StartCoroutine(CoWaitTrue(new[] { wait }, okCallback));
 }
コード例 #26
0
        public static bool IsCompleted(this IWaitable self)
        {
            Assert.NotNull(self, nameof(self));

            return(self.Status != WaitableStatus.Running);
        }
コード例 #27
0
 private IWaitable Add(IWaitable waitable)
 {
     waitables.Add(waitable);
     waitable.Finally(() => waitables.Remove(waitable));
     return(waitable);
 }
コード例 #28
0
ファイル: Waitable.cs プロジェクト: whisnantryd/Waitable
 public void WaitsOn(IWaitable waitable)
 {
     WaitsOn(new List <IWaitable> {
         waitable
     });
 }
コード例 #29
0
 public MalockTryEnterCallback(EventWaitHandle handle)
 {
     this.handle = handle;
     this.signal = handle.NewWaitable();
 }
コード例 #30
0
 public static Awaiter GetAwaiter(this IWaitable waitable)
 {
     return(new Awaiter(waitable));
 }
コード例 #31
0
 public Awaiter(IWaitable waitable)
 {
     this.waitable = waitable;
 }