Added IExecutable and ISlotContainer interface.
Changed SlotContainerNode to ExecutableNode
This commit is contained in:
3
Editor/Views/BaseClasses.meta
Normal file
3
Editor/Views/BaseClasses.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e395d546cad54c19a0f7bcd3c700f3c8
|
||||
timeCreated: 1730721678
|
||||
3
Editor/Views/Blackboard.meta
Normal file
3
Editor/Views/Blackboard.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3eccc1eae4c41168ddac1b27a18a4aa
|
||||
timeCreated: 1730721637
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
3
Editor/Views/Inspector.meta
Normal file
3
Editor/Views/Inspector.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a9b88871c5c4e728c7d39476e3e4571
|
||||
timeCreated: 1730721654
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user