using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.Pool; namespace BITKit.Entities.Variables { public interface IVariable { string Variable { get; set; } string[] Variables { get; } event Action OnVariableChanged; event Func TryChangeVariable; event Func CollectVariables; } [Serializable] public sealed class IVariableFromDI : InjectFromDI,IVariable { private IVariable _variableImplementation => Value; public string Variable { get => _variableImplementation.Variable; set => _variableImplementation.Variable = value; } public string[] Variables => _variableImplementation.Variables; public event Action OnVariableChanged { add => _variableImplementation.OnVariableChanged += value; remove => _variableImplementation.OnVariableChanged -= value; } public event Func TryChangeVariable { add => _variableImplementation.TryChangeVariable += value; remove => _variableImplementation.TryChangeVariable -= value; } public event Func CollectVariables { add => _variableImplementation.CollectVariables += value; remove => _variableImplementation.CollectVariables -= value; } } [CustomType(typeof(IVariable),true)] public sealed class EntityVariable:MonoBehaviour,IVariable { public string Variable { get => _variable; set { if (TryChangeVariable is null || TryChangeVariable.CastAsFunc().All(Yes)) { OnVariableChanged?.Invoke(_variable, _variable = value); } return; bool Yes(Func arg) { return arg.Invoke(value); } } } public string[] Variables { get { if (CollectVariables is null) { return Array.Empty(); } var listPool=ListPool.Get(); foreach (var x in CollectVariables.CastAsFunc()) { listPool.Add(x.Invoke()); } var result = listPool.ToArray(); ListPool.Release(listPool); return result; } } public event Action OnVariableChanged; public event Func TryChangeVariable; public event Func CollectVariables; private string _variable="Default"; private void Awake() { if (GetType().GetCustomAttribute() is { AsGlobal: true }) { DI.Register(this); } } } }