#nullable enable
namespace TagFighter.Effects.Steps
{
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public enum PortCapacity
{
None = 0,
Single = 1,
Multi = 2,
}
public class EffectStepValidatedEventArgs : EventArgs
{
public string DisplayName;
public bool IsValid;
public EffectStepValidatedEventArgs(string displayName, bool isValid) {
DisplayName = displayName;
IsValid = isValid;
}
}
[System.Serializable]
public class EffectStepNodeData
{
public CareBoo.Serially.SerializableType SerializedType;
public string Guid;
public Vector2 Position;
public List<PortData> PortsData;
public List<double>? Const;
[UnityEngine.SerializeReference]
public IResourceOperator? Operator;
public CareBoo.Serially.SerializableType? Resource;
public CareBoo.Serially.SerializableType? Register;
public string? DisplayName;
public EffectStepNodeData(System.Type type, string guid, Vector2 position, List<PortData> portsData) {
SerializedType = new(type);
Guid = guid;
Position = position;
PortsData = portsData;
}
}
public interface IEffectStepNodeData
{
public EffectStepNodeData ToData();
public bool FromData(EffectStepNodeData effectStepNodeData, Dictionary<string, EffectStepNode> guidToNode);
}
public abstract class EffectStepNode : ScriptableObject, IEffectStepNodeData
{
public Vector2 Position;
public string Guid = System.Guid.NewGuid().ToString();
public event EventHandler<EffectStepValidatedEventArgs>? EffectStepValidated;
public abstract IEnumerable<IPort> Inputs { get; }
public abstract bool IsValid { get; }
protected virtual void OnValidate() {
OnValidated(this, new(ToString(), IsValid));
}
protected virtual void OnValidated(object sender, EffectStepValidatedEventArgs e) {
EffectStepValidated?.Invoke(sender, e);
}
public virtual EffectStepNodeData ToData() {
return new(GetType(), Guid, Position, Inputs.Select(input => input.ToData()).ToList());
}
public virtual bool FromData(EffectStepNodeData effectStepNodeData, Dictionary<string, EffectStepNode> guidToNode) {
name = effectStepNodeData.SerializedType.Type.Name;
Guid = effectStepNodeData.Guid;
Position = effectStepNodeData.Position;
foreach (var (input, data) in Inputs.Zip(effectStepNodeData.PortsData, (input, data) => (input, data))) {
input.FromData(data, guidToNode);
}
return true;
}
}
[System.AttributeUsage(System.AttributeTargets.Class, Inherited = false)
]
public class StepTypeAttribute : System.Attribute
{
public string Name;
public StepTypeAttribute(string name) {
Name = name;
}
public override string ToString() => Name;
public const string OperatorStep = "Operator";
public const string GetterStep = "Get";
public const string SetterStep = "Set";
public const string TesterStep = "Test";
public const string ReleaseStep = "Release";
}
public abstract class OutputStep<T> : EffectStepNode
{
public abstract T Run(EffectInput blackBoard);
}
public abstract class ReleaseStep : EffectStepNode
{
public abstract void Run(EffectInput blackBoard);
}
}