Inheritance: UnityEngine.MonoBehaviour
 public static void Initialize()
 {
     if (!initialized)
     {
         if (!Application.isPlaying) return;
         initialized = true;
         instance = new GameObject("MainThreadDispatcher").AddComponent<MainThreadDispatcher>();
         DontDestroyOnLoad(instance);
         mainThreadToken = new object();
     }
 }
示例#2
0
 public static IObservable <bool> EveryApplicationFocus()
 {
     return(MainThreadDispatcher.OnApplicationFocusAsObservable().AsObservable());
 }
示例#3
0
 public IgnoreTimeScaleMainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
 }
示例#4
0
 /// <summary>
 /// EveryLateUpdate calls from MainThreadDispatcher's OnLateUpdate.
 /// </summary>
 public static IObservable<long> EveryLateUpdate()
 {
     return MainThreadDispatcher.LateUpdateAsObservable().Scan(-1L, (x, y) => x + 1);
 }
示例#5
0
 /// <summary>
 /// EveryGameObjectUpdate calls from MainThreadDispatcher's Update.
 /// </summary>
 public static IObservable <long> EveryGameObjectUpdate()
 {
     return(MainThreadDispatcher.UpdateAsObservable().Scan(-1L, (x, y) => x + 1));
 }
示例#6
0
 public void ScheduleQueueing <T>(ICancelable cancel, T state, Action <T> action)
 {
     MainThreadDispatcher.StartEndOfFrameMicroCoroutine(ImmediateAction(state, action, cancel));
 }
示例#7
0
 public FixedUpdateMainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
 }
示例#8
0
        void OnDestroy()
        {
            if (instance == this)
            {
                instance = GameObject.FindObjectOfType<MainThreadDispatcher>();
                initialized = instance != null;

                /*
                // Although `this` still refers to a gameObject, it won't be found.
                var foundDispatcher = GameObject.FindObjectOfType<MainThreadDispatcher>();

                if (foundDispatcher != null)
                {
                    // select another game object
                    Debug.Log("new instance: " + foundDispatcher.name);
                    instance = foundDispatcher;
                    initialized = true;
                }
                */
            }
        }
        static IObservable <T> RepeatUntilCore <T>(this IEnumerable <IObservable <T> > sources, IObservable <Unit> trigger, GameObject lifeTimeChecker)
        {
            return(Observable.Create <T>(observer =>
            {
                var isFirstSubscribe = true;
                var isDisposed = false;
                var isStopped = false;
                var e = sources.AsSafeEnumerable().GetEnumerator();
                var subscription = new SerialDisposable();
                var schedule = new SingleAssignmentDisposable();
                var gate = new object();

                var stopper = trigger.Subscribe(_ =>
                {
                    lock (gate)
                    {
                        isStopped = true;
                        e.Dispose();
                        subscription.Dispose();
                        schedule.Dispose();
                        observer.OnCompleted();
                    }
                }, observer.OnError);

                schedule.Disposable = Scheduler.CurrentThread.Schedule(self =>
                {
                    lock (gate)
                    {
                        if (isDisposed)
                        {
                            return;
                        }
                        if (isStopped)
                        {
                            return;
                        }

                        var current = default(IObservable <T>);
                        var hasNext = false;
                        var ex = default(Exception);

                        try
                        {
                            hasNext = e.MoveNext();
                            if (hasNext)
                            {
                                current = e.Current;
                                if (current == null)
                                {
                                    throw new InvalidOperationException("sequence is null.");
                                }
                            }
                            else
                            {
                                e.Dispose();
                            }
                        }
                        catch (Exception exception)
                        {
                            ex = exception;
                            e.Dispose();
                        }

                        if (ex != null)
                        {
                            stopper.Dispose();
                            observer.OnError(ex);
                            return;
                        }

                        if (!hasNext)
                        {
                            stopper.Dispose();
                            observer.OnCompleted();
                            return;
                        }

                        var source = e.Current;
                        var d = new SingleAssignmentDisposable();
                        subscription.Disposable = d;

                        var repeatObserver = Observer.Create <T>(observer.OnNext, observer.OnError, self);

                        if (isFirstSubscribe)
                        {
                            isFirstSubscribe = false;
                            d.Disposable = source.Subscribe(repeatObserver);
                        }
                        else
                        {
                            MainThreadDispatcher.SendStartCoroutine(SubscribeAfterEndOfFrame(d, source, repeatObserver, lifeTimeChecker));
                        }
                    }
                });

                return new CompositeDisposable(schedule, subscription, stopper, Disposable.Create(() =>
                {
                    lock (gate)
                    {
                        isDisposed = true;
                        e.Dispose();
                    }
                }));
            }));
        }
示例#10
0
 static void DomainCleanup()
 {
     initialized = false;
     isQuitting  = false;
     instance    = null;
 }
示例#11
0
 public static Coroutine WhenAll(IEnumerable <LazyTask> tasks)
 {
     Coroutine[] coroutines = (from x in tasks
                               select x.Start()).ToArray();
     return(MainThreadDispatcher.StartCoroutine(WhenAllCore(coroutines)));
 }
示例#12
0
 public void ScheduleQueueing <T>(ICancelable cancel, T state, Action <T> action)
 {
     MainThreadDispatcher.Post(Scheduler.IgnoreTimeScaleMainThreadScheduler.QueuedAction <T> .Instance, Tuple.Create <ICancelable, T, Action <T> >(cancel, state, action));
 }
示例#13
0
 public IgnoreTimeScaleMainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
     this.scheduleAction = new Action <object>(this.Schedule);
 }
示例#14
0
 public void ScheduleQueueing <T>(ICancelable cancel, T state, Action <T> action)
 {
     MainThreadDispatcher.StartFixedUpdateMicroCoroutine(this.ImmediateAction <T>(state, action, cancel));
 }
            IEnumerator DelayAction(TimeSpan dueTime, Action action)
            {
                yield return(new WaitForSeconds((float)dueTime.TotalSeconds));

                MainThreadDispatcher.Post(action);
            }
示例#16
0
 void Awake()
 {
     instance    = this;
     initialized = true;
 }
示例#17
0
 static void DestroyDispatcher(MainThreadDispatcher aDispatcher)
 {
     if (aDispatcher != instance)
     {
         // Try to remove game object if it's empty
         var components = aDispatcher.gameObject.GetComponents<Component>();
         if (aDispatcher.gameObject.transform.childCount == 0 && components.Length == 2)
         {
             if (components[0] is Transform && components[1] is MainThreadDispatcher)
             {
                 Destroy(aDispatcher.gameObject);
             }
         }
         else
         {
             // Remove component
             MonoBehaviour.Destroy(aDispatcher);
         }
     }
 }
示例#18
0
 public static Coroutine WhenAll(IEnumerable <LazyTask> tasks)
 {
     Coroutine[] coroutines = Enumerable.ToArray <Coroutine>(Enumerable.Select <LazyTask, Coroutine>(tasks, (LazyTask x) => x.Start()));
     return(MainThreadDispatcher.StartCoroutine(LazyTask.WhenAllCore(coroutines)));
 }
示例#19
0
 public void ScheduleQueueing <T>(ICancelable cancel, T state, Action <T> action)
 {
     MainThreadDispatcher.Post(QueuedAction <T> .Instance, Tuple.Create(cancel, state, action));
 }
示例#20
0
            // delay action is run in StartCoroutine
            // Okay to action run synchronous and guaranteed run on MainThread
            IEnumerator DelayAction(TimeSpan dueTime, Action action, ICancelable cancellation)
            {
#if UNITY_EDITOR
                if (!ScenePlaybackDetector.IsPlaying)
                {
                    var startTime = DateTimeOffset.UtcNow;
                    while (true)
                    {
                        yield return(null);

                        if (cancellation.IsDisposed)
                        {
                            break;
                        }

                        var elapsed = DateTimeOffset.UtcNow - startTime;
                        if (elapsed >= dueTime)
                        {
                            MainThreadDispatcher.UnsafeSend(action);
                            break;
                        }
                    }
                    ;
                    yield break;
                }
#endif

                if (dueTime == TimeSpan.Zero)
                {
                    yield return(null); // not immediately, run next frame

                    if (cancellation.IsDisposed)
                    {
                        yield break;
                    }

                    MainThreadDispatcher.UnsafeSend(action);
                }
                else if (dueTime.TotalMilliseconds % 1000 == 0)
                {
                    yield return(new WaitForSeconds((float)dueTime.TotalSeconds));

                    if (cancellation.IsDisposed)
                    {
                        yield break;
                    }

                    MainThreadDispatcher.UnsafeSend(action);
                }
                else
                {
                    var startTime = Time.time;
                    var dt        = (float)dueTime.TotalSeconds;
                    while (true)
                    {
                        yield return(null);

                        if (cancellation.IsDisposed)
                        {
                            break;
                        }

                        var elapsed = Time.time - startTime;
                        if (elapsed >= dt)
                        {
                            MainThreadDispatcher.UnsafeSend(action);
                            break;
                        }
                    }
                }
            }
示例#21
0
 public EndOfFrameMainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
 }
 void Awake()
 {
     instance = this;
     initialized = true;
 }
示例#23
0
 public MainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
     scheduleAction = new Action <object>(Schedule);
 }
示例#24
0
        public static Coroutine WhenAll(IEnumerable <LazyTask> tasks)
        {
            var coroutines = tasks.Select(x => x.Start()).ToArray();

            return(MainThreadDispatcher.StartCoroutine(WhenAllCore(coroutines)));
        }
