public Task <SetObjectMemberResponse> SetObjectMemberAsync(
     long objHandle,
     RepresentedMemberInfo memberInfo,
     object value,
     bool returnUpdatedValue,
     CancellationToken cancellationToken = default)
 => throw new NotImplementedException();
Example #2
0
        void SafeReadMembers()
        {
            var propertyNames = new HashSet <string> ();
            var members       = new List <Tuple <RepresentedMemberInfo, object> > ();

            for (var type = RepresentedType; type != null; type = type.BaseType)
            {
                foreach (var memberItem in type.ProxyableMembers)
                {
                    var pi = memberItem.Value.ResolvedMemberInfo as PropertyInfo;
                    if (pi != null)
                    {
                        if (propertyNames.Contains(pi.Name))
                        {
                            continue;
                        }

                        propertyNames.Add(pi.Name);
                    }

                    object value;
                    try {
                        if (memberFilter != null &&
                            !memberFilter(memberItem.Value, representedObject))
                        {
                            value = new GetMemberValueError();
                        }
                        else
                        {
                            value = memberItem.Value.GetValue(representedObject);
                        }
                    } catch (TargetInvocationException e) {
                        value = new GetMemberValueError(e.InnerException);
                    } catch (Exception e) {
                        value = new GetMemberValueError(e);
                    }

                    var preparedValue = new RepresentedObject(value?.GetType());
                    ItemPreparer(preparedValue, Depth + 1, value);
                    if (preparedValue.Count == 0)
                    {
                        preparedValue = null;
                    }

                    members.Add(Tuple.Create(memberItem.Value, (object)preparedValue));
                }
            }

            members.Sort((x, y) => string.Compare(x.Item1.Name, y.Item1.Name));

            Members = new RepresentedMemberInfo [members.Count];
            Values  = new object [members.Count];

            for (int i = 0; i < members.Count; i++)
            {
                Members [i] = members [i].Item1;
                Values [i]  = members [i].Item2;
            }
        }
Example #3
0
 public SetObjectMemberRequest(
     long objectHandle,
     RepresentedMemberInfo memberInfo,
     object value,
     bool returnUpdatedValue)
 {
     ObjectHandle       = objectHandle;
     MemberInfo         = memberInfo;
     Value              = value;
     ReturnUpdatedValue = returnUpdatedValue;
 }
Example #4
0
        /// <summary>
        /// Sets the value of the member represented by <paramref name="memberInfo"/> on the object pointed to
        /// by <paramref name="handle"/>.
        /// </summary>
        /// <returns><c>true</c>, if member was set, <c>false</c> otherwise.</returns>
        /// <param name="handle">The cache handle to the object on which we want to set a value.</param>
        /// <param name="memberInfo">The member which we want to set. Can be a field or a proprety.</param>
        /// <param name="value">The new value.</param>
        /// <param name="returnUpdatedValue">
        /// If set to <c>true</c>, set <paramref name="updatedValue"/> to the updated value of the object.
        /// </param>
        /// <param name="updatedValue">The updated value of the object.</param>
        public bool TrySetObjectMember(
            long handle,
            RepresentedMemberInfo memberInfo,
            object value,
            bool returnUpdatedValue,
            out InteractiveObject updatedValue)
        {
            updatedValue = null;

            var translatedValue = value;
            var propertyType    = memberInfo.MemberType.ResolvedType;

            if (value != null)
            {
                object convertedValue;
                if (RepresentationManager.TryConvertFromRepresentation(
                        memberInfo.MemberType,
                        new [] { value },
                        out convertedValue))
                {
                    translatedValue = convertedValue;
                }
            }

            // TODO: Special handling if null value comes in for non-nullable property?
            try {
                if (translatedValue != null)
                {
                    if (propertyType.IsEnum)
                    {
                        translatedValue = Enum.ToObject(propertyType, translatedValue);
                    }
                    else if (translatedValue.GetType() != propertyType)
                    {
                        translatedValue = Convert.ChangeType(translatedValue, propertyType);
                    }
                }
            } catch (InvalidCastException ice) {
                Log.Error(TAG, $"Cannot convert from {translatedValue.GetType ().Name} to {propertyType.Name}");
                throw ice;
            }

            var target = ObjectCache.Shared.GetObject(handle);

            memberInfo.SetValue(target, translatedValue);

            if (returnUpdatedValue)
            {
                updatedValue = RepresentationManager.PrepareInteractiveObject(target);
            }

            return(true);
        }
