namespace Zinnia.Data.Operation.Extraction { using UnityEngine; using UnityEngine.Events; using Zinnia.Extension; using Zinnia.Process; /// /// Provides the basis for emitting the that any concrete implementation is residing on. /// /// The element type for the result. /// The element type for the source. /// The event to invoke. /// The event element type that is invoked. public abstract class ValueExtractor : MonoBehaviour, IProcessable where TEvent : UnityEvent, new() { /// /// Emitted when the is extracted. /// [Header("Extractor Events")] public TEvent Extracted = new TEvent(); /// /// Emitted when the data can't be extracted. /// public UnityEvent Failed = new UnityEvent(); [Header("Extractor Settings")] [Tooltip("The source to extract from.")] [SerializeField] private TSourceElement source; /// /// The source to extract from. /// public TSourceElement Source { get { return source; } set { source = value; } } /// /// The extracted . /// public TResultElement Result { get; protected set; } /// /// Clears the to the default value of the . /// public virtual void ClearSource() { Source = default; } /// /// Extracts each time the process is run in a moment. /// public virtual void Process() { DoExtract(); } /// /// Extracts the / /// /// The extracted . public virtual TResultElement Extract() { if (!this.IsValidState()) { return default; } Result = ExtractValue(); if (!InvokeResult(Result)) { Failed?.Invoke(); } return Result; } /// /// Extracts the . /// public virtual void DoExtract() { Extract(); } /// /// Extracts the from the given . /// /// The data to extract from. /// The extracted data. public virtual TResultElement Extract(TSourceElement data) { if (!this.IsValidState()) { return default; } Source = data; return Extract(); } /// /// Extracts the from the given . /// /// The data to extract from. public virtual void DoExtract(TSourceElement data) { Extract(data); } /// /// The mechanism for extracting the property value. /// /// The extracted value. protected abstract TResultElement ExtractValue(); /// /// Invokes the result via the event. /// /// The data to emit with the event. /// Whether the results were invoked. protected abstract bool InvokeResult(TResultElement data); protected virtual void OnDisable() { Result = default; } /// /// Attempts to invoke the event if the is not null. /// /// The data to emit. /// Whether the event was invoked. protected virtual bool InvokeEvent(TEventElement data) { if (Result == null) { return false; } Extracted?.Invoke(data); return true; } } }