Changed Slot in RelayNode to ProxySlot;

Changed PullData and PushData from SlotExtension to ISlot;

Added BackTraceExecutableNode;

Removed IExecutable from RelayNode;
This commit is contained in:
Misaki
2024-11-10 12:28:12 +09:00
parent 994297a3f2
commit d3c5968a80
21 changed files with 398 additions and 281 deletions

View File

@@ -17,6 +17,8 @@ namespace Misaki.GraphView
private List<SlotConnection> _connections = new();
[SerializeReference]
private List<ExposedProperty> _exposedProperties = new();
[SerializeField]
private List<NodeGroupData> nodeGroupDatas = new();
private readonly Dictionary<string, DataNode> _nodeMap = new();
@@ -24,6 +26,7 @@ namespace Misaki.GraphView
public ReadOnlyCollection<StickyNoteData> StickyNotes => _stickyNotes.AsReadOnly();
public ReadOnlyCollection<SlotConnection> Connections => _connections.AsReadOnly();
public ReadOnlyCollection<ExposedProperty> ExposedProperties => _exposedProperties.AsReadOnly();
public ReadOnlyCollection<NodeGroupData> NodeGroupDatas => nodeGroupDatas.AsReadOnly();
public Vector3 graphPosition;
public Vector3 graphScale = Vector3.one;

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
namespace Misaki.GraphView
{
[Serializable]
public struct NodeGroupData
{
public string id;
public string name;
public List<string> nodeIds;
public NodeGroupData(string groupName)
{
id = Guid.NewGuid().ToString();
name = groupName;
nodeIds = new List<string>();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fcd834a0bef681248b79c1cc4648c27e

View File

@@ -4,16 +4,12 @@ using UnityEngine;
namespace Misaki.GraphView
{
[Serializable]
public class RelayNode : DataNode, ISlotContainer, IExecutable
public class RelayNode : DataNode, ISlotContainer
{
[SerializeField]
private Slot _inputSlot;
private ProxySlot _inputSlot;
[SerializeField]
private Slot _outputSlot;
private bool _isExecuted;
public bool IsExecuted => _isExecuted;
private ProxySlot _outputSlot;
public string portValueType;
@@ -21,7 +17,7 @@ namespace Misaki.GraphView
{
base.Initialize(graph);
_inputSlot = new Slot(this, new SlotData
_inputSlot = new(this, new SlotData
{
slotName = "Input",
nodeID = Id,
@@ -29,8 +25,7 @@ namespace Misaki.GraphView
direction = SlotDirection.Input,
valueType = typeof(object).FullName
});
_outputSlot = new Slot(this, new SlotData
_outputSlot = new(this, new SlotData
{
slotName = "Output",
nodeID = Id,
@@ -42,22 +37,39 @@ namespace Misaki.GraphView
portValueType = typeof(object).FullName;
}
///// <summary>
///// Bind the slot to the relay node.
///// </summary>
///// <param name="slot"> <see cref="ISlot"/> The slot want to bind to current relay node </param>
//public void BindSlot(ISlot slot)
//{
// switch (slot.SlotData.direction)
// {
// case SlotDirection.Input:
// _inputSlot.Bind(slot);
// break;
// case SlotDirection.Output:
// _outputSlot.Bind(slot);
// break;
// }
//}
/// <summary>
/// Bind the slot to the relay node.
/// </summary>
/// <param name="slot"> <see cref="ISlot"/> The slot want to bind to current relay node </param>
public void BindSlot(ISlot slot)
{
switch (slot.SlotData.direction)
{
case SlotDirection.Input:
_inputSlot.Bind(slot);
break;
case SlotDirection.Output:
_outputSlot.Bind(slot);
break;
}
}
/// <summary>
/// Unbind the slot from the relay node.
/// </summary>
/// <param name="direction"> The direction of the slot </param>
public void UnbindSlot(SlotDirection direction)
{
switch (direction)
{
case SlotDirection.Input:
_inputSlot.Unbind();
break;
case SlotDirection.Output:
_outputSlot.Unbind();
break;
}
}
public ISlot GetSlot(int index, SlotDirection direction)
{
@@ -75,23 +87,12 @@ namespace Misaki.GraphView
_outputSlot.UnlinkAll();
}
public void Execute()
public override void Dispose()
{
if (_isExecuted)
{
return;
}
base.Dispose();
_inputSlot.PullData(null);
_outputSlot.ReceiveData(_inputSlot.Data);
_outputSlot.PushData(null);
_isExecuted = true;
}
public void ClearExecutionFlag()
{
_isExecuted = false;
_inputSlot.Unbind();
_outputSlot.Unbind();
}
}
}

View File

@@ -8,37 +8,76 @@ namespace Misaki.GraphView
public class ProxySlot : ISlot
{
[SerializeReference]
private ISlot _slot;
private ISlot _masterSlot;
public SlotData SlotData => _slot == null ? default : _slot.SlotData;
public List<SlotData> LinkedSlotDatas => _slot?.LinkedSlotDatas;
public bool IsLinked => LinkedSlotDatas?.Count > 0;
public DataNode Owner => _slot?.Owner;
public object Data => _slot?.Data;
[SerializeField]
private SlotData _slotData;
[SerializeField]
private List<SlotData> _linkedSlotDatas = new();
[SerializeReference]
private DataNode _owner;
public SlotData SlotData => _slotData;
public List<SlotData> LinkedSlotDatas => _linkedSlotDatas;
public bool IsLinked => _linkedSlotDatas.Count > 0;
public DataNode Owner => _owner;
public ISlot MasterSlot => _masterSlot;
public object Data => _masterSlot?.Data;
public ProxySlot(DataNode owner, SlotData slotData)
{
_owner = owner;
_slotData = slotData;
}
public void Bind(ISlot slot)
{
_slot = slot;
_masterSlot = slot;
_slotData.direction = slot.SlotData.direction;
_slotData.valueType = slot.SlotData.valueType;
}
public void Unbind()
{
_masterSlot = null;
}
public bool Link(ISlot other, out SlotConnection connection)
{
if (_slot == null)
connection = new(_slotData, other.SlotData);
if (other.SlotData.direction == _slotData.direction ||
_linkedSlotDatas.Contains(other.SlotData) ||
_masterSlot == null)
{
connection = default;
return false;
}
return _slot.Link(other, out connection);
_linkedSlotDatas.Add(other.SlotData);
return _masterSlot.Link(other, out _);
}
public void Unlink(ISlot other)
{
_slot?.Unlink(other);
_linkedSlotDatas.Remove(other.SlotData);
_masterSlot?.Unlink(other);
}
public void PullData(Action<ISlot> OnPullData)
{
_masterSlot.PullData(OnPullData);
}
public void PushData(Action<ISlot> OnPushData)
{
_masterSlot.PushData(OnPushData);
}
public void ReceiveData(object data)
{
_slot?.ReceiveData(data);
_masterSlot?.ReceiveData(data);
}
}
}

View File

@@ -4,56 +4,21 @@ using UnityEngine;
namespace Misaki.GraphView
{
[Serializable]
public struct SlotData : IEquatable<SlotData>
{
public string slotName;
public string nodeID;
public int slotIndex;
public SlotDirection direction;
public string valueType;
public bool Equals(SlotData other)
{
return slotName == other.slotName && nodeID == other.nodeID && slotIndex == other.slotIndex && direction == other.direction && valueType == other.valueType;
}
public override bool Equals(object obj)
{
return obj is SlotData other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(slotName, nodeID, slotIndex, direction, valueType);
}
public static bool operator ==(SlotData left, SlotData right)
{
return left.Equals(right);
}
public static bool operator !=(SlotData left, SlotData right)
{
return !left.Equals(right);
}
}
[Serializable]
public class Slot : ISlot
{
[SerializeField]
private SlotData _slotData;
[SerializeField]
private List<SlotData> _linkedSlotData = new();
private List<SlotData> _linkedSlotDatas = new();
[SerializeReference]
private DataNode _owner;
private object _data;
public SlotData SlotData => _slotData;
public List<SlotData> LinkedSlotDatas => _linkedSlotData;
public bool IsLinked => _linkedSlotData.Count > 0;
public List<SlotData> LinkedSlotDatas => _linkedSlotDatas;
public bool IsLinked => _linkedSlotDatas.Count > 0;
public DataNode Owner => _owner;
public object Data => _data;
@@ -66,31 +31,86 @@ namespace Misaki.GraphView
/// <inheritdoc/>
public bool Link(ISlot other, out SlotConnection connection)
{
connection = default;
if (other.SlotData.direction == _slotData.direction)
{
return false;
}
if (_linkedSlotData.Contains(other.SlotData))
{
return false;
}
_linkedSlotData.Add(other.SlotData);
other.LinkedSlotDatas.Add(_slotData);
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;
}
/// <inheritdoc/>
public void Unlink(ISlot other)
{
_linkedSlotData.Remove(other.SlotData);
_linkedSlotDatas.Remove(other.SlotData);
other.LinkedSlotDatas.Remove(_slotData);
}
/// <inheritdoc/>
public void PullData(Action<ISlot> 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<ISlot> 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();
}
}
}
/// <inheritdoc/>
public void ReceiveData(object data)
{

View File

@@ -0,0 +1,39 @@
using System;
namespace Misaki.GraphView
{
[Serializable]
public struct SlotData : IEquatable<SlotData>
{
public string slotName;
public string nodeID;
public int slotIndex;
public SlotDirection direction;
public string valueType;
public bool Equals(SlotData other)
{
return slotName == other.slotName && nodeID == other.nodeID && slotIndex == other.slotIndex && direction == other.direction && valueType == other.valueType;
}
public override bool Equals(object obj)
{
return obj is SlotData other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(slotName, nodeID, slotIndex, direction, valueType);
}
public static bool operator ==(SlotData left, SlotData right)
{
return left.Equals(right);
}
public static bool operator !=(SlotData left, SlotData right)
{
return !left.Equals(right);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0895a7c121619ff4986f686264e1afa2