protected override IValue GetElementValueAt(IObjectValueRole <TValue> collection, int index, IValueFetchOptions options)
            {
                var name = $"[{index}]";

                try
                {
                    var frame      = mySerializedPropertyRole.ValueReference.OriginatingFrame;
                    var indexValue = myValueServices.ValueFactory.CreatePrimitive(frame, options, index);
                    var childSerializedPropertyValue = collection.CallInstanceMethod(myGetElementMethod, indexValue);
                    var valueReference = new SimpleValueReference <TValue>(childSerializedPropertyValue,
                                                                           mySerializedPropertyRole.ReifiedType.MetadataType, name, ValueOriginKind.ArrayElement,
                                                                           ValueFlags.None | ValueFlags.IsReadOnly, frame, myValueServices.RoleFactory);

                    // Tell the value presenter to hide the name, because it's always "data" (DefaultName is the key name)
                    // Also hide the type presentation - they can only ever be SerializedProperty instances
                    return(new CalculatedValueReferenceDecorator <TValue>(valueReference, myValueServices.RoleFactory,
                                                                          valueReference.DefaultName, false, false).ToValue(myValueServices));
                }
                catch (Exception e)
                {
                    // We must always return a value, as we're effectively showing the contents of an array here. We're
                    // possibly also being evaluated lazily, thanks to chunked arrays, so can't rely on the caller
                    // catching exceptions.
                    myLogger.LogExceptionSilently(e);
                    return(myValueServices.ValueRenderers.GetValueStubForException(e, name,
                                                                                   collection.ValueReference.OriginatingFrame) as IValue
                           ?? new ErrorValue(name, "Unable to retrieve child serialized property"));
                }
            }
Exemple #2
0
        protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                                  IMetadataTypeLite instanceType,
                                                                  IPresentationOptions options,
                                                                  IUserDataHolder dataHolder,
                                                                  CancellationToken token)
        {
            // GetChildren is passed options that always allow evaluation, e.g. to calculate IEnumerable's "Results"
            // node. We eagerly evaluate Scene Path here, we should return a lazy reference to allow evaluating during
            // presentation, so that we get the "Refresh" link if the user has disabled evaluation
            // TODO: Make "Scene Path" lazy in 212
            if (mySession.EvaluationOptions.AllowTargetInvoke)
            {
                // Only add "Scene Path" to the most derived type, not every "base" node back to Component
                var valueType = valueRole.ValueReference.GetValueType(options, ValueServices.ValueMetadataProvider);
                if (valueType.Equals(instanceType))
                {
                    var scenePathValue = GetGameObjectScenePath(valueRole, options);
                    if (scenePathValue != null)
                    {
                        yield return(scenePathValue);
                    }
                }
            }

            foreach (var valueEntity in base.GetChildren(valueRole, instanceType, options, dataHolder, token))
            {
                yield return(valueEntity);
            }
        }
Exemple #3
0
 public override bool IsApplicable(IObjectValueRole <TValue> valueRole,
                                   IMetadataTypeLite instanceType,
                                   IPresentationOptions options,
                                   IUserDataHolder dataHolder)
 {
     return(myUnityOptions.ExtensionsEnabled && instanceType.Is("UnityEditor.SerializedProperty"));
 }
        protected IEnumerable <IValueEntity> RenderChildren(IObjectValueRole <TValue> valueRole,
                                                            IEnumerable <IValueReference <TValue> > references,
                                                            IPresentationOptions options, CancellationToken token)
        {
            if (!options.FlattenHierarchy)
            {
                // Add when rendering to avoid sorting issues
                var baseRole = FindNextBaseRoleWithVisibleMembers(valueRole);
                if (baseRole != null)
                {
                    yield return(new ConcreteObjectRoleReference <TValue>(baseRole, "base", false, ValueOriginKind.Base,
                                                                          ValueFlags.None).ToValue(ValueServices));
                }
            }

            foreach (var memberValue in ChildrenRenderingUtil.RenderReferencesWithVisibilityGroups(references, options,
                                                                                                   token, ValueServices))
            {
                yield return(memberValue);
            }

            foreach (var staticMember in ChildrenRenderingUtil.EnumerateStaticMembersIfNeeded(valueRole, options,
                                                                                              token, ValueServices))
            {
                yield return(staticMember);
            }
        }
