Added IExecutable and ISlotContainer interface.

Changed SlotContainerNode to ExecutableNode
This commit is contained in:
Misaki
2024-11-05 02:25:15 +09:00
parent 7eec130b39
commit c853994bf5
51 changed files with 443 additions and 400 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e395d546cad54c19a0f7bcd3c700f3c8
timeCreated: 1730721678

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a3eccc1eae4c41168ddac1b27a18a4aa
timeCreated: 1730721637

View File

@@ -1,8 +1,5 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace Misaki.GraphView.Editor
@@ -19,6 +16,8 @@ namespace Misaki.GraphView.Editor
_editor = editor;
}
public override bool IsDroppable() => true;
public override void OnSelected()
{
base.OnSelected();
@@ -31,7 +30,7 @@ namespace Misaki.GraphView.Editor
OnItemSelected?.Invoke(null);
}
public virtual EditorNodeView CreateNodeView()
public virtual ExecutableNodeView CreateNodeView()
{
return null;
}

View File

@@ -70,7 +70,7 @@ namespace Misaki.GraphView.Editor
exposedProperty.propertyName = newValue;
_owner.Query<PropertyInputNodeView>().ForEach(n =>
{
if (n.DataNode.Property.Equals(exposedProperty))
if (n.Data.Property.Equals(exposedProperty))
{
n.title = newValue;
}

View File

@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

View File

@@ -33,7 +33,7 @@ namespace Misaki.GraphView.Editor
gridBackground.SendToBack();
var minimapConfig = _graphViewConfig.miniMapConfig;
if (minimapConfig != null && minimapConfig.enable)
if (minimapConfig is { enable: true })
{
var minimap = new MiniMap()
{
@@ -76,8 +76,11 @@ namespace Misaki.GraphView.Editor
InitializeAssetElements();
graphViewChanged += OnGraphViewChanged;
RegisterCallback<DragPerformEvent>(OnDragPerform);
RegisterCallbackOnce<GeometryChangedEvent>(_ => _graphInspectorView?.DockToParent(layout, DockingPosition.Right, false));
}
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
base.BuildContextualMenu(evt);
@@ -125,10 +128,6 @@ namespace Misaki.GraphView.Editor
{
AddConnectionView(connection);
}
RegisterCallback<DragPerformEvent>(OnDragPerform);
RegisterCallbackOnce<GeometryChangedEvent>(_ => _graphInspectorView?.DockToParent(layout, DockingPosition.Right, false));
}
private GraphViewChange OnGraphViewChanged(GraphViewChange graphViewChange)
@@ -140,7 +139,7 @@ namespace Misaki.GraphView.Editor
for (var i = removedElements.Count - 1; i >= 0; i--)
{
if (removedElements[i] is Node { userData: SlotContainerNode node })
if (removedElements[i] is Node { userData: ExecutableNode node })
{
RemoveNode(node);
}
@@ -154,14 +153,17 @@ namespace Misaki.GraphView.Editor
{
if (_slotConnections.Remove(edge, out var connection))
{
var inputSlotData = connection.InputSlotData;
var outputSlotData = connection.OutputSlotData;
var inputSlot = _graphObject.GetNode(inputSlotData.nodeID)
.GetSlot(inputSlotData.slotIndex, inputSlotData.direction);
var outputSlot = _graphObject.GetNode(outputSlotData.nodeID)
.GetSlot(outputSlotData.slotIndex, outputSlotData.direction);
var inputNode = _graphObject.GetNode(connection.InputSlotData.nodeID);
var outputNode = _graphObject.GetNode(connection.OutputSlotData.nodeID);
if (inputNode is ISlotContainer inputSlotContainer && outputNode is ISlotContainer outputSlotContainer)
{
var inputSlot = inputSlotContainer.GetSlot(connection.InputSlotData.slotIndex, connection.InputSlotData.direction);
var outputSlot = outputSlotContainer.GetSlot(connection.OutputSlotData.slotIndex, connection.OutputSlotData.direction);
inputSlot.Unlink(outputSlot);
}
inputSlot.Unlink(outputSlot);
RemoveConnection(connection);
}
}
@@ -230,55 +232,50 @@ namespace Misaki.GraphView.Editor
private void OnDragPerform(DragPerformEvent evt)
{
var data = DragAndDrop.GetGenericData("DragSelection");
if (data is List<ExposedProperty> properties)
if (data is List<ISelectable> selectables)
{
var position = contentViewContainer.WorldToLocal(evt.mousePosition);
foreach (var property in properties)
var propertyViews = selectables.OfType<BlackboardPropertyView>().ToArray();
if (propertyViews.Length <= 0)
{
var baseNode = new PropertyInputNode(property);
baseNode.position = new Rect(position, Vector2.zero);
return;
}
var position = (evt.currentTarget as VisualElement).ChangeCoordinatesTo(contentViewContainer, evt.localMousePosition);
foreach (var view in propertyViews)
{
if (view.userData is not ExposedProperty property)
{
continue;
}
var baseNode = new PropertyInput(property)
{
position = new Rect(position, Vector2.zero)
};
AddNode(baseNode);
}
}
}
public void AddNode(SlotContainerNode slotContainerNode)
public void AddNode(ExecutableNode executableNode)
{
Undo.RecordObject(_graphObject, $"Add {slotContainerNode.GetType().Name}");
Undo.RecordObject(_graphObject, $"Add {executableNode.GetType().Name}");
_graphObject.AddNode(slotContainerNode);
AddNodeView(slotContainerNode);
_graphObject.AddNode(executableNode);
AddNodeView(executableNode);
EditorUtility.SetDirty(_graphObject);
}
public virtual void AddNodeView(SlotContainerNode slotContainerNode)
private void AddNodeView(DataNode node)
{
Node nodeView;
var types = TypeCache.GetTypesWithAttribute<CustomInspectorAttribute>();
var type = types.FirstOrDefault(t =>
t.GetCustomAttribute<CustomInspectorAttribute>().InspectorType == slotContainerNode.GetType());
if (slotContainerNode is PropertyInputNode propertyInputNode)
{
// type ??= typeof(PropertyInputNodeView);
// var slot = propertyInputNode.GetSlot(0, SlotDirection.Output);
// nodeView = Activator.CreateInstance(type, propertyInputNode, _graphViewConfig.portColorManager) as PropertyInputNodeView;
nodeView = PropertyInputNodeView.Create(propertyInputNode, _graphViewConfig.portColorManager);
}
else
{
type ??= typeof(EditorNodeView);
nodeView = Activator.CreateInstance(type, slotContainerNode, _graphViewConfig.serializedObject, _graphViewConfig.portColorManager, _graphObject.Logger) as EditorNodeView;
}
var nodeView = CreateNodeView(node);
if (nodeView == null)
{
return;
}
nodeView.SetPosition(slotContainerNode.position);
nodeView.SetPosition(node.position);
if (nodeView is IInspectable inspectable)
{
@@ -286,22 +283,41 @@ namespace Misaki.GraphView.Editor
}
AddElement(nodeView);
_nodeViewsMap.Add(slotContainerNode.Id, nodeView);
_nodeViewsMap.Add(node.Id, nodeView);
}
protected virtual Node CreateNodeView(DataNode node)
{
var types = TypeCache.GetTypesWithAttribute<CustomInspectorAttribute>();
var type = types.FirstOrDefault(t =>
t.GetCustomAttribute<CustomInspectorAttribute>().InspectorType == node.GetType());
if (node is PropertyInput propertyInputNode)
{
return PropertyInputNodeView.Create(propertyInputNode, _graphViewConfig.portColorManager);
}
else if (node is ExecutableNode executableNode)
{
type ??= typeof(ExecutableNodeView);
return Activator.CreateInstance(type, executableNode, _graphViewConfig.serializedObject, _graphViewConfig.portColorManager, _graphObject.Logger) as ExecutableNodeView;
}
return null;
}
private void RemoveNode(SlotContainerNode slotContainerNode)
private void RemoveNode(ExecutableNode executableNode)
{
Undo.RecordObject(_graphObject, $"Remove {slotContainerNode.GetType().Name}");
Undo.RecordObject(_graphObject, $"Remove {executableNode.GetType().Name}");
_graphObject.RemoveNode(slotContainerNode);
RemoveNodeView(slotContainerNode);
_graphObject.RemoveNode(executableNode);
RemoveNodeView(executableNode);
EditorUtility.SetDirty(_graphObject);
}
private void RemoveNodeView(SlotContainerNode slotContainerNode)
private void RemoveNodeView(ExecutableNode executableNode)
{
if (_nodeViewsMap.Remove(slotContainerNode.Id, out var nodeView))
if (_nodeViewsMap.Remove(executableNode.Id, out var nodeView))
{
RemoveElement(nodeView);

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6a9b88871c5c4e728c7d39476e3e4571
timeCreated: 1730721654

View File

@@ -8,7 +8,7 @@ namespace Misaki.GraphView.Editor
{
public sealed class GraphInspectorView : GraphSubWindow
{
private const string UIDocumentPath = "Packages/com.misaki.graph-view/Editor/Views/GraphInspectorView.uxml";
private const string UI_Document_Path = "Packages/com.misaki.graph-view/Editor/Views/Inspector/GraphInspectorView.uxml";
private readonly Label _header;
private readonly VisualElement _inspectorPropertiesContainer;
@@ -21,7 +21,7 @@ namespace Misaki.GraphView.Editor
style.minWidth = 300;
style.minHeight = 500;
var uiDocument = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(UIDocumentPath);
var uiDocument = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(UI_Document_Path);
var inspectorView = uiDocument.Instantiate();
inspectorView.style.flexGrow = 1;

View File

@@ -10,9 +10,9 @@ using UnityEngine.UIElements;
namespace Misaki.GraphView.Editor
{
public class EditorNodeView : Node, IInspectable, IPortContainer
public class ExecutableNodeView : Node, IInspectable, IPortContainer
{
private readonly SlotContainerNode _dataNode;
private readonly ExecutableNode _dataNode;
private readonly Type _nodeType;
private readonly NodeInfoAttribute _nodeInfo;
@@ -24,7 +24,6 @@ namespace Misaki.GraphView.Editor
private readonly VisualElement _logContainer = new();
public SlotContainerNode DataNode => _dataNode;
public List<Port> InputPorts => _inputPorts;
public List<Port> OutputPorts => _outputPorts;
@@ -32,7 +31,7 @@ namespace Misaki.GraphView.Editor
public string InspectorName => _nodeInfo.Name ?? _nodeType.Name;
public EditorNodeView(SlotContainerNode dataNode, SerializedObject serializedObject, IPortColorManager portColorManager, ILogger logger)
public ExecutableNodeView(ExecutableNode dataNode, SerializedObject serializedObject, IPortColorManager portColorManager, ILogger logger)
{
if (dataNode == null)
{
@@ -59,7 +58,7 @@ namespace Misaki.GraphView.Editor
AddToClassList(depth.ToLower().Replace(" ", "-"));
}
var inputs = _nodeType.GetProperty(nameof(SlotContainerNode.Inputs));
var inputs = _nodeType.GetProperty(nameof(ExecutableNode.Inputs));
if (inputs != null)
{
@@ -78,7 +77,7 @@ namespace Misaki.GraphView.Editor
}
}
var outputs = _nodeType.GetProperty(nameof(SlotContainerNode.Outputs));
var outputs = _nodeType.GetProperty(nameof(ExecutableNode.Outputs));
if (outputs != null)
{
@@ -101,14 +100,14 @@ namespace Misaki.GraphView.Editor
Add(_logContainer);
_dataNode.OnExecuteFlagCleared += OnExecuteFlagCleared;
_dataNode.OnExecutionFailed += (_) => AddToClassList("node-execution-failed");
_dataNode.OnExecutionFailed += () => AddToClassList("node-execution-failed");
if (logger != null)
{
logger.OnLog += CreateLogElement;
}
}
private void CreateLogElement(SlotContainerNode node, string message, LogType type)
private void CreateLogElement(ExecutableNode node, string message, LogType type)
{
if (node.Id != _dataNode.Id)
{

View File

@@ -11,38 +11,38 @@ namespace Misaki.GraphView.Editor
{
private readonly List<Port> _outputPorts = new List<Port>();
private readonly PropertyInputNode _dataNode;
private readonly PropertyInput _data;
//private readonly ExposedPropertyEditor _editor;
public PropertyInputNode DataNode => _dataNode;
public PropertyInput Data => _data;
public List<Port> InputPorts => null;
public List<Port> OutputPorts => _outputPorts;
public PropertyInputNodeView(PropertyInputNode dataNode, Port output) : base(null, output)
public PropertyInputNodeView(PropertyInput data, Port output) : base(null, output)
{
_dataNode = dataNode;
_data = data;
//_editor = editor;
name = dataNode.Property.propertyName;
title = dataNode.Property.propertyName;
userData = dataNode;
name = data.Property.propertyName;
title = data.Property.propertyName;
userData = data;
this.Q<VisualElement>("top").style.minHeight = 24;
_outputPorts.Add(output);
}
public static PropertyInputNodeView Create(PropertyInputNode dataNode, IPortColorManager portColorManager)
public static PropertyInputNodeView Create(PropertyInput data, IPortColorManager portColorManager)
{
if (dataNode == null)
if (data == null)
{
return null;
}
var outputSlot = dataNode.GetSlot(0, SlotDirection.Output);
var outputPort = CreateOutputPort(dataNode.Property, outputSlot, portColorManager);
var nodeView = new PropertyInputNodeView(dataNode, outputPort);
var outputSlot = data.GetSlot(0, SlotDirection.Output);
var outputPort = CreateOutputPort(data.Property, outputSlot, portColorManager);
var nodeView = new PropertyInputNodeView(data, outputPort);
return nodeView;
}
@@ -68,12 +68,12 @@ namespace Misaki.GraphView.Editor
return port;
}
public string InspectorName => _dataNode.Property.propertyName;
public string InspectorName => _data.Property.propertyName;
public override void SetPosition(Rect newPos)
{
base.SetPosition(newPos);
_dataNode.position = newPos;
_data.position = newPos;
}
}
}