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;
}
}
}