Exemple #5
0
            protected override IValue GetElementValueAt(IObjectValueRole <TValue> collection, int index, IValueFetchOptions options)
            {
                try
                {
                    var frame               = myGameObjectRole.ValueReference.OriginatingFrame;
                    var indexValue          = myValueServices.ValueFactory.CreatePrimitive(frame, options, index);
                    var childTransformValue = collection.CallInstanceMethod(myGetChildMethod, indexValue);
                    var childTransform      = new SimpleValueReference <TValue>(childTransformValue,
                                                                                frame, myValueServices.RoleFactory).AsObjectSafe(options);
                    var gameObject = childTransform?.GetInstancePropertyReference("gameObject", true)
                                     ?.AsObjectSafe(options);
                    if (gameObject == null)
                    {
                        return(new ErrorValue("Game Object", "Unable to find child gameObject, or value is null"));
                    }

                    var name = gameObject.GetInstancePropertyReference("name", true)?.AsStringSafe(options)
                               ?.GetString() ?? "Game Object";

                    // Tell the value presenter to not show the name field, we're already showing it as the key. Also don't
                    // show the type - a GameObject's child can only be a GameObject
                    return(new CalculatedValueReferenceDecorator <TValue>(gameObject.ValueReference,
                                                                          myValueServices.RoleFactory, name, false, false).ToValue(myValueServices));
                }
                catch (Exception e)
                {
                    // We must always return a value, as we're effectively showing the contents of an array here. We're
                    // possibly also being evaluated lazily, thanks to chunked arrays, so can't rely on the caller
                    // catching exceptions.
                    myLogger.LogExceptionSilently(e);
                    return(myValueServices.ValueRenderers.GetValueStubForException(e, "Game Object",
                                                                                   collection.ValueReference.OriginatingFrame) as IValue
                           ?? new ErrorValue("Game Object", "Unable to retrieve child game object"));
                }
            }
            private bool TryCopySerializedProperty(IObjectValueRole <TValue> serializedPropertyRole,
                                                   IValueFetchOptions options,
                                                   out IObjectValueRole <TValue> copiedSerializedPropertyRole)
            {
                copiedSerializedPropertyRole = null;

                // Get a copy of the property, so we can call Next(true) without updating the current instance
                var copyMethod = MetadataTypeLiteEx.LookupInstanceMethodSafe(
                    mySerializedPropertyRole.ReifiedType.MetadataType,
                    MethodSelectors.SerializedProperty_Copy, false);

                if (copyMethod == null)
                {
                    myLogger.Warn("Cannot find Copy method on SerializedProperty");
                    return(false);
                }

                // CallInstanceMethod always returns not null (VoidValue if it fails)
                copiedSerializedPropertyRole = new SimpleValueReference <TValue>(
                    serializedPropertyRole.CallInstanceMethod(copyMethod),
                    mySerializedPropertyRole.ValueReference.OriginatingFrame, myValueServices.RoleFactory)
                                               .AsObjectSafe(options);
                if (copiedSerializedPropertyRole == null)
                {
                    myLogger.Warn("Unable to Copy serializedProperty");
                    return(false);
                }

                return(true);
            }
Exemple #7
0
        protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                                  IMetadataTypeLite instanceType,
                                                                  IPresentationOptions options,
                                                                  IUserDataHolder dataHolder,
                                                                  CancellationToken token)
        {
            // GetChildren is always called with evaluation enabled (e.g. to calculate IEnumerable's "Results" node).
            // If the user has disabled "Allow property evaluation..."  we shouldn't show the "Scene Path" item.
            // Ideally, we should add it with a "Refresh" link to calculate it if required. This involves returning a
            // reference to calculate the value rather than calculating it eagerly.
            // TODO: Make "Scene Path" lazy in 212
            if (mySession.EvaluationOptions.AllowTargetInvoke)
            {
                var scenePathValue = ScenePathValueHelper.GetScenePathValue(valueRole, options, ValueServices, Logger);
                if (scenePathValue != null)
                {
                    yield return(scenePathValue);
                }
            }

            yield return(new GameObjectComponentsGroup(valueRole, ValueServices, Logger));

            yield return(new GameObjectChildrenGroup(valueRole, ValueServices, Logger));

            foreach (var valueEntity in base.GetChildren(valueRole, instanceType, options, dataHolder, token))
            {
                yield return(valueEntity);
            }
        }
