protected override IValue GetElementValueAt(IArrayValueRole <TValue> collection, int index,
                                                        IValueFetchOptions options)
            {
                var elementReference = collection.GetElementReference(index);

                return(GetElementValue(elementReference, options));
            }
            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);
            }
Пример #3
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);
            }
        private IEnumerable <IValueEntity> SplitIntoChunks(TRole collection, int chunkStartIndex, int length,
                                                           IValueFetchOptions options, CancellationToken token)
        {
            // Chunks of chunks
            var step = myChunkSize;
            var div  = length / step;

            while (div > myChunkSize || div == myChunkSize && length % step > 0)
            {
                token.ThrowIfCancellationRequested();

                step *= myChunkSize;
                div   = length / step;
            }

            for (var i = 0; i < length; i += step)
            {
                token.ThrowIfCancellationRequested();

                var startIndex  = chunkStartIndex + i;
                var endIndex    = Math.Min(chunkStartIndex + i + step, chunkStartIndex + length) - 1;
                var chunkLength = endIndex - startIndex + 1;
                var name        = $"[{i}..{endIndex}]";
                yield return(new SimpleEntityGroup(name,
                                                   GetChunkedChildren(collection, startIndex, chunkLength, options, token)));
            }
        }
Пример #5
0
            private string GetComponentName(IValueReference <TValue> componentValue,
                                            [CanBeNull] IReifiedType <TValue> objectNamesType,
                                            [CanBeNull] IMetadataMethodLite getInspectorTitleMethod,
                                            IStackFrame frame,
                                            IValueFetchOptions options, IValueServicesFacade <TValue> services)
            {
                if (objectNamesType != null && getInspectorTitleMethod != null)
                {
                    try
                    {
                        var inspectorTitle = objectNamesType.CallStaticMethod(frame, options, getInspectorTitleMethod,
                                                                              componentValue.GetValue(options));
                        var stringValueRole =
                            new SimpleValueReference <TValue>(inspectorTitle, frame, services.RoleFactory)
                            .AsStringSafe(options);
                        if (stringValueRole != null)
                        {
                            return(stringValueRole.GetString());
                        }
                    }
                    catch (Exception e)
                    {
                        myLogger.Error(e, "Unable to fetch object names for {0}", componentValue);
                    }
                }

                return(componentValue.GetPrimaryRole(options).ReifiedType.MetadataType.ShortName);
            }
 public virtual void SetValue(TValue value, IValueFetchOptions options)
 {
     if ((DefaultFlags & ValueFlags.IsReadOnly) != 0)
     {
         throw ValueErrors.ReadOnlyReference();
     }
     myValueReferenceImplementation.SetValue(value, options);
 }
        private IEnumerable <IValueEntity> GetChildrenLazy(TRole collection, int startIndex, int length,
                                                           IValueFetchOptions options, CancellationToken token)
        {
            for (var i = 0; i < length; i++)
            {
                token.ThrowIfCancellationRequested();

                yield return(GetElementValueAt(collection, startIndex + i, options));
            }
        }
        protected IEnumerable <IValueEntity> GetChunkedChildren(TRole collection, int startIndex, int length,
                                                                IValueFetchOptions options, CancellationToken token)
        {
            if (length > myChunkSize)
            {
                return(SplitIntoChunks(collection, startIndex, length, options, token));
            }

            // Get an enumerable of child values. Calculating this is expensive, so do it on demand inside an iterator.
            // When a chunk group is created, it receives an enumerable of values. If we're not careful, each chunk's
            // children are eagerly evaluated and the whole point of chunking is lost.
            // The default array children renderer uses an array for this enumerable, but populates it with lightweight
            // array element value references that calculate the actual value on demand, via ICachedValueReference.
            // If we hit problems with this simple lazy enumerable, we could adopt a similar approach.
            return(GetChildrenLazy(collection, startIndex, length, options, token));
        }
Пример #9
0
        public static string GetIntValueAsPrintableChar <TValue>(IValueReference <TValue> intValueReference,
                                                                 IValueFetchOptions options)
            where TValue : class
        {
            var primitiveValue = intValueReference.AsPrimitiveSafe(options)?.GetPrimitive();

            if (primitiveValue != null)
            {
                var value = primitiveValue as long? ?? primitiveValue as int?;
                if (value < char.MaxValue)
                {
                    return($"'{ToPrintableChar((char) value)}'");
                }
            }

            return(null);
        }
        private IEnumerable <IValueReference <TValue> > DecorateCharacterValue(IEnumerable <IValueReference <TValue> > references,
                                                                               IValueFetchOptions options)
        {
            foreach (var reference in references)
            {
                if (reference.DefaultName == "intValue" || reference.DefaultName == "longValue")
                {
                    var extraDetail = SerializedPropertyHelper.GetIntValueAsPrintableChar(reference, options);
                    if (extraDetail != null)
                    {
                        yield return(new ExtraDetailValueReferenceDecorator <TValue>(reference,
                                                                                     ValueServices.RoleFactory, extraDetail));

                        continue;
                    }
                }

                yield return(reference);
            }
        }
