DisposeOnDestroy
拡張メソッド
名前空間:SilCilSystem.Variables
Assembly:SilCilSystem
ゲームオブジェクトが破棄されるタイミングでIDisposable.Dispose
を呼ぶようにする拡張メソッドです。
イベントアセットの解除処理に利用できます。
使用例
ゲームオブジェクトが行うイベントの解除を簡潔に書けるようになります。
using UnityEngine;
using SilCilSystem.Variables;
public class TestDisposeOnDestroy : MonoBehaviour
{
[SerializeField] private GameEventListener m_event = default;
[SerializeField] private GameEventIntListener m_eventInt = default;
private void Start()
{
// OnDestroyメソッドでDisposeを書く必要がなくなります.
m_event?.Subscribe(() => Debug.Log("Hello")).DisposeOnDestroy(gameObject);
// Subscribeの第2引数にGameObjectを指定することもできます.
m_eventInt?.Subscribe(i => Debug.Log(i), gameObject);
}
}
実装
Disopose
を呼ぶためのコンポーネントを指定されたゲームオブジェクトにAddComponent
することで実現しています。
イベント1つ1つに対してそれぞれコンポーネントを追加するのはパフォーマンス的にもよろしくないので、
CompositeDisposableを使用して複数のIDisposable
を1つにまとめています。
アタッチする用のコンポーネントは以下のようになっています。
internal class DisposeOnDestroyCaller : MonoBehaviour
{
private CompositeDisposable m_disposable = new CompositeDisposable();
private void OnDestroy()
{
m_disposable?.Dispose();
}
internal void Set(IDisposable disposable)
{
m_disposable.Add(disposable);
}
}
これを拡張メソッドで生成/取得しています。
public static void DisposeOnDestroy(this IDisposable disposable, GameObject gameObject)
{
if (gameObject == null) return;
if(gameObject.TryGetComponent(out DisposeOnDestroyCaller caller))
{
caller.Set(disposable);
}
else
{
gameObject.AddComponent<DisposeOnDestroyCaller>().Set(disposable);
}
}