示例#25
0
        // I can't avoid Unity 5.3's uNET weaver bug, pending...

        //public static IObservable<T> SubscribeOnMainThread<T>(this IObservable<T> source, MainThreadDispatchType dispatchType)
        //{
        //    switch (dispatchType)
        //    {
        //        case MainThreadDispatchType.Update:
        //            return source.SubscribeOnMainThread(); // faster path

        //        // others, bit slower

        //        case MainThreadDispatchType.FixedUpdate:
        //            return new UniRx.Operators.SubscribeOnMainThreadObservable<T>(source, EveryFixedUpdate().Take(1));
        //        case MainThreadDispatchType.EndOfFrame:
        //            return new UniRx.Operators.SubscribeOnMainThreadObservable<T>(source, EveryEndOfFrame().Take(1));
        //        case MainThreadDispatchType.GameObjectUpdate:
        //            return new UniRx.Operators.SubscribeOnMainThreadObservable<T>(source, MainThreadDispatcher.UpdateAsObservable().Select(_ => 0L).Take(1));
        //        case MainThreadDispatchType.LateUpdate:
        //            return new UniRx.Operators.SubscribeOnMainThreadObservable<T>(source, MainThreadDispatcher.LateUpdateAsObservable().Select(_ => 0L).Take(1));
        //        case MainThreadDispatchType.AfterUpdate:
        //            return new UniRx.Operators.SubscribeOnMainThreadObservable<T>(source, EveryAfterUpdate().Take(1));
        //        default:
        //            throw new ArgumentException("type is invalid");
        //    }
        //}

        public static IObservable<bool> EveryApplicationPause()
        {
            return MainThreadDispatcher.OnApplicationPauseAsObservable().AsObservable();
        }
示例#26
0
 public MainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
     scheduleAction = Schedule;
 }
示例#27
0
 public MainThreadScheduler()
 {
     MainThreadDispatcher.Initialize();
 }
示例#28
0
        public static void Initialize()
        {
            if (!initialized)
            {
#if UNITY_EDITOR
                // Don't try to add a GameObject when the scene is not playing. Only valid in the Editor, EditorView.
                if (!ScenePlaybackDetector.IsPlaying) return;
#endif
                MainThreadDispatcher dispatcher = null;

                try
                {
                    dispatcher = GameObject.FindObjectOfType<MainThreadDispatcher>();
                }
                catch
                {
                    // Throw exception when calling from a worker thread.
                    var ex = new Exception("UniRx requires a MainThreadDispatcher component created on the main thread. Make sure it is added to the scene before calling UniRx from a worker thread.");
                    UnityEngine.Debug.LogException(ex);
                    throw ex;
                }

                if (isQuitting)
                {
                    // don't create new instance after quitting
                    // avoid "Some objects were not cleaned up when closing the scene find target" error.
                    return;
                }

                if (dispatcher == null)
                {
                    instance = new GameObject("MainThreadDispatcher").AddComponent<MainThreadDispatcher>();
                }
                else
                {
                    instance = dispatcher;
                }
                DontDestroyOnLoad(instance);
                mainThreadToken = new object();
                initialized = true;
            }
        }
示例#29
0
 /// <summary>AutoStart observable as coroutine.</summary>
 public static Coroutine StartAsCoroutine <T>(this IObservable <T> source, Action <T> onResult, Action <Exception> onError, CancellationToken cancel = default(CancellationToken))
 {
     return(MainThreadDispatcher.StartCoroutine(source.ToAwaitableEnumerator(onResult, onError, cancel)));
 }
示例#30
0
        void Awake()
        {
            if (instance == null)
            {
                instance = this;
                mainThreadToken = new object();
                initialized = true;

                // Added for consistency with Initialize()
                DontDestroyOnLoad(gameObject);
            }
            else
            {
                if (cullingMode == CullingMode.Self)
                {
                    Debug.LogWarning("There is already a MainThreadDispatcher in the scene. Removing myself...");
                    // Destroy this dispatcher if there's already one in the scene.
                    DestroyDispatcher(this);
                }
                else if (cullingMode == CullingMode.All)
                {
                    Debug.LogWarning("There is already a MainThreadDispatcher in the scene. Cleaning up all excess dispatchers...");
                    CullAllExcessDispatchers();
                }
                else
                {
                    Debug.LogWarning("There is already a MainThreadDispatcher in the scene.");
                }
            }
        }
示例#31
0
 /// <summary>publish OnNext(Unit) and OnCompleted() on application quit.</summary>
 public static IObservable <Unit> OnceApplicationQuit()
 {
     return(MainThreadDispatcher.OnApplicationQuitAsObservable().Take(1));
 }
示例#32
0
		public static CoroutineAsyncBridge Start<T>(T awaitTarget) {
			var bridge = new CoroutineAsyncBridge();
			MainThreadDispatcher.StartCoroutine(bridge.Run(awaitTarget));
			return bridge;
		}