123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- /*
- 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
- }
- }
- */
|