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:
parent
c39dda0701
commit
a66926e777
@ -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 );
|
||||||
|
|||||||
@ -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 )
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 95e515f7b1abc3440b3e1a9f324f9187
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Loading…
x
Reference in New Issue
Block a user