Пример #11
0
            private IEnumerable <IValueEntity> GetChildrenImpl(IValueFetchOptions options)
            {
                if (!TryInvokeGetIterator(mySerializedObjectRole, options, out var serializedPropertyRole))
                {
                    yield break;
                }

                var name = serializedPropertyRole.GetInstancePropertyReference("name")
                           ?.AsStringSafe(options)?.GetString() ?? "Child";

                // Tell the value presenter to hide the name field, as we're using it for the key name. Also hide the
                // type presentation - of course it's a SerializedProperty
                yield return(new CalculatedValueReferenceDecorator <TValue>(serializedPropertyRole.ValueReference,
                                                                            myValueServices.RoleFactory, name, false, false).ToValue(myValueServices));

                // Technically, we should now repeatedly call Copy() and Next(false) until Next returns false so that we
                // show all child properties of the SerializedObject. But empirically, there is only one direct child of
                // SerializedObject, called "Base", with a depth of -1. We'll avoid the unnecessary method invocations,
                // unless it turns out to be an actual issue.
            }
 public static string GetThrownExceptionMessage <TValue>(EvaluatorExceptionThrownException <TValue> exception,
                                                         IStackFrame frame,
                                                         IValueServicesFacade <TValue> valueServices,
                                                         IValueFetchOptions valueFetchOptions,
                                                         ILogger logger)
     where TValue : class
 {
     try
     {
         var reference = new SimpleValueReference <TValue>(exception.Exception, frame, valueServices.RoleFactory);
         return(reference.AsObjectSafe(valueFetchOptions)
                ?.GetInstancePropertyReference("Message", true)
                ?.AsStringSafe(valueFetchOptions)?.GetString());
     }
     catch (Exception e)
     {
         // Argh! Exception thrown while trying to get information about a thrown exception!
         logger.LogExceptionSilently(e);
         return(null);
     }
 }
            private bool TryInvokeNext(IObjectValueRole <TValue> serializedPropertyRole,
                                       IMetadataMethodLite nextMethod,
                                       TValue boolArg,
                                       IValueFetchOptions options,
                                       out bool returnValue)
            {
                returnValue = false;

                var returnValueRole = new SimpleValueReference <TValue>(
                    serializedPropertyRole.CallInstanceMethod(nextMethod, boolArg),
                    mySerializedPropertyRole.ValueReference.OriginatingFrame,
                    myValueServices.RoleFactory)
                                      .AsPrimitiveSafe(options);

                if (returnValueRole == null)
                {
                    myLogger.Warn("Unable to call Next on serializedProperty");
                    return(false);
                }

                returnValue = returnValueRole.GetPrimitive <bool>();
                return(true);
            }
Пример #14
0
            private string GetComponentName(IValueReference <TValue> componentValue,
                                            [CanBeNull] IReifiedType <TValue> objectNamesType,
                                            [CanBeNull] IMetadataMethodLite getInspectorTitleMethod,
                                            IStackFrame frame,
                                            IValueFetchOptions options,
                                            IValueServicesFacade <TValue> services,
                                            out bool isNameFromValue)
            {
                if (objectNamesType != null && getInspectorTitleMethod != null)
                {
                    try
                    {
                        var inspectorTitle = objectNamesType.CallStaticMethod(frame, options, getInspectorTitleMethod,
                                                                              componentValue.GetValue(options));
                        var stringValueRole =
                            new SimpleValueReference <TValue>(inspectorTitle, frame, services.RoleFactory)
                            .AsStringSafe(options);
                        if (stringValueRole != null)
                        {
                            isNameFromValue = true;
                            return(stringValueRole.GetString());
                        }
                    }
                    catch (EvaluatorAbortedException e)
                    {
                        myLogger.LogExceptionSilently(e);
                    }
                    catch (Exception e)
                    {
                        myLogger.Warn(e, ExceptionOrigin.Algorithmic,
                                      $"Unable to fetch object names for {componentValue}");
                    }
                }

                isNameFromValue = false;
                return(componentValue.GetPrimaryRole(options).ReifiedType.MetadataType.ShortName);
            }
 public TValue GetValue(IValueFetchOptions options) => myOriginalReference.GetValue(options);
            private IValue GetElementValue(IValueReference <TValue> elementReference, IValueFetchOptions options)
            {
                var elementRole = elementReference.AsObjectSafe(options);

                if (elementRole == null)
                {
                    return(null);
                }

                var isNameFromValue = true;
                var name            = elementRole.GetInstancePropertyReference("name", true)?.AsStringSafe(options)
                                      ?.GetString();

                if (name == null)
                {
                    name            = "Game Object";
                    isNameFromValue = false;
                }

                // Tell the value presenter to hide the name field, if we're using it for the key. Also hide the default
                // type presentation - we know it's a GameObject, it's under a group called "Game Objects"
                return(new CalculatedValueReferenceDecorator <TValue>(elementRole.ValueReference,
                                                                      myValueServices.RoleFactory, name, !isNameFromValue, false).ToValue(myValueServices));
            }
