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; } } }
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); } }