#nullable enable
namespace TagFighter.Effects.Steps
{
using System.Collections.Generic;
using System.Reflection;
using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;
[StepType(StepTypeAttribute.SetterStep)]
public class ContextResourceSet : OutputStep<bool>
{
[UnityEngine.SerializeField]
SinglePort<double> _in = new();
[CareBoo.Serially.TypeFilter(derivedFrom: typeof(Resources.Resource<>))]
public CareBoo.Serially.SerializableType? Resource;
[CareBoo.Serially.TypeFilter(derivedFrom: typeof(ContextRegister<>))]
public CareBoo.Serially.SerializableType? Register;
public override IEnumerable<IPort> Inputs {
get {
yield return _in;
}
}
public override string ToString() {
var resourceName = Resource == null || Resource.Type == null ? "*" : Resource.Type.Name;
var registerName = Register == null || Register.Type == null ? "*" : Register.Type.Name;
return $"Context.Set.{resourceName}.{registerName}";
}
public override bool IsValid {
get {
return Register != null && Register.Type != null && Resource != null && Resource.Type != null;
}
}
public override bool Run(EffectInput Data) {
if (!IsValid || Resource == null || Register == null) {
UnityEngine.Debug.LogError($"{this} Inner types are null");
return false;
}
var getSpecificMethod = typeof(ContextResourceSet).GetMethod(nameof(SetSpecific), BindingFlags.NonPublic | BindingFlags.Instance).
MakeGenericMethod(Resource.Type, Resource.Type.BaseType.GetGenericArguments()[0], Register.Type);
var value = getSpecificMethod.Invoke(this, new object[] { Data });
return (bool)value;
}
bool SetSpecific<TResource, TUnitType, TContextRegister>(EffectInput blackBoard)
where TResource : Resources.Resource<TUnitType>
where TUnitType : Resources.IUnitType
where TContextRegister : IContextRegister {
var result = (_in.Node != null) ? _in.Node.Run(blackBoard) : default;
var success = false;
if (blackBoard != null) {
blackBoard.Context.SetResource<TResource, TUnitType, TContextRegister>((Resources.Unit<TUnitType>)result);
success = true;
}
return success;
}
public override EffectStepNodeData ToData() {
var effectStepNodeData = base.ToData();
effectStepNodeData.Resource = Resource;
effectStepNodeData.Register = Register;
return effectStepNodeData;
}
public override bool FromData(EffectStepNodeData effectStepNodeData, Dictionary<string, EffectStepNode> guidToNode) {
base.FromData(effectStepNodeData, guidToNode);
Resource = effectStepNodeData.Resource;
Register = effectStepNodeData.Register;
return true;
}
}
}