Пример #17
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"));
                }
            }
            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"));
                }
            }
            private IEnumerable <IValueEntity> GetChildrenImpl(IValueFetchOptions options, CancellationToken token)
            {
                // SerializedProperty is a view over a serialized stream. Calling Next() or GetEnumerator().MoveNext()
                // will update this view. We need to work with copies, so that the original value isn't updated
                if (!TryCopySerializedProperty(mySerializedPropertyRole, options, out var cursor))
                {
                    yield break;
                }

                // Get the depth of this "parent" property. We'll call Next() until  children's depth changes
                if (!Util.TryEvaluatePrimitiveProperty(cursor, "depth", options, out int initialDepth))
                {
                    myLogger.Warn("Unable to evaluate initial depth on serializedProperty");
                    yield break;
                }

                var nextMethod = MetadataTypeLiteEx.LookupInstanceMethodSafe(cursor.ReifiedType.MetadataType,
                                                                             MethodSelectors.SerializedProperty_Next, false);

                if (nextMethod == null)
                {
                    myLogger.Warn("Cannot find Next method on SerializedProperty");
                    yield break;
                }

                var trueValue = myValueServices.ValueFactory.CreatePrimitive(
                    mySerializedPropertyRole.ValueReference.OriginatingFrame, options, true);
                var falseValue = myValueServices.ValueFactory.CreatePrimitive(
                    mySerializedPropertyRole.ValueReference.OriginatingFrame, options, false);

                // Call cursor.Next(true). Our cursor is now a view over the first child
                if (!TryInvokeNext(cursor, nextMethod, trueValue, options, out var nextResult))
                {
                    yield break;
                }

                var count = 0;

                while (nextResult)
                {
                    token.ThrowIfCancellationRequested();

                    if (!Util.TryEvaluatePrimitiveProperty(cursor, "depth", options, out int thisDepth))
                    {
                        myLogger.Warn("Unable to evaluate initial depth on serializedProperty");
                        yield break;
                    }

                    // SerializedProperties are a view on a stream of serialised objects (not the C# objects!). Children
                    // are simply the next node in the stream, but they have a depth set to current depth + 1. Iterating
                    // children has finished when the next node's depth is set back to current depth.
                    if (thisDepth != initialDepth + 1)
                    {
                        break;
                    }

                    // Yield a copy of the current instance
                    if (!TryCopySerializedProperty(cursor, options, out var copiedSerializedPropertyRole))
                    {
                        myLogger.Warn("Failed to copy current serialised property");
                        break;
                    }

                    var name = copiedSerializedPropertyRole.GetInstancePropertyReference("name")
                               ?.AsStringSafe(options)?.GetString() ?? $"prop{count}";

                    // Tell the value presenter to hide the name field, because we're using it for the key name. Also
                    // hide the default presentation. Of course it's a SerializedProperty, it's a child of a
                    // SerializedProperty
                    yield return(new CalculatedValueReferenceDecorator <TValue>(
                                     copiedSerializedPropertyRole.ValueReference, myValueServices.RoleFactory, name, false,
                                     false)
                                 .ToValue(myValueServices));

                    // MoveNext(false). cursor is now viewing either the next child or a sibling of the original
                    // property, or is at the end of the stream (nextResult is false). If this evaluation fails,
                    // we've already logged and nextResult is already false, so we don't need extra error handling
                    TryInvokeNext(cursor, nextMethod, falseValue, options, out nextResult);

                    count++;
                }
            }
            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));
            }
 public virtual IValueRole GetPrimaryRole(IValueFetchOptions options)
 {
     // Get a role based on *this* reference, not the underlying reference. Otherwise, the returned role has the
     // wrong reference.
     return(myRoleFactory.GetPrimaryRole(this, options));
 }
