1
0
mirror of https://github.com/Siccity/xNode.git synced 2026-03-26 22:49:02 +08:00

Added support for user added dynamic ports (no attribute)

This commit is contained in:
Kailey Joanette 2019-10-06 15:31:49 -04:00
parent c39dda0701
commit a66926e777
6 changed files with 115 additions and 23 deletions

View File

@ -10,18 +10,17 @@ namespace XNodeEditor.Odin
{ {
internal abstract class AsDynamicPortAtribute : System.Attribute internal abstract class AsDynamicPortAtribute : System.Attribute
{ {
internal string fieldName { get; set; } public string FieldName { get; set; }
internal int index { get; set; } public Node Node { get; set; }
internal Node Node { get; set; }
internal ConnectionType connectionType { get; set; } public bool InList { get; set; }
internal ShowBackingValue backingValue { get; set; } public ShowBackingValue BackingValue { get; set; }
internal NodePort Port public NodePort Port
{ {
get get
{ {
return Node.GetPort( $"{fieldName} {index}" ); return Node.GetPort( FieldName );
} }
} }
} }
@ -31,19 +30,31 @@ namespace XNodeEditor.Odin
internal struct AsDynamicPortScope : IDisposable internal struct AsDynamicPortScope : IDisposable
{ {
public AsDynamicPortScope( NodePort port ) public AsDynamicPortScope( NodePort port, bool inList )
{ {
EditorGUILayout.BeginVertical(); EditorGUILayout.BeginVertical();
var rect = GUILayoutUtility.GetRect( 0f, float.MaxValue, 0f, 0f, GUI.skin.label, GUILayout.ExpandWidth( true ) ); var rect = GUILayoutUtility.GetRect( 0f, float.MaxValue, 0f, 0f, GUI.skin.label, GUILayout.ExpandWidth( true ) );
if ( NodeEditor.isNodeEditor ) if ( port != null && NodeEditor.isNodeEditor )
{ {
if ( port.IsInput ) if ( port.IsInput )
{ {
NodeEditorGUILayout.PortField( new Vector2( rect.xMin - 42, rect.center.y ), port ); Vector2 offset;
if ( inList )
offset = new Vector2( -42, 0 );
else
offset = new Vector2( -18, 0 );
NodeEditorGUILayout.PortField( new Vector2( rect.xMin, rect.center.y ) + offset, port );
} }
else else
{ {
NodeEditorGUILayout.PortField( new Vector2( rect.xMax + 21, rect.center.y ), port ); Vector2 offset;
if ( inList )
offset = new Vector2( 21, 0 );
else
offset = new Vector2( 0, 0 );
NodeEditorGUILayout.PortField( new Vector2( rect.xMax, rect.center.y ) + offset, port );
} }
} }
@ -67,7 +78,7 @@ namespace XNodeEditor.Odin
if ( Attribute.Port == null ) if ( Attribute.Port == null )
return; return;
using ( new AsDynamicPortScope( Attribute.Port ) ) using ( new AsDynamicPortScope( Attribute.Port, Attribute.InList ) )
CallNextDrawer( label ); CallNextDrawer( label );
} }
} }
@ -83,9 +94,9 @@ namespace XNodeEditor.Odin
return; return;
if ( Event.current.type == EventType.Layout ) if ( Event.current.type == EventType.Layout )
drawData = Attribute.backingValue == ShowBackingValue.Always || Attribute.backingValue == ShowBackingValue.Unconnected && !Attribute.Port.IsConnected; drawData = Attribute.BackingValue == ShowBackingValue.Always || Attribute.BackingValue == ShowBackingValue.Unconnected && !Attribute.Port.IsConnected;
using ( new AsDynamicPortScope( Attribute.Port ) ) using ( new AsDynamicPortScope( Attribute.Port, Attribute.InList ) )
{ {
if ( drawData ) if ( drawData )
CallNextDrawer( label ); CallNextDrawer( label );

View File

@ -14,7 +14,7 @@ namespace XNodeEditor.Odin
{ {
EditorGUILayout.BeginVertical(); EditorGUILayout.BeginVertical();
var rect = GUILayoutUtility.GetRect( 0f, float.MaxValue, 0f, 0f, GUI.skin.label, GUILayout.ExpandWidth( true ) ); var rect = GUILayoutUtility.GetRect( 0f, float.MaxValue, 0f, 0f, GUI.skin.label, GUILayout.ExpandWidth( true ) );
if ( NodeEditor.isNodeEditor ) if ( port != null && NodeEditor.isNodeEditor )
{ {
if ( port.IsInput ) if ( port.IsInput )
{ {

View File

@ -86,12 +86,11 @@ namespace XNodeEditor.Odin
{ {
return new AsDynamicPortWithDataAtribute() return new AsDynamicPortWithDataAtribute()
{ {
fieldName = fieldName, FieldName = string.Format( "{0} {1}", fieldName, index ),
index = index, InList = true,
Node = node, Node = node,
connectionType = connectionType, BackingValue = backingValue
backingValue = backingValue
}; };
} }

View File

@ -69,12 +69,11 @@ namespace XNodeEditor
{ {
return new AsDynamicPortNoDataAtribute() return new AsDynamicPortNoDataAtribute()
{ {
fieldName = fieldName, FieldName = string.Format( "{0} {1}", fieldName, index ),
index = index, InList = true,
Node = node, Node = node,
connectionType = connectionType, BackingValue = backingValue
backingValue = backingValue
}; };
} }

View File

@ -0,0 +1,72 @@
#if UNITY_EDITOR && ODIN_INSPECTOR
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using XNode;
using XNodeEditor.Odin;
using static XNode.Node;
namespace XNodeEditor
{
[ResolverPriority( -4 )]
public class FullyDynamicPortPropertyResolver<T> : BaseMemberPropertyResolver<T>
where T : Node
{
private List<OdinPropertyProcessor> processors;
protected override InspectorPropertyInfo[] GetPropertyInfos()
{
if ( this.processors == null )
{
this.processors = OdinPropertyProcessorLocator.GetMemberProcessors( this.Property );
}
var includeSpeciallySerializedMembers = this.Property.ValueEntry.SerializationBackend != SerializationBackend.Unity;
var infos = InspectorPropertyInfoUtility.CreateMemberProperties( this.Property, typeof( T ), includeSpeciallySerializedMembers );
for ( int i = 0; i < this.processors.Count; i++ )
{
ProcessedMemberPropertyResolverExtensions.ProcessingOwnerType = typeof( T );
this.processors[i].ProcessMemberProperties( infos );
}
// Find ports that aren't managed by an attribute
if ( this.Property.Tree.UnitySerializedObject.targetObjects.Length == 1 )
{
var node = Property.Tree.UnitySerializedObject.targetObject as Node;
var nodeType = typeof( T );
string error;
MemberInfo[] fieldsAndProperties;
nodeType.FindMember()
.IsFieldOrProperty()
.TryGetMembers( out fieldsAndProperties, out error );
var attributedMembers = fieldsAndProperties?.Where( x => x.GetAttribute<InputAttribute>() != null || x.GetAttribute<OutputAttribute>() != null );
foreach ( var port in node.DynamicPorts )
{
if ( attributedMembers.Any( x => port.fieldName.StartsWith( string.Format( "{0} ", x.Name ) ) ) )
continue;
// value can't possibly matter here so many this "lie" is ok
infos.AddValue( port.fieldName, () => 0, value => { },
new AsDynamicPortNoDataAtribute()
{
BackingValue = ShowBackingValue.Never,
FieldName = port.fieldName,
InList = false,
Node = node
}
);
}
}
return InspectorPropertyInfoUtility.BuildPropertyGroupsAndFinalize( this.Property, typeof( T ), infos, includeSpeciallySerializedMembers );
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 95e515f7b1abc3440b3e1a9f324f9187
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: