/// <summary>Dispose self on target gameObject has been destroyed. Return value is self disposable.</summary> public static T AddTo <T>(this T disposable, GameObject gameObject) where T : IDisposable { if (gameObject == null) { disposable.Dispose(); return(disposable); } ObservableDestroyTrigger trigger = gameObject.GetComponent <ObservableDestroyTrigger>(); if (trigger == null) { trigger = gameObject.AddComponent <ObservableDestroyTrigger>(); } #pragma warning disable 618 // If gameObject is deactive, does not raise OnDestroy, watch and invoke trigger. if (!trigger.IsActivated && !trigger.IsMonitoredActivate && !trigger.gameObject.activeInHierarchy) { trigger.IsMonitoredActivate = true; MainThreadDispatcher.StartEndOfFrameMicroCoroutine(MonitorTriggerHealth(trigger, gameObject)); } #pragma warning restore 618 trigger.AddDisposableOnDestroy(disposable); return(disposable); }
private static ObservableDestroyTrigger GetOrAddDestroyTrigger(GameObject go) { ObservableDestroyTrigger observableDestroyTrigger = go.GetComponent <ObservableDestroyTrigger>(); if (observableDestroyTrigger == null) { observableDestroyTrigger = go.AddComponent <ObservableDestroyTrigger>(); } return(observableDestroyTrigger); }
static ObservableDestroyTrigger GetOrAddDestroyTrigger(UnityEngine.GameObject go) { ObservableDestroyTrigger dt = go.GetComponent <ObservableDestroyTrigger>(); if (dt == null) { dt = go.AddComponent <ObservableDestroyTrigger>(); } return(dt); }
public static void Notify(this GameObject gameObject) { if (!(gameObject == null)) { ObservableDestroyTrigger component = gameObject.GetComponent <ObservableDestroyTrigger>(); if (component != null) { component.Invoke("OnDestroy", 0f); } } }
private static IEnumerator MonitorTriggerHealth(ObservableDestroyTrigger trigger, GameObject targetGameObject) { do { yield return(null); if (trigger.IsActivated) { yield break; } }while (!(targetGameObject == null)); trigger.ForceRaiseOnDestroy(); }
static IEnumerator MonitorTriggerHealth(ObservableDestroyTrigger trigger, GameObject targetGameObject) { while (true) { yield return(null); if (trigger.IsActivated) { yield break; } if (targetGameObject == null) // isDestroy { trigger.ForceRaiseOnDestroy(); // Force publish OnDestroy yield break; } } }
public static IDisposable AddTo(this IDisposable disposable, GameObject gameObject) { if (gameObject == null) { disposable.Dispose(); return(disposable); } ObservableDestroyTrigger observableDestroyTrigger = gameObject.GetComponent <ObservableDestroyTrigger>(); if (observableDestroyTrigger == null) { observableDestroyTrigger = gameObject.AddComponent <ObservableDestroyTrigger>(); } observableDestroyTrigger.OnDestroyAsObservable().Subscribe(delegate { disposable.Dispose(); }); return(disposable); }
private static IEnumerator MonitorTriggerHealth(ObservableDestroyTrigger trigger, GameObject targetGameObject) { for (;;) { yield return(null); if (trigger.IsActivated) { break; } if (targetGameObject == null) { goto Block_1; } } yield break; Block_1: trigger.ForceRaiseOnDestroy(); yield break; yield break; }
public static T AddTo <T>(this T disposable, GameObject gameObject) where T : IDisposable { if (gameObject == null) { disposable.Dispose(); return(disposable); } ObservableDestroyTrigger observableDestroyTrigger = gameObject.GetComponent <ObservableDestroyTrigger>(); if (observableDestroyTrigger == null) { observableDestroyTrigger = gameObject.AddComponent <ObservableDestroyTrigger>(); } if (!observableDestroyTrigger.IsActivated && !observableDestroyTrigger.IsMonitoredActivate && !observableDestroyTrigger.gameObject.activeInHierarchy) { observableDestroyTrigger.IsMonitoredActivate = true; MainThreadDispatcher.StartEndOfFrameMicroCoroutine(DisposableExtensions.MonitorTriggerHealth(observableDestroyTrigger, gameObject)); } observableDestroyTrigger.AddDisposableOnDestroy(disposable); return(disposable); }
static IEnumerator PublishUnityObjectValueChanged <TSource, TProperty>(UnityEngine.Object unityObject, TProperty firstValue, Func <TSource, TProperty> propertySelector, IEqualityComparer <TProperty> comparer, IObserver <TProperty> observer, CancellationToken cancellationToken, bool fastDestroyCheck) { var currentValue = default(TProperty); var prevValue = firstValue; var source = (TSource)(object)unityObject; if (fastDestroyCheck) { ObservableDestroyTrigger destroyTrigger = null; { var gameObject = unityObject as UnityEngine.GameObject; if (gameObject == null) { var comp = unityObject as UnityEngine.Component; if (comp != null) { gameObject = comp.gameObject; } } // can't use faster path if (gameObject == null) { goto STANDARD_LOOP; } destroyTrigger = GetOrAddDestroyTrigger(gameObject); } // fast compare path while (!cancellationToken.IsCancellationRequested) { var isDestroyed = destroyTrigger.IsActivated ? !destroyTrigger.IsCalledOnDestroy : (unityObject != null); if (isDestroyed) { try { currentValue = propertySelector(source); } catch (Exception ex) { observer.OnError(ex); yield break; } } else { observer.OnCompleted(); yield break; } if (!comparer.Equals(currentValue, prevValue)) { observer.OnNext(currentValue); prevValue = currentValue; } yield return(null); } yield break; } STANDARD_LOOP: while (!cancellationToken.IsCancellationRequested) { if (unityObject != null) { try { currentValue = propertySelector(source); } catch (Exception ex) { observer.OnError(ex); yield break; } } else { observer.OnCompleted(); yield break; } if (!comparer.Equals(currentValue, prevValue)) { observer.OnNext(currentValue); prevValue = currentValue; } yield return(null); } }
private static IEnumerator PublishUnityObjectValueChanged <TSource, TProperty>(UnityEngine.Object unityObject, TProperty firstValue, Func <TSource, TProperty> propertySelector, IEqualityComparer <TProperty> comparer, IObserver <TProperty> observer, CancellationToken cancellationToken, bool fastDestroyCheck) { TProperty prevValue = firstValue; TSource source = (TSource)(object)unityObject; if (fastDestroyCheck) { GameObject gameObject = unityObject as GameObject; if (gameObject == null) { Component component = unityObject as Component; if (component != null) { gameObject = component.gameObject; } } if (!(gameObject == null)) { ObservableDestroyTrigger destroyTrigger = GetOrAddDestroyTrigger(gameObject); while (true) { if (!cancellationToken.IsCancellationRequested) { if (!((!destroyTrigger.IsActivated) ? (unityObject != null) : (!destroyTrigger.IsCalledOnDestroy))) { break; } TProperty currentValue2; try { currentValue2 = propertySelector(source); } catch (Exception error) { observer.OnError(error); yield break; } if (!comparer.Equals(currentValue2, prevValue)) { observer.OnNext(currentValue2); prevValue = currentValue2; } yield return(null); continue; } yield break; } observer.OnCompleted(); yield break; } } while (true) { if (!cancellationToken.IsCancellationRequested) { if (!(unityObject != null)) { break; } TProperty currentValue2; try { currentValue2 = propertySelector(source); } catch (Exception error2) { observer.OnError(error2); yield break; } if (!comparer.Equals(currentValue2, prevValue)) { observer.OnNext(currentValue2); prevValue = currentValue2; } yield return(null); continue; } yield break; } observer.OnCompleted(); }