using System; using System.Collections.Generic; using UnityEngine; namespace Misaki.GraphView { [Serializable] public class Slot : ISlot { [SerializeField] private SlotData _slotData; [SerializeField] private List _linkedSlotDatas = new(); [SerializeReference] private DataNode _owner; private object _data; public SlotData SlotData => _slotData; public List LinkedSlotDatas => _linkedSlotDatas; public bool IsLinked => _linkedSlotDatas.Count > 0; public DataNode Owner => _owner; public object Data => _data; public Slot(DataNode owner, SlotData slotData) { _owner = owner; _slotData = slotData; } /// public bool Link(ISlot other, out SlotConnection connection) { connection = new(_slotData, other.SlotData); if (other.SlotData.direction == _slotData.direction || _linkedSlotDatas.Contains(other.SlotData)) { return false; } _linkedSlotDatas.Add(other.SlotData); other.LinkedSlotDatas.Add(_slotData); return true; } /// public void Unlink(ISlot other) { _linkedSlotDatas.Remove(other.SlotData); other.LinkedSlotDatas.Remove(_slotData); } /// public void PullData(Action OnPullData) { if (_slotData.direction == SlotDirection.Output) { return; } OnPullData?.Invoke(this); var property = _owner.GetType().GetField(_slotData.slotName, ConstResource.NODE_FIELD_BINDING_FLAGS); if (IsLinked && property != null) { property?.SetValue(_owner, _data); } } public void PushData(Action OnPushData) { if (_slotData.direction == SlotDirection.Input) { return; } var property = _owner.GetType().GetField(_slotData.slotName, ConstResource.NODE_FIELD_BINDING_FLAGS); if (property != null) { ReceiveData(property.GetValue(_owner)); } OnPushData?.Invoke(this); foreach (var connectedSlotData in _linkedSlotDatas) { var node = _owner.GraphObject.GetNode(connectedSlotData.nodeID); if (node is not ISlotContainer slotContainer) { continue; } var connectedSlot = slotContainer.GetSlot(connectedSlotData.slotIndex, connectedSlotData.direction); if (connectedSlotData.GetValueType() == _slotData.GetValueType() || _slotData.GetValueType() == typeof(object) || connectedSlotData.GetValueType() == typeof(object)) { connectedSlot.ReceiveData(_data); } else if (_owner.GraphObject.ValueConverterManager != null && _owner.GraphObject.ValueConverterManager.TryConvert(_slotData.GetValueType(), connectedSlotData.GetValueType(), _data, out var data)) { connectedSlot.ReceiveData(data); } else { _owner.GraphObject.Logger?.LogError(_owner, $"Failed to convert value from {_slotData.valueType} to {connectedSlotData.valueType}"); _owner.GraphObject.GraphProcessor.Break(); } } } /// public void ReceiveData(object data) { _data = data; } } }