Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class InvocationInspector : Inspector
|
||||
{
|
||||
protected InvocationInspector(Metadata metadata) : base(metadata) { }
|
||||
|
||||
protected Metadata argumentsMetadata => metadata["_" + nameof(MemberInvocation.arguments)];
|
||||
|
||||
protected IList<Metadata> parameters => argumentsMetadata.children;
|
||||
|
||||
public virtual Type expectedType { get; set; }
|
||||
|
||||
protected virtual IEnumerable<GUIContent> compactLabels => parameters.Select(p => p.label);
|
||||
|
||||
protected void PrepareParameterLabel(Metadata parameter, string label, string tooltip)
|
||||
{
|
||||
if (StringUtility.IsNullOrWhiteSpace(label))
|
||||
{
|
||||
label = "(?)";
|
||||
}
|
||||
|
||||
parameter.label.text = label;
|
||||
parameter.label.tooltip = tooltip;
|
||||
}
|
||||
|
||||
protected void PrepareParameterInspector(Metadata parameter, Type expectedType)
|
||||
{
|
||||
parameter.Inspector<IExpressionInspector>().expectedType = expectedType;
|
||||
}
|
||||
|
||||
protected float GetParametersHeight(float width)
|
||||
{
|
||||
var height = 0f;
|
||||
|
||||
using (LudiqGUIUtility.labelWidth.Override(GetCompactLabelsWidth(width)))
|
||||
{
|
||||
for (var i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
var parameter = parameters[i];
|
||||
|
||||
height += GetParameterHeight(parameter, width);
|
||||
|
||||
if (i < parameters.Count - 1)
|
||||
{
|
||||
height += Styles.spaceBetweenParameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
protected float GetCompactLabelsWidth(float width)
|
||||
{
|
||||
var compactLabelsWidth = 0f;
|
||||
|
||||
foreach (var compactLabel in compactLabels)
|
||||
{
|
||||
compactLabelsWidth = Mathf.Max(compactLabelsWidth, Styles.compactLabel.CalcSize(compactLabel).x);
|
||||
}
|
||||
|
||||
compactLabelsWidth = Mathf.Min(compactLabelsWidth, width / 3);
|
||||
|
||||
return compactLabelsWidth;
|
||||
}
|
||||
|
||||
protected virtual float GetParameterHeight(Metadata parameter, float width)
|
||||
{
|
||||
return InspectorGUI.GetHeight(parameter, width, parameter.label, this);
|
||||
}
|
||||
|
||||
protected virtual void OnParameterGUI(Rect parameterPosition, Metadata parameter)
|
||||
{
|
||||
InspectorGUI.Field(parameter, parameterPosition, parameter.label);
|
||||
}
|
||||
|
||||
protected void OnParametersGUI(Rect position)
|
||||
{
|
||||
if (parameters.Any())
|
||||
{
|
||||
using (LudiqGUIUtility.labelWidth.Override(GetCompactLabelsWidth(position.width)))
|
||||
{
|
||||
for (var i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
var parameter = parameters[i];
|
||||
|
||||
var parameterPosition = position.VerticalSection(ref y, GetParameterHeight(parameter, position.width));
|
||||
|
||||
OnParameterGUI(parameterPosition, parameter);
|
||||
|
||||
if (i < parameters.Count - 1)
|
||||
{
|
||||
y += Styles.spaceBetweenParameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Styles
|
||||
{
|
||||
static Styles()
|
||||
{
|
||||
compactLabel = new GUIStyle(EditorStyles.label);
|
||||
var padding = compactLabel.padding;
|
||||
padding.right += labelPadding;
|
||||
compactLabel.padding = padding;
|
||||
}
|
||||
|
||||
public static readonly float spaceBetweenParameters = EditorGUIUtility.standardVerticalSpacing;
|
||||
public static readonly float spaceAfterLabel = 0;
|
||||
public static readonly int labelPadding = 3;
|
||||
public static readonly GUIStyle compactLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 99c3d3d722538449ea1c09230a82c731
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Inspector(typeof(MemberInvocation))]
|
||||
public sealed class MemberInvocationInspector : InvocationInspector
|
||||
{
|
||||
public MemberInvocationInspector(Metadata metadata) : base(metadata) { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
memberInspector = memberMetadata.Inspector<MemberManipulatorInspector>();
|
||||
memberInspector.direction = (ActionDirection)directionMetadata.value;
|
||||
|
||||
referenceInspectors = new Dictionary<Metadata, Inspector>();
|
||||
memberFilter = metadata.GetAttribute<MemberFilter>() ?? MemberFilter.Any;
|
||||
memberTypeFilter = metadata.GetAttribute<TypeFilter>();
|
||||
memberMetadata.valueChanged += previousMember => ReflectMember(false);
|
||||
}
|
||||
|
||||
private MemberManipulatorInspector memberInspector;
|
||||
|
||||
private Dictionary<Metadata, Inspector> referenceInspectors;
|
||||
|
||||
private IFuzzyOptionTree GetMemberOptions()
|
||||
{
|
||||
return new MemberOptionTree(typeSet, memberFilter, memberTypeFilter, (ActionDirection)directionMetadata.value);
|
||||
}
|
||||
|
||||
#region Metadata
|
||||
|
||||
private Metadata memberMetadata => metadata[nameof(MemberInvocation.member)];
|
||||
|
||||
private Metadata directionMetadata => metadata[nameof(MemberInvocation.direction)];
|
||||
|
||||
private Metadata targetMetadata => metadata[nameof(MemberInvocation.target)];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Settings
|
||||
|
||||
private ReadOnlyCollection<Type> _typeSet;
|
||||
|
||||
private MemberFilter _memberFilter;
|
||||
|
||||
private TypeFilter _memberTypeFilter;
|
||||
|
||||
public override Type expectedType
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.expectedType;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.expectedType = value;
|
||||
memberTypeFilter = value != null ? new TypeFilter(TypesMatching.Any, value) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<Type> typeSet
|
||||
{
|
||||
get
|
||||
{
|
||||
return _typeSet;
|
||||
}
|
||||
set
|
||||
{
|
||||
_typeSet = value;
|
||||
memberInspector.typeSet = value;
|
||||
}
|
||||
}
|
||||
|
||||
public MemberFilter memberFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return _memberFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
_memberFilter = value;
|
||||
memberInspector.memberFilter = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeFilter memberTypeFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return _memberTypeFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
_memberTypeFilter = value;
|
||||
memberInspector.memberTypeFilter = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reflection
|
||||
|
||||
private bool reflectionSucceeded;
|
||||
|
||||
private void ReflectMember(bool reset)
|
||||
{
|
||||
memberMetadata.DisposeChildren();
|
||||
|
||||
var member = (Member)memberMetadata.value;
|
||||
|
||||
// Clear the metadata tree and optionally the arguments
|
||||
|
||||
if (reset)
|
||||
{
|
||||
targetMetadata.value = null;
|
||||
argumentsMetadata.Clear();
|
||||
}
|
||||
|
||||
referenceInspectors.Clear();
|
||||
|
||||
// Attempt to reflect the member
|
||||
|
||||
reflectionSucceeded = false;
|
||||
|
||||
if (member != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
member.EnsureReflected();
|
||||
reflectionSucceeded = true;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
if (!reflectionSucceeded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the metadata tree and optionally assign default arguments
|
||||
|
||||
if (reset)
|
||||
{
|
||||
IExpression target;
|
||||
|
||||
if (member.requiresTarget)
|
||||
{
|
||||
if (ComponentHolderProtocol.IsComponentHolderType(member.targetType) && metadata.UnityObjectAncestor() != null)
|
||||
{
|
||||
target = new Self();
|
||||
}
|
||||
else
|
||||
{
|
||||
target = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target = null;
|
||||
}
|
||||
|
||||
targetMetadata.value = target;
|
||||
}
|
||||
|
||||
targetMetadata.Inspector<IExpressionInspector>().expectedType = member.targetType;
|
||||
|
||||
if (member.isInvocable)
|
||||
{
|
||||
var argumentIndex = 0;
|
||||
|
||||
foreach (var parameterInfo in member.methodBase.GetParametersWithoutThis())
|
||||
{
|
||||
if (reset || argumentIndex >= argumentsMetadata.Count)
|
||||
{
|
||||
argumentsMetadata.Add(parameterInfo.DefaultInspectableExpression());
|
||||
}
|
||||
|
||||
var argumentMetadata = argumentsMetadata[argumentIndex];
|
||||
|
||||
PrepareParameterLabel(argumentMetadata, parameterInfo.HumanName(), member.methodBase.ParameterSummary(parameterInfo));
|
||||
|
||||
if (parameterInfo.ParameterType.IsByRef)
|
||||
{
|
||||
var argument = argumentsMetadata[argumentIndex].value as Literal;
|
||||
|
||||
if (argument == null || argument.type != typeof(IVariableReference))
|
||||
{
|
||||
argumentsMetadata[argumentIndex].value = new Literal(typeof(IVariableReference), null);
|
||||
}
|
||||
|
||||
var referenceInspector = new IVariableReferenceInspector(argumentMetadata[nameof(ILiteral.value)]);
|
||||
referenceInspector.Initialize();
|
||||
referenceInspector.direction = ActionDirection.Set;
|
||||
referenceInspectors.Add(argumentMetadata, referenceInspector);
|
||||
PrepareParameterLabel(argumentMetadata[nameof(ILiteral.value)], parameterInfo.HumanName(), member.methodBase.ParameterSummary(parameterInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
PrepareParameterInspector(argumentMetadata, parameterInfo.ParameterType);
|
||||
}
|
||||
|
||||
argumentIndex++;
|
||||
}
|
||||
}
|
||||
else if (member.isSettable && (ActionDirection)directionMetadata.value != ActionDirection.Get)
|
||||
{
|
||||
if (reset || argumentsMetadata.Count == 0)
|
||||
{
|
||||
argumentsMetadata.Add(member.type.ToInspectableExpression());
|
||||
}
|
||||
|
||||
var argumentMetadata = argumentsMetadata[0];
|
||||
|
||||
PrepareParameterLabel(argumentMetadata, member.info.HumanName(), member.info.Summary());
|
||||
PrepareParameterInspector(argumentMetadata, member.type);
|
||||
}
|
||||
|
||||
SetHeightDirty();
|
||||
}
|
||||
|
||||
public static bool WillFail(bool reflectionSucceeded, MemberInvocation invocation, UnityObject owner)
|
||||
{
|
||||
if (!reflectionSucceeded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// We can only analyze if the member isn't null and
|
||||
// if we can infer the value of the target expression in edit mode
|
||||
var canAnalyze = invocation.member != null && (invocation.target is ILiteral || invocation.target is Self);
|
||||
|
||||
if (!canAnalyze)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
object target;
|
||||
|
||||
if (invocation.target is ILiteral)
|
||||
{
|
||||
target = ((ILiteral)invocation.target).value;
|
||||
}
|
||||
else if (invocation.target is Self)
|
||||
{
|
||||
target = owner;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetType = target.GetType();
|
||||
|
||||
if (ComponentHolderProtocol.IsComponentHolderType(invocation.member.targetType))
|
||||
{
|
||||
if (!ComponentHolderProtocol.IsComponentHolderType(targetType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't fail true if the owner isn't a component holder
|
||||
// (e.g. it might be a graph asset)
|
||||
if (!owner.IsComponentHolder())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return invocation.member.targetType != typeof(GameObject) && !((UnityObject)target).GetComponents<Component>().Any(c => invocation.member.targetType.IsInstanceOfType(c));
|
||||
}
|
||||
else
|
||||
{
|
||||
return !invocation.member.targetType.IsAssignableFrom(targetType);
|
||||
}
|
||||
}
|
||||
|
||||
private bool willFail => WillFail(reflectionSucceeded, (MemberInvocation)metadata.value, metadata.UnityObjectAncestor());
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rendering
|
||||
|
||||
protected override IEnumerable<GUIContent> compactLabels => base.compactLabels.Concat(targetMetadata.label.Yield());
|
||||
|
||||
protected override float GetHeight(float width, GUIContent label)
|
||||
{
|
||||
var height = 0f;
|
||||
|
||||
height += GetMemberHeight(width);
|
||||
|
||||
using (LudiqGUIUtility.labelWidth.Override(GetCompactLabelsWidth(width)))
|
||||
{
|
||||
if (reflectionSucceeded)
|
||||
{
|
||||
height += Styles.spaceBetweenParameters;
|
||||
|
||||
if (((Member)memberMetadata.value).requiresTarget)
|
||||
{
|
||||
height += GetTargetHeight(width);
|
||||
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
height += Styles.spaceBetweenParameters;
|
||||
}
|
||||
}
|
||||
|
||||
height += GetParametersHeight(width);
|
||||
}
|
||||
}
|
||||
|
||||
height = HeightWithLabel(metadata, width, height, label);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
private float GetMemberHeight(float width)
|
||||
{
|
||||
return InspectorGUI.GetHeight(memberMetadata, width, GUIContent.none, this);
|
||||
}
|
||||
|
||||
private float GetTargetHeight(float width)
|
||||
{
|
||||
return InspectorGUI.GetHeight(targetMetadata, width, targetMetadata.label, this);
|
||||
}
|
||||
|
||||
protected override float GetParameterHeight(Metadata parameter, float width)
|
||||
{
|
||||
if (referenceInspectors.ContainsKey(parameter))
|
||||
{
|
||||
return referenceInspectors[parameter].GetHeight(width, GUIContent.none, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InspectorGUI.GetHeight(parameter, width, GUIContent.none, this);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnGUI(Rect position, GUIContent label)
|
||||
{
|
||||
var memberPosition = position.VerticalSection(ref y, GetMemberHeight(position.width));
|
||||
|
||||
memberPosition = PrefixLabel(metadata, memberPosition, label);
|
||||
|
||||
OnMemberGUI(memberPosition);
|
||||
|
||||
position = ReclaimImplementationSelector(position);
|
||||
|
||||
if (reflectionSucceeded)
|
||||
{
|
||||
using (LudiqGUIUtility.labelWidth.Override(GetCompactLabelsWidth(position.width)))
|
||||
{
|
||||
y += Styles.spaceBetweenParameters;
|
||||
|
||||
if (((Member)memberMetadata.value).requiresTarget)
|
||||
{
|
||||
var targetPosition = position.VerticalSection(ref y, GetTargetHeight(position.width));
|
||||
|
||||
OnTargetGUI(targetPosition);
|
||||
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
y += Styles.spaceBetweenParameters;
|
||||
}
|
||||
}
|
||||
|
||||
OnParametersGUI(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMemberGUI(Rect memberPosition)
|
||||
{
|
||||
BeginBlock(memberMetadata, memberPosition, GUIContent.none);
|
||||
|
||||
memberMetadata.Inspector<MemberManipulatorInspector>().willFail = willFail;
|
||||
|
||||
InspectorGUI.Field(memberMetadata, memberPosition, GUIContent.none);
|
||||
|
||||
if (EndBlock(memberMetadata))
|
||||
{
|
||||
ReflectMember(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTargetGUI(Rect targetPosition)
|
||||
{
|
||||
InspectorGUI.Field(targetMetadata, targetPosition);
|
||||
}
|
||||
|
||||
protected override void OnParameterGUI(Rect parameterPosition, Metadata parameter)
|
||||
{
|
||||
if (referenceInspectors.ContainsKey(parameter))
|
||||
{
|
||||
referenceInspectors[parameter].Field(parameterPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnParameterGUI(parameterPosition, parameter);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 41f5d158b421e44c78e95341ab945c13
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue