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