Files
JuegoSim/Assets/_Project/Scripts/Code/DebendancyInjection/RuntimeAnchor.cs
T
2026-07-21 08:56:10 +03:00

71 lines
2.2 KiB
C#

using System;
using DependencyInjection.ScriptableObjects;
using UnityEngine;
namespace DependencyInjection.ScriptableObjects
{
/// <summary>
/// A ScriptableObject that acts as a typed, persistent anchor for a runtime reference.
/// Serves as the bridge between the SO architecture and the DI system — inject the
/// anchor itself so consumers always hold a stable reference and react to value changes.
/// </summary>
public abstract class RuntimeAnchor<T> : ScriptableObject where T : class
{
[Tooltip("Optional fallback value used when no runtime instance is registered.")]
[SerializeField] T _fallback;
T _runtimeValue;
bool _isSet;
public T Value => _isSet ? _runtimeValue : _fallback;
public bool IsSet => _isSet;
public event Action<T, T> OnValueChanged;
/// <summary>Register an instance into this anchor.</summary>
public void Register(T instance)
{
if (instance == null)
{
Debug.LogWarning($"[RuntimeAnchor<{typeof(T).Name}>] Attempted to register a null instance.");
return;
}
var previous = Value;
_runtimeValue = instance;
_isSet = true;
// only invoke if the value actually changed
if (previous != _runtimeValue)
{
OnValueChanged?.Invoke(previous, _runtimeValue);
}
}
/// <summary>Unregister the current instance (e.g., on object destroy).</summary>
public void Deregister(T instance)
{
if (!_isSet || _runtimeValue != instance) return;
var previous = Value;
_runtimeValue = null;
_isSet = false;
OnValueChanged?.Invoke(previous, Value); // Value now returns _fallback
}
/// <summary>Force-clear without reference matching — use with care.</summary>
public void Clear()
{
var previous = Value;
_runtimeValue = null;
_isSet = false;
OnValueChanged?.Invoke(previous, Value);
}
void OnDisable()
{
_runtimeValue = null;
_isSet = false;
}
}
}