Example #5
0
 public async Task <SetObjectMemberResponse> SetObjectMemberAsync(
     long objHandle,
     RepresentedMemberInfo memberInfo,
     object value,
     bool returnUpdatedValue)
 => (await SendAsync <SetObjectMemberResponse> (
         new SetObjectMemberRequest {
     ObjectHandle = objHandle,
     MemberInfo = memberInfo,
     Value = value,
     ReturnUpdatedValue = returnUpdatedValue
 },
         SessionCancellationToken));
Example #6
0
 public Task <SetObjectMemberResponse> SetObjectMemberAsync(
     long objHandle,
     RepresentedMemberInfo memberInfo,
     object value,
     bool returnUpdatedValue,
     CancellationToken cancellationToken = default)
 => SendAsync <SetObjectMemberResponse> (
     new SetObjectMemberRequest(
         objHandle,
         memberInfo,
         value,
         returnUpdatedValue),
     GetCancellationToken(cancellationToken));
        protected override void ReadMembers()
        {
            Members = new RepresentedMemberInfo [values.Count];
            Values  = new object [values.Count];

            for (int i = 0; i < values.Count; i++)
            {
                var entry = values [i];

                var value = new RepresentedObject(entry.Item2?.GetType());
                ItemPreparer(value, Depth + 1, entry.Item2);
                if (value.Count == 0)
                {
                    value = null;
                }

                Members [i] = entry.Item1;
                Values [i]  = value;
            }
        }
Example #8
0
        /// <summary>
        /// Filter reflected members of an object from an interactive representation.
        /// </summary>
        /// <returns><c>true</c> to include the member, <c>false</c> otherwise.</returns>
        /// <param name="memberInfo">The member to possibly filter out.</param>
        /// <remarks>
        /// We will expose this to RepresentationProvider at some point, but currently
        /// RepresentedMemberInfo and RepresentedType are too complicated for PCL
        /// inclusion. We either need to figure that out, or cull interfaces.
        /// </remarks>
        bool InteractiveObjectMemberFilter(RepresentedMemberInfo memberInfo, object obj)
        {
            // Dont evalute Task<>.Result. Creates deadlock on WPF, unnecessary wait elsewhere.
            if (memberInfo.Name == "Result")
            {
                var declaringType = memberInfo?.DeclaringType?.ResolvedType;
                if (declaringType != null &&
                    declaringType.IsGenericType &&
                    declaringType.GetGenericTypeDefinition() == typeof(Task <>))
                {
                    return(false);
                }
            }

            var debuggerBrowsableAttr = memberInfo
                                        .ResolvedMemberInfo
                                        .GetCustomAttribute <DebuggerBrowsableAttribute> ();

            if (debuggerBrowsableAttr != null &&
                debuggerBrowsableAttr.State == DebuggerBrowsableState.Never)
            {
                return(false);
            }

            // some of the libraries we consume use EditorBrowsableAttribute
            // without adding a DebuggerBrowsable attribute as well
            var editorBrowsableAttr = memberInfo
                                      .ResolvedMemberInfo
                                      .GetCustomAttribute <EditorBrowsableAttribute> ();

            if (editorBrowsableAttr != null)
            {
                switch (editorBrowsableAttr.State)
                {
                case EditorBrowsableState.Never:
                case EditorBrowsableState.Advanced:
                    return(false);
                }
            }

            // Don't evaluate delegate types. It is not useful, and on iOS/Mac it can actually
            // unset existing delegates.
            if (typeof(Delegate).IsAssignableFrom(memberInfo.MemberType.ResolvedType))
            {
                return(false);
            }

            foreach (var provider in providers)
            {
                try {
                    if (!provider.ShouldReadMemberValue(memberInfo, obj))
                    {
                        return(false);
                    }
                } catch (Exception e) {
                    Log.Error(TAG, $"provider {provider}.", e);
                }
            }

            return(true);
        }