Exemple #8
0
            private bool TryInvokeGetIterator(IObjectValueRole <TValue> serializedObjectRole,
                                              IValueFetchOptions options,
                                              out IObjectValueRole <TValue> returnedSerializedPropertyRole)
            {
                returnedSerializedPropertyRole = null;

                var method = MetadataTypeLiteEx.LookupInstanceMethodSafe(serializedObjectRole.ReifiedType.MetadataType,
                                                                         MethodSelectors.SerializedObject_GetIterator, false);

                if (method == null)
                {
                    myLogger.Warn("Cannot find GetIterator method on SerializedObject");
                    return(false);
                }

                returnedSerializedPropertyRole = new SimpleValueReference <TValue>(
                    serializedObjectRole.CallInstanceMethod(method),
                    serializedObjectRole.ValueReference.OriginatingFrame, myValueServices.RoleFactory)
                                                 .AsObjectSafe(options);
                if (returnedSerializedPropertyRole == null)
                {
                    myLogger.Warn("Unable to invoke GetIterator");
                    return(false);
                }

                return(true);
            }
Exemple #9
0
        private IEnumerable <IValueEntity> EnumerateMembersWithBaseNode(IObjectValueRole <TValue> valueRole,
                                                                        IPresentationOptions options,
                                                                        CancellationToken token,
                                                                        IValueServicesFacade <TValue> valueServices)
        {
            var baseRole = FindNextBaseRoleWithVisibleMembers(valueRole);

            if (baseRole != null)
            {
                yield return(new ConcreteObjectRoleReference <TValue>(baseRole, "base", false, ValueOriginKind.Base, ValueFlags.None).ToValue(valueServices));
            }

            var propertiesAndFields = GetPropertiesAndFields(valueRole)
                                      .Where(IsAllowedReference)
                                      .OrderBy(IdentityFunc <IValueReference <TValue> > .Instance, ByNameReferenceComparer <TValue> .Instance);

            foreach (var member in ChildrenRenderingUtil.RenderReferencesWithVisibilityGroups(propertiesAndFields, options, token, valueServices))
            {
                yield return(member);
            }

            foreach (var staticMember in ChildrenRenderingUtil.EnumerateStaticMembersIfNeeded(valueRole, options, token, valueServices))
            {
                yield return(staticMember);
            }
        }
Exemple #10
0
 protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole, IMetadataTypeLite instanceType, IPresentationOptions options,
                                                           IUserDataHolder dataHolder, CancellationToken token)
 {
     return(options.FlattenHierarchy
         ? EnumerateMembersFlat(valueRole, options, token, ValueServices)
         : EnumerateMembersWithBaseNode(valueRole, options, token, ValueServices));
 }
