LifetimeDisposableExtensions.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UniRx.Triggers;
  5. using UnityEngine;
  6. namespace UniRx
  7. {
  8. public static partial class DisposableExtensions
  9. {
  10. /// <summary>Dispose self on target gameObject has been destroyed. Return value is self disposable.</summary>
  11. public static T AddTo<T>(this T disposable, GameObject gameObject)
  12. where T : IDisposable
  13. {
  14. if (gameObject == null)
  15. {
  16. disposable.Dispose();
  17. return disposable;
  18. }
  19. var trigger = gameObject.GetComponent<ObservableDestroyTrigger>();
  20. if (trigger == null)
  21. {
  22. trigger = gameObject.AddComponent<ObservableDestroyTrigger>();
  23. }
  24. #pragma warning disable 618
  25. // If gameObject is deactive, does not raise OnDestroy, watch and invoke trigger.
  26. if (!trigger.IsActivated && !trigger.IsMonitoredActivate && !trigger.gameObject.activeInHierarchy)
  27. {
  28. trigger.IsMonitoredActivate = true;
  29. MainThreadDispatcher.StartEndOfFrameMicroCoroutine(MonitorTriggerHealth(trigger, gameObject));
  30. }
  31. #pragma warning restore 618
  32. trigger.AddDisposableOnDestroy(disposable);
  33. return disposable;
  34. }
  35. static IEnumerator MonitorTriggerHealth(ObservableDestroyTrigger trigger, GameObject targetGameObject)
  36. {
  37. while (true)
  38. {
  39. yield return null;
  40. if (trigger.IsActivated) yield break;
  41. if (targetGameObject == null) // isDestroy
  42. {
  43. trigger.ForceRaiseOnDestroy(); // Force publish OnDestroy
  44. yield break;
  45. }
  46. }
  47. }
  48. /// <summary>Dispose self on target gameObject has been destroyed. Return value is self disposable.</summary>
  49. public static T AddTo<T>(this T disposable, Component gameObjectComponent)
  50. where T : IDisposable
  51. {
  52. if (gameObjectComponent == null)
  53. {
  54. disposable.Dispose();
  55. return disposable;
  56. }
  57. return AddTo(disposable, gameObjectComponent.gameObject);
  58. }
  59. /// <summary>
  60. /// <para>Add disposable(self) to CompositeDisposable(or other ICollection) and Dispose self on target gameObject has been destroyed.</para>
  61. /// <para>Return value is self disposable.</para>
  62. /// </summary>
  63. public static T AddTo<T>(this T disposable, ICollection<IDisposable> container, GameObject gameObject)
  64. where T : IDisposable
  65. {
  66. return disposable.AddTo(container).AddTo(gameObject);
  67. }
  68. /// <summary>
  69. /// <para>Add disposable(self) to CompositeDisposable(or other ICollection) and Dispose self on target gameObject has been destroyed.</para>
  70. /// <para>Return value is self disposable.</para>
  71. /// </summary>
  72. public static T AddTo<T>(this T disposable, ICollection<IDisposable> container, Component gameObjectComponent)
  73. where T : IDisposable
  74. {
  75. return disposable.AddTo(container).AddTo(gameObjectComponent);
  76. }
  77. }
  78. }