using System;
using System.Collections.Generic;
namespace Misaki.GraphView
{
public static class SlotExtension
{
///
/// Unlink all slots from this slot.
///
/// The slot to unlink all connections from.
public static void UnlinkAll(this Slot slot)
{
var slotCount = slot.LinkedSlotData.Count;
for (var i = 0; i < slotCount; i++)
{
var other = slot.LinkedSlotData[i];
var otherNode = slot.owner.GraphObject.GetNode(other.nodeID);
if (otherNode is ISlotContainer slotContainer)
{
slotContainer.GetSlot(other.slotIndex, other.direction)?.Unlink(slot);
}
}
}
///
/// Get the value type of the slot data.
///
/// The slot data to get the value type from.
/// The type of the slot value.
public static Type GetValueType(this SlotData slotData)
{
return Type.GetType(slotData.valueType);
}
public static void ReceiveData(this Slot slot, object data)
{
slot.value = data;
}
///
/// Pull data from the slot and execute the provided action.
///
/// The slot to pull data from.
/// The action to execute when pulling data.
public static void PullData(this Slot slot, Action OnPullData)
{
var property = slot.owner.GetType().GetField(slot.slotData.slotName, ConstResource.NODE_FIELD_BINDING_FLAGS);
if (property == null)
{
return;
}
OnPullData(slot);
if (slot.LinkedSlotData.Count == 0)
{
return;
}
property.SetValue(slot.owner, slot.value);
}
///
/// Push data to the slot and execute the provided action.
///
/// The slot to push data to.
/// The action to execute when pushing data.
public static void PushData(this Slot slot, Action OnPushData)
{
var property = slot.owner.GetType().GetField(slot.slotData.slotName, ConstResource.NODE_FIELD_BINDING_FLAGS);
if (property == null)
{
return;
}
OnPushData(slot);
slot.value = property.GetValue(slot.owner);
foreach (var slotData in slot.LinkedSlotData)
{
var node = slot.owner.GraphObject.GetNode(slotData.nodeID);
if (node is not ISlotContainer slotContainer)
{
continue;
}
var otherSlot = slotContainer.GetSlot(slotData.slotIndex, slotData.direction);
if (slotData.GetValueType() == slot.slotData.GetValueType() || slot.slotData.GetValueType() == typeof(object))
{
otherSlot.ReceiveData(slot.value);
}
else if (slot.owner.GraphObject.ValueConverterManager != null && slot.owner.GraphObject.ValueConverterManager.TryConvert(slot.slotData.GetValueType(),
slotData.GetValueType(), slot.value, out var data))
{
otherSlot.ReceiveData(data);
}
else
{
slot.owner.GraphObject.Logger?.LogError(slot.owner, $"Failed to convert value from {otherSlot.slotData.valueType} to {slotData.valueType}");
}
}
}
///
/// Pull data from a collection of slots and execute the provided action.
///
/// The collection of slots to pull data from.
/// The action to execute when pulling data.
public static void PullData(this IEnumerable slots, Action OnPullData)
{
foreach (var slot in slots)
{
slot.PullData(OnPullData);
}
}
///
/// Push data to a collection of slots and execute the provided action.
///
/// The collection of slots to push data to.
/// The action to execute when pushing data.
public static void PushData(this IEnumerable slots, Action OnPushData)
{
foreach (var slot in slots)
{
slot.PushData(OnPushData);
}
}
}
}