Exemple #11
0
        private IValuePresentation GetValuePresentation(IObjectValueRole <TValue> serializedPropertyRole,
                                                        SerializedPropertyKind propertyType,
                                                        IPresentationOptions options,
                                                        out string extraDetail)
        {
            extraDetail = null;

            var valueProperty  = GetValueFieldName(propertyType);
            var valueReference = valueProperty == null ? null : serializedPropertyRole.GetInstancePropertyReference(valueProperty);

            if (propertyType == SerializedPropertyKind.Enum)
            {
                extraDetail = SerializedPropertyHelper.GetEnumValueIndexAsEnumName(serializedPropertyRole, valueReference, options);
            }
            else if (propertyType == SerializedPropertyKind.Character)
            {
                extraDetail = SerializedPropertyHelper.GetIntValueAsPrintableChar(valueReference, options);
            }
            else if (propertyType == SerializedPropertyKind.Integer)
            {
                var type = serializedPropertyRole.GetInstancePropertyReference("type")?.AsStringSafe(options)
                           ?.GetString();
                if (type == "char")
                {
                    extraDetail = SerializedPropertyHelper.GetIntValueAsPrintableChar(valueReference, options);
                }
            }

            return(valueReference?.ToValue(ValueServices)?.GetValuePresentation(options));
        }
        private bool TryCacheDebuggerDisplay(IObjectValueRole <TValue> valueRole, IMetadataTypeLite instanceType,
                                             IUserDataHolder userDataHolder)
        {
            // Special case. Replace with a second dictionary or whatever if we need to handle more types
            if (valueRole.ValueReference is NamedReferenceDecorator <TValue> reference && reference.IsNameFromValue &&
                instanceType.FullName == "UnityEngine.GameObject")
            {
                userDataHolder.PutData(ourDebuggerDisplayStringKey, GameObjectDebuggerDisplayStringWithoutName);
                return(true);
            }

            // DebuggerDisplayAttribute is inherited. This is important for applying a debug string on Behaviour, and
            // having it used in custom MonoBehaviour classes
            var current = instanceType;

            while (current != null)
            {
                if (myDebuggerDisplayValues.TryGetValue(current.GetGenericTypeDefinition().FullName,
                                                        out var displayString))
                {
                    userDataHolder.PutData(ourDebuggerDisplayStringKey, displayString);
                    return(true);
                }

                current = current.BaseType;
            }

            return(false);
        }
 public override bool IsApplicable(IObjectValueRole <TValue> valueRole, IMetadataTypeLite instanceType,
                                   IPresentationOptions options,
                                   IUserDataHolder dataHolder)
 {
     // Note that DebuggerDisplayObjectPresenter checks options.AllowTargetInvoke here
     return(myUnityOptions.ExtensionsEnabled && options.AllowDebuggerDisplayEvaluation &&
            TryCacheDebuggerDisplay(valueRole, instanceType.GetGenericTypeDefinition(), dataHolder));
 }
 public GameObjectChildrenGroup(IObjectValueRole <TValue> gameObjectRole,
                                IValueServicesFacade <TValue> valueServices, ILogger logger)
     : base("Children")
 {
     myGameObjectRole = gameObjectRole;
     myValueServices  = valueServices;
     myLogger         = logger;
 }
Exemple #15
0
 public GameObjectsGroup(IObjectValueRole <TValue> valueRole, IMetadataMethodLite getRootObjectMethod,
                         IValueServicesFacade <TValue> valueServices)
     : base("Game Objects")
 {
     myValueRole           = valueRole;
     myGetRootObjectMethod = getRootObjectMethod;
     myValueServices       = valueServices;
 }
Exemple #16
0
 protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                           IMetadataTypeLite instanceType,
                                                           IPresentationOptions options,
                                                           IUserDataHolder dataHolder,
                                                           CancellationToken token)
 {
     yield return(new ChildrenGroup(valueRole, ValueServices, myLogger));
 }
Exemple #17
0
 public ChildrenGroup(IObjectValueRole <TValue> serializedObjectRole,
                      IValueServicesFacade <TValue> valueServices,
                      ILogger logger)
     : base("Serialized Properties")
 {
     mySerializedObjectRole = serializedObjectRole;
     myValueServices        = valueServices;
     myLogger = logger;
 }
 public GameObjectsGroup(IObjectValueRole <TValue> sceneValueRole, IMetadataMethodLite getRootObjectsMethod,
                         IValueServicesFacade <TValue> valueServices, ILogger logger)
     : base("Game objects")
 {
     mySceneValueRole       = sceneValueRole;
     myGetRootObjectsMethod = getRootObjectsMethod;
     myValueServices        = valueServices;
     myLogger = logger;
 }
 protected IEnumerable <IValueReference <TValue> > EnumerateChildren([NotNull] IObjectValueRole <TValue> valueRole,
                                                                     IPresentationOptions options,
                                                                     CancellationToken token)
 {
     // This is essentially the same as ChildrenRenderingUtil.EnumerateMembersFlat and EnumerateMembersWithBaseNode
     // but allows us to split enumerating, sorting, and rendering into separate steps so we can also insert
     // filtering.
     return(options.FlattenHierarchy
         ? ChildrenRenderingUtil.CollectMembersByOverridingRules(valueRole, options, token)
         : GetPropertiesAndFields(valueRole));
 }
