public Task <SetObjectMemberResponse> SetObjectMemberAsync( long objHandle, RepresentedMemberInfo memberInfo, object value, bool returnUpdatedValue, CancellationToken cancellationToken = default) => throw new NotImplementedException();
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; } }
public SetObjectMemberRequest( long objectHandle, RepresentedMemberInfo memberInfo, object value, bool returnUpdatedValue) { ObjectHandle = objectHandle; MemberInfo = memberInfo; Value = value; ReturnUpdatedValue = returnUpdatedValue; }
/// <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); }
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));
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; } }
/// <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); }