/// <summary>ThreadSafe StartCoroutine.</summary> public static void SendStartCoroutine(IEnumerator routine) { if (mainThreadToken != null) { StartCoroutine(routine); } else { if (RichUnity.IsAnyEditor()) { // call from other thread if (!ScenePlaybackDetector.IsPlaying) { EditorThreadDispatcher.Instance.PseudoStartCoroutine(routine); return; } } var dispatcher = Instance; if (!isQuitting && !object.ReferenceEquals(dispatcher, null)) { dispatcher.queueWorker.Enqueue(_ => { var dispacher2 = Instance; if (dispacher2 != null) { (dispacher2 as MonoBehaviour).StartCoroutine(routine); } }, null); } } }
/// <summary>Dispatch Synchronous action if possible.</summary> public static void Send(Action <object> action, object state) { if (RichUnity.IsAnyEditor()) { if (!ScenePlaybackDetector.IsPlaying) { EditorThreadDispatcher.Instance.Enqueue(action, state); return; } } if (mainThreadToken != null) { try { action(state); } catch (Exception ex) { var dispatcher = MainThreadDispatcher.Instance; if (dispatcher != null) { dispatcher.unhandledExceptionCallback(ex); } } } else { Post(action, state); } }
public static void StartEndOfFrameMicroCoroutine(IEnumerator routine) { if (RichUnity.IsAnyEditor()) { if (!ScenePlaybackDetector.IsPlaying) { EditorThreadDispatcher.Instance.PseudoStartCoroutine(routine); return; } } var dispatcher = Instance; if (dispatcher != null) { dispatcher.endOfFrameMicroCoroutine.AddCoroutine(routine); } }
/// <summary>Dispatch Asyncrhonous action.</summary> public static void Post(Action <object> action, object state) { if (RichUnity.IsAnyEditor()) { if (!ScenePlaybackDetector.IsPlaying) { EditorThreadDispatcher.Instance.Enqueue(action, state); return; } } var dispatcher = Instance; if (!isQuitting && !object.ReferenceEquals(dispatcher, null)) { dispatcher.queueWorker.Enqueue(action, state); } }
public static void Initialize() { if (!initialized) { if (RichUnity.IsAnyEditor()) { // Don't try to add a GameObject when the scene is not playing. Only valid in the Editor, EditorView. if (!ScenePlaybackDetector.IsPlaying) { return; } } 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) { // awake call immediately from UnityEngine new GameObject("MainThreadDispatcher").AddComponent <MainThreadDispatcher>(); } else { dispatcher.Awake(); // force awake } } }
EditorThreadDispatcher() { if (RichUnity.IsAnyEditor()) { var assembly = Assembly.Load("UnityEditor"); var editorApplicationType = assembly.GetType("UnityEditor.EditorApplication"); if (null != editorApplicationType) { var updateField = editorApplicationType.GetField("update"); var updateDelegate = (MulticastDelegate)updateField.GetValue(null); var delegateType = updateDelegate.GetType(); var handler = GetType().GetMethod("Update", BindingFlags.NonPublic | BindingFlags.Instance); if (null != handler) { updateField.SetValue(null, Delegate.CreateDelegate(delegateType, this, handler)); } } } }
new public static Coroutine StartCoroutine(IEnumerator routine) { if (RichUnity.IsAnyEditor()) { if (!ScenePlaybackDetector.IsPlaying) { EditorThreadDispatcher.Instance.PseudoStartCoroutine(routine); return(null); } } var dispatcher = Instance; if (dispatcher != null) { return((dispatcher as MonoBehaviour).StartCoroutine(routine)); } else { return(null); } }
/// <summary>Run Synchronous action.</summary> public static void UnsafeSend <T>(Action <T> action, T state) { if (RichUnity.IsAnyEditor()) { if (!ScenePlaybackDetector.IsPlaying) { EditorThreadDispatcher.Instance.UnsafeInvoke(action, state); return; } } try { action(state); } catch (Exception ex) { var dispatcher = MainThreadDispatcher.Instance; if (dispatcher != null) { dispatcher.unhandledExceptionCallback(ex); } } }