Пример #22
0
            private IEnumerable <IValueEntity> GetChildrenImpl(IValueFetchOptions options)
            {
                var frame         = myGameObjectRole.ValueReference.OriginatingFrame;
                var componentType =
                    myValueServices.GetReifiedType(frame, "UnityEngine.Component, UnityEngine.CoreModule")
                    ?? myValueServices.GetReifiedType(frame, "UnityEngine.Component, UnityEngine");

                if (componentType == null)
                {
                    myLogger.Warn("Unable to find UnityEngine.Component");
                    yield break;
                }

                var getComponentsMethod = myGameObjectRole.ReifiedType.MetadataType.GetMethods()
                                          .FirstOrDefault(ourGetComponentsSelector);

                if (getComponentsMethod == null)
                {
                    myLogger.Warn("Unable to find UnityEngine.GameObject.GetComponents method");
                    yield break;
                }

                // Call Component[] GameObject.GetComponents(typeof(Component))
                var typeObject      = (IValueReference <TValue>)componentType.GetTypeObject(frame);
                var componentsArray =
                    myGameObjectRole.CallInstanceMethod(getComponentsMethod, typeObject.GetValue(options));
                var componentArray =
                    new SimpleValueReference <TValue>(componentsArray, frame, myValueServices.RoleFactory)
                    .GetExactPrimaryRoleSafe <TValue, IArrayValueRole <TValue> >(options);

                if (componentArray == null)
                {
                    myLogger.Warn("Cannot get return value of GameObject.GetComponents or method returned null");
                    yield break;
                }

                // string UnityEditor.ObjectNames.GetInspectorTitle(UnityEngine.Object)
                // Returns the name of the component, formatted the same as in the Inspector. Values are also cached per
                // type. This obviously won't be available for standalone players, where we'll display the short type
                // name instead.
                // TODO: Support extra fallback names
                // Unity doesn't use the short name, but will look at the type and use GameObject.name,
                // MonoBehaviour.GetScriptClassName and so on.
                var objectNamesType = myValueServices.GetReifiedType(frame, "UnityEditor.ObjectNames, UnityEditor")
                                      ?? myValueServices.GetReifiedType(frame,
                                                                        "UnityEditor.ObjectNames, UnityEditor.CoreModule");
                var getInspectorTitleMethod = objectNamesType?.MetadataType.GetMethods()
                                              .FirstOrDefault(ourGetInspectorTitleSelector);

                var childReferencesEnumerator = (IChildReferencesEnumerator <TValue>)componentArray;

                foreach (var componentReference in childReferencesEnumerator.GetChildReferences())
                {
                    var componentName = GetComponentName(componentReference, objectNamesType,
                                                         getInspectorTitleMethod, frame, options, myValueServices, out var isNameFromValue);

                    // Tell the value presenter to hide the name field, if we're using it for the key. Also hide the
                    // default type presentation - we know it's a Component, it's under a group called "Components"
                    yield return(new CalculatedValueReferenceDecorator <TValue>(componentReference,
                                                                                myValueServices.RoleFactory, componentName, !isNameFromValue, false).ToValue(myValueServices));
                }
            }
 public virtual TValue GetValue(IValueFetchOptions options)
 {
     return(myValueReferenceImplementation.GetValue(options));
 }
 protected abstract IValue GetElementValueAt(TRole collection, int index, IValueFetchOptions options);
            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));
            }
 public virtual void SetValue(TValue value, IValueFetchOptions options)
 {
     myValueReferenceImplementation.SetValue(value, options);
 }
 public void SetValue(TValue value, IValueFetchOptions options) => throw ValueErrors.ReadOnlyReference();
            private IValue GetElementValue(IValueReference <TValue> elementReference, IValueFetchOptions options)
            {
                var elementRole = elementReference.AsObjectSafe(options);

                if (elementRole == null)
                {
                    return(null);
                }

                var isNameFromValue = true;
                var name            = elementRole.GetInstancePropertyReference("name", true)?.AsStringSafe(options)
                                      ?.GetString();

                if (name == null)
                {
                    name            = "Game Object";
                    isNameFromValue = false;
                }

                return(new NamedReferenceDecorator <TValue>(elementRole.ValueReference, name,
                                                            ValueOriginKind.Property, ValueFlags.None | ValueFlags.IsReadOnly,
                                                            elementRole.ReifiedType.MetadataType, myValueServices.RoleFactory, isNameFromValue)
                       .ToValue(myValueServices));
            }
 public IValueRole GetPrimaryRole(IValueFetchOptions options)
 {
     return(myRoleFactory.GetPrimaryRole(this, options));
 }
Пример #30
0
            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);

                if (gameObject == null)
                {
                    return(new ErrorValue("Game Object", "Unable to retrieve child game object"));
                }

                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));
            }