Exemple #20
0
        private IValueEntity GetGameObjectScenePath(IObjectValueRole <TValue> componentRole,
                                                    IPresentationOptions options)
        {
            var gameObjectRole = Logger.CatchEvaluatorException <TValue, IObjectValueRole <TValue> >(
                () => componentRole.GetInstancePropertyReference("gameObject", true)
                ?.AsObjectSafe(options),
                exception => Logger.LogThrownUnityException(exception, componentRole.ValueReference.OriginatingFrame,
                                                            ValueServices, options));

            return(ScenePathValueHelper.GetScenePathValue(gameObjectRole, options, ValueServices, Logger));
        }
        protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                                  IMetadataTypeLite instanceType,
                                                                  IPresentationOptions options,
                                                                  IUserDataHolder dataHolder, CancellationToken token)
        {
            var references = EnumerateChildren(valueRole, options, token);

            references = FilterChildren(references);
            references = SortChildren(references);
            return(RenderChildren(valueRole, references, options, token));
        }
Exemple #22
0
        private IValueEntity GetGameObjectScenePath(IObjectValueRole <TValue> componentRole, IPresentationOptions options)
        {
            var gameObjectRole =
                componentRole.GetInstancePropertyReference("gameObject", true)?.AsObjectSafe(options);

            if (gameObjectRole == null)
            {
                return(null);
            }
            return(ScenePathValueHelper.GetScenePathValue(gameObjectRole, options, ValueServices, myLogger));
        }
 public ArrayElementsGroup(IObjectValueRole <TValue> serializedPropertyRole, int arraySize,
                           MethodSelector getMethodElementSelector,
                           IValueServicesFacade <TValue> valueServices,
                           ILogger logger)
     : base($"[0..{arraySize - 1}]")
 {
     mySerializedPropertyRole = serializedPropertyRole;
     myArraySize = arraySize;
     myGetMethodElementSelector = getMethodElementSelector;
     myValueServices            = valueServices;
     myLogger = logger;
 }
        protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                                  IMetadataTypeLite instanceType,
                                                                  IPresentationOptions options,
                                                                  IUserDataHolder dataHolder, CancellationToken token)
        {
            // GetRootGameObjects was introduced in Unity 5.3.2
            var getRootObjectsMethod = valueRole.ReifiedType.MetadataType.GetMethods()
                                       .FirstOrDefault(ourGetRootGameObjectsSelector);

            if (getRootObjectsMethod != null)
            {
                yield return(new GameObjectsGroup(valueRole, getRootObjectsMethod, ValueServices, myLogger));
            }
        }
            protected override IValue GetElementValueAt(IObjectValueRole <TValue> collection, int index, IValueFetchOptions options)
            {
                var frame      = mySerializedPropertyRole.ValueReference.OriginatingFrame;
                var indexValue = myValueServices.ValueFactory.CreatePrimitive(frame, options, index);
                var childSerializedPropertyValue = collection.CallInstanceMethod(myGetElementMethod, indexValue);
                var valueReference = new SimpleValueReference <TValue>(childSerializedPropertyValue,
                                                                       mySerializedPropertyRole.ReifiedType.MetadataType, $"[{index}]", ValueOriginKind.ArrayElement,
                                                                       ValueFlags.None | ValueFlags.IsReadOnly, frame, myValueServices.RoleFactory);

                // Tell the value presenter to hide the name, because it's always "data" (DefaultName is the key name)
                // Also hide the type presentation - they can only ever be SerializedProperty instances
                return(new CalculatedValueReferenceDecorator <TValue>(valueReference, myValueServices.RoleFactory,
                                                                      valueReference.DefaultName, false, false).ToValue(myValueServices));
            }
 protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                           IMetadataTypeLite instanceType,
                                                           IPresentationOptions options,
                                                           IUserDataHolder dataHolder,
                                                           CancellationToken token)
 {
     // Keep an eye on iterators and enumeration: we need to eagerly evaluate GetChildrenImpl so we can catch any
     // exceptions. The return value of GetChildren is eagerly evaluated, so we're not changing any semantics
     return(Logger.CatchEvaluatorException <TValue, IEnumerable <IValueEntity> >(
                () => GetChildrenImpl(valueRole, instanceType, options, dataHolder, token).ToList(),
                exception =>
                Logger.LogThrownUnityException(exception, valueRole.ValueReference.OriginatingFrame,
                                               ValueServices, options))
            ?? base.GetChildren(valueRole, instanceType, options, dataHolder, token));
 }
Exemple #27
0
        public static string GetEnumValueIndexAsEnumName <TValue>(IObjectValueRole <TValue> serializedProperty,
                                                                  IValueReference <TValue> enumValueIndexReference,
                                                                  IPresentationOptions options)
            where TValue : class
        {
            var primitiveValue = enumValueIndexReference.AsPrimitiveSafe(options)?.GetPrimitive();

            if (primitiveValue is int enumValueIndex &&
                serializedProperty.GetInstancePropertyReference("enumNames")?.GetPrimaryRole(options) is
                IArrayValueRole <TValue> enumNamesArray)
            {
                return(enumNamesArray.GetElementReference(enumValueIndex).AsStringSafe(options)?.GetString());
            }

            return(null);
        }
Exemple #28
0
        protected override IEnumerable <IValueEntity> GetChildren(IObjectValueRole <TValue> valueRole,
                                                                  IMetadataTypeLite instanceType,
                                                                  IPresentationOptions options,
                                                                  IUserDataHolder dataHolder, CancellationToken token)
        {
            yield return(new GameObjectComponentsGroup(valueRole, ValueServices, myLogger));

            // The children of the current GameObject (as seen in Unity's Hierarchy view) are actually the children of
            // GameObject.transform. This should never be null
            var transformProperty = valueRole.GetInstancePropertyReference("transform");

            if (transformProperty != null)
            {
                yield return(new GameObjectChildrenGroup(transformProperty, ValueServices));
            }
        }
Exemple #29
0
        public static bool TryEvaluatePrimitiveProperty <TValue, TPrimitive>(IObjectValueRole <TValue> valueRole,
                                                                             string property, IValueFetchOptions options,
                                                                             out TPrimitive value)
            where TValue : class
            where TPrimitive : struct
        {
            value = default;
            var primitiveValueRole = valueRole.GetInstancePropertyReference(property)?.AsPrimitiveSafe(options);

            if (!(primitiveValueRole?.GetPrimitive() is TPrimitive primitive))
            {
                return(false);
            }
            value = primitive;
            return(true);
        }
            protected override IValue GetElementValueAt(IObjectValueRole <TValue> collection, int index, IValueFetchOptions options)
            {
                var frame               = myGameObjectRole.ValueReference.OriginatingFrame;
                var indexValue          = myValueServices.ValueFactory.CreatePrimitive(frame, options, index);
                var childTransformValue = collection.CallInstanceMethod(myGetChildMethod, indexValue);
                var childTransform      = new SimpleValueReference <TValue>(childTransformValue,
                                                                            frame, myValueServices.RoleFactory).AsObjectSafe(options);
                var gameObject = childTransform?.GetInstancePropertyReference("gameObject", true)
                                 ?.AsObjectSafe(options);
                var name = gameObject?.GetInstancePropertyReference("name", true)?.AsStringSafe(options)
                           ?.GetString() ?? "Game Object";

                return(new NamedReferenceDecorator <TValue>(gameObject.ValueReference, name,
                                                            ValueOriginKind.Property,
                                                            ValueFlags.None | ValueFlags.IsReadOnly,
                                                            myGameObjectRole.ReifiedType.MetadataType, myValueServices.RoleFactory, true)
                       .ToValue(myValueServices));
            }