Пример #1
0
 public void GetPropertyAtIndex <TGetter>(ref TContainer container, int index, ref ChangeTracker changeTracker, ref TGetter getter)
     where TGetter : ICollectionElementPropertyGetter <TContainer>
 {
     getter.VisitProperty <CollectionElementProperty, TElement>(new CollectionElementProperty(this, index, Attributes), ref container, ref changeTracker);
 }
Пример #2
0
 public static bool TryVisitAtPath <TContainer>(ref TContainer container, PropertyPath propertyPath,
                                                int propertyPathIndex, IPropertyVisitor visitor, ref ChangeTracker changeTracker)
 {
     return(TryVisitAtPathImpl(ref container, propertyPath, propertyPathIndex, visitor, ref changeTracker) == VisitErrorCode.Ok);
 }
Пример #3
0
 void ICollectionElementPropertyGetter <TContainer> .VisitCollectionProperty <TProperty, TPropertyValue>(
     TProperty property, ref TContainer container, ref ChangeTracker changeTracker) =>
 ErrorCode = VisitCollectionSetValueProperty <TContainer, TProperty, TPropertyValue, TTargetValue>(property,
                                                                                                   ref container, m_PropertyPath, m_PropertyPathIndex, m_Value, ref changeTracker);
Пример #4
0
        public static void VisitAtPath <TContainer>(ref TContainer container, PropertyPath propertyPath,
                                                    int propertyPathIndex, IPropertyVisitor visitor, ref ChangeTracker changeTracker)
        {
            var status = TryVisitAtPathImpl(ref container, propertyPath, propertyPathIndex, visitor, ref changeTracker);

            switch (status)
            {
            case VisitErrorCode.InvalidPath:
                throw new ArgumentException($"`{propertyPath}` is not a valid path.");
            }
        }
Пример #5
0
        static VisitErrorCode TryVisitAtPathImpl <TContainer>(ref TContainer container, PropertyPath propertyPath,
                                                              int propertyPathIndex, IPropertyVisitor visitor, ref ChangeTracker changeTracker)
        {
            var action = new VisitAtPathGetter <TContainer>(propertyPath, propertyPathIndex, visitor);

            if (PropertyBagResolver.Resolve <TContainer>()
                .FindProperty(propertyPath[propertyPathIndex].Name, ref container, ref changeTracker, ref action))
            {
                return(action.ErrorCode);
            }

            if (typeof(TContainer) != container.GetType())
            {
                return(VisitAtPathCallback.TryExecute(container, propertyPath, propertyPathIndex, visitor, ref changeTracker));
            }

            return(VisitErrorCode.InvalidPath);
        }
Пример #6
0
 public void VisitCollectionProperty <TProperty, TDestinationValue>(TProperty property, ref TContainer container, ref ChangeTracker changeTracker)
     where TProperty : ICollectionProperty <TContainer, TDestinationValue>
 {
     VisitProperty <TProperty, TDestinationValue>(property, ref container, ref changeTracker);
 }
Пример #7
0
        /// <summary>
        /// Sets the value of the property with the given name for the given container.
        /// </summary>
        /// <param name="container">The container whose data will be set.</param>
        /// <param name="name">The property name to set.</param>
        /// <param name="value">The value to assign to the property.</param>
        /// <param name="changeTracker">The change tracker to increment if the value changes.</param>
        public static void SetValue <TContainer, TValue>(ref TContainer container, string name, TValue value, ref ChangeTracker changeTracker)
        {
            var propertyBag = PropertyBagResolver.Resolve <TContainer>();

            if (null == propertyBag)
            {
                throw new Exception($"Failed to resolve property bag for ContainerType=[{typeof(TContainer)}]");
            }

            var action = new SetValueAction <TContainer, TValue> {
                SrcValue = value
            };

            if (!propertyBag.FindProperty(name, ref container, ref changeTracker, ref action))
            {
                throw new Exception($"Failed to find property Name=[{name}] for ContainerType=[{typeof(TContainer)}]");
            }

            if (action.Result == k_ResultErrorConvert)
            {
                throw new Exception($"Failed assign ValueType=[{typeof(TValue)}] to property Name=[{name}] for ContainerType=[{typeof(TContainer)}]");
            }
        }
        VisitStatus TryVisitContainerWithAdapters <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref TValue value, ref ChangeTracker changeTracker)
            where TProperty : IProperty <TContainer, TValue>
        {
            VisitStatus status;

            if (null != m_Adapters)
            {
                for (var i = 0; i < m_Adapters.Count; i++)
                {
                    if ((status = m_Adapters[i].TryVisitContainer(this, property, ref container, ref value, ref changeTracker)) != VisitStatus.Unhandled)
                    {
                        return(status);
                    }
                }
            }

            if ((status = BeginContainer(property, ref container, ref value, ref changeTracker)) == VisitStatus.Handled)
            {
                PropertyContainer.Visit(ref value, this, ref changeTracker);
                EndContainer(property, ref container, ref value, ref changeTracker);
            }

            return(status);
        }
        VisitStatus TryVisitCollectionWithAdapters <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref TValue value, ref ChangeTracker changeTracker)
            where TProperty : ICollectionProperty <TContainer, TValue>
        {
            VisitStatus status;

            if (null != m_Adapters)
            {
                for (var i = 0; i < m_Adapters.Count; i++)
                {
                    if ((status = m_Adapters[i].TryVisitCollection(this, property, ref container, ref value, ref changeTracker)) != VisitStatus.Unhandled)
                    {
                        return(status);
                    }
                }
            }

            if ((status = BeginCollection(property, ref container, ref value, ref changeTracker)) != VisitStatus.Unhandled)
            {
                if (status == VisitStatus.Handled)
                {
                    for (int i = 0, count = property.GetCount(ref container); i < count; i++)
                    {
                        var callback             = new VisitCollectionElementCallback <TContainer>(this);
                        var elementChangeTracker = new ChangeTracker(changeTracker.VersionStorage);

                        property.GetPropertyAtIndex(ref container, i, ref elementChangeTracker, ref callback);

                        if (elementChangeTracker.IsChanged())
                        {
                            changeTracker.IncrementVersion <TProperty, TContainer, TValue>(property, ref container);
                        }
                    }
                }

                EndCollection(property, ref container, ref value, ref changeTracker);
            }

            return(status);
        }
Пример #10
0
 public static bool TrySetValue <TContainer, TTargetValue>(ref TContainer container, PropertyPath propertyPath,
                                                           int propertyPathIndex, TTargetValue value, ref ChangeTracker changeTracker)
 {
     return(TrySetValueImpl(ref container, propertyPath, propertyPathIndex, value, ref changeTracker) == VisitErrorCode.Ok);
 }
Пример #11
0
 public void VisitCollectionProperty <TElementProperty, TElement>(TElementProperty property, ref TContainer container, ref ChangeTracker changeTracker)
     where TElementProperty : ICollectionProperty <TContainer, TElement>, ICollectionElementProperty <TContainer, TElement>
 {
     m_Visitor.VisitCollectionProperty <TElementProperty, TContainer, TElement>(property, ref container, ref changeTracker);
 }
Пример #12
0
        static VisitErrorCode TrySetValueImpl <TContainer, TTargetValue>(ref TContainer container, PropertyPath propertyPath,
                                                                         int propertyPathIndex, TTargetValue value, ref ChangeTracker changeTracker)
        {
            var action = new SetValueAtPathAction <TContainer, TTargetValue>(propertyPath, propertyPathIndex, value);

            if (PropertyBagResolver.Resolve <TContainer>()
                .FindProperty(propertyPath[propertyPathIndex].Name, ref container, ref changeTracker, ref action))
            {
                return(action.ErrorCode);
            }

            if (typeof(TContainer) != container.GetType())
            {
                return(SetValueCallback <TTargetValue> .TryExecute(container, propertyPath, propertyPathIndex, value, ref changeTracker));
            }

            return(VisitErrorCode.InvalidPath);
        }
Пример #13
0
            public static VisitErrorCode TryExecute(object container, PropertyPath propertyPath, int propertyPathIndex, TValue value, ref ChangeTracker changeTracker)
            {
                var action = new SetValueCallback <TValue>(container, propertyPath, propertyPathIndex, value, ref changeTracker);

                PropertyBagResolver.Resolve(container.GetType()).Cast(ref action);
                changeTracker = action.m_ChangeTracker;
                return(action.m_ErrorCode);
            }
Пример #14
0
 private SetValueCallback(object container, PropertyPath propertyPath, int propertyPathIndex, TValue value, ref ChangeTracker changeTracker)
 {
     m_Container         = container;
     m_PropertyPath      = propertyPath;
     m_PropertyPathIndex = propertyPathIndex;
     Value           = value;
     m_ChangeTracker = changeTracker;
     m_ErrorCode     = VisitErrorCode.Ok;
 }
Пример #15
0
 public void VisitProperty <TProperty, TSourceValue>(TProperty property, ref TContainer container, ref ChangeTracker changeTracker)
     where TProperty : IProperty <TContainer, TSourceValue>
 {
     if (!TypeConversion.TryConvert(property.GetValue(ref container), out DstValue))
     {
         Result = k_ResultErrorConvert;
     }
 }
 void ICollectionElementPropertyGetter <TContainer> .VisitCollectionProperty <TElementProperty, TElement>(TElementProperty property, ref TContainer container, ref ChangeTracker changeTracker)
 => m_Visitor.VisitCollectionProperty <TElementProperty, TContainer, TElement>(property, ref container, ref changeTracker);
Пример #17
0
            public void VisitProperty <TProperty, TDestinationValue>(TProperty property, ref TContainer container, ref ChangeTracker changeTracker)
                where TProperty : IProperty <TContainer, TDestinationValue>
            {
                if (!TypeConversion.TryConvert <TSourceValue, TDestinationValue>(SrcValue, out var dstValue))
                {
                    Result = k_ResultErrorConvert;
                    return;
                }

                if (CustomEquality.Equals(dstValue, property.GetValue(ref container)))
                {
                    return;
                }

                property.SetValue(ref container, dstValue);
                changeTracker.IncrementVersion <TProperty, TContainer, TDestinationValue>(property, ref container);
            }
 /// <summary>
 /// Invoked before entering into a collection node.
 ///
 /// If false is returned, the collection should NOT be visited and <see cref="EndCollection{TProperty,TContainer,TValue}"/> should NOT be called.
 /// </summary>
 /// <returns>True if the visit event was consumed.</returns>
 protected virtual VisitStatus BeginCollection <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref TValue value, ref ChangeTracker changeTracker)
     where TProperty : ICollectionProperty <TContainer, TValue>
 {
     return(VisitStatus.Handled);
 }
Пример #19
0
        /// <summary>
        /// Sets the value of the property with the given name for the given container.
        /// </summary>
        /// <param name="container">The container whose data will be set.</param>
        /// <param name="name">The property name to set.</param>
        /// <param name="value">The value to assign to the property.</param>
        /// <param name="versionStorage">The version storage to increment if the value is changed.</param>
        public static void SetValue <TContainer, TValue>(ref TContainer container, string name, TValue value, IVersionStorage versionStorage = null)
        {
            var changeTracker = new ChangeTracker(versionStorage);

            SetValue(ref container, name, value, ref changeTracker);
        }
 /// <summary>
 /// Invoked after completing a collection node. Only if <see cref="BeginCollection{TProperty,TContainer,TValue}"/> returned true.
 /// </summary>
 protected virtual void EndCollection <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref TValue value, ref ChangeTracker changeTracker)
     where TProperty : ICollectionProperty <TContainer, TValue>
 {
 }
Пример #21
0
 void IPropertyGetter <TContainer> .VisitProperty <TProperty, TPropertyValue>(TProperty property,
                                                                              ref TContainer container, ref ChangeTracker changeTracker) =>
 ErrorCode = VisitPropertyAtPath <TContainer, TProperty, TPropertyValue>(property, ref container, m_PropertyPath,
                                                                         m_PropertyPathIndex, m_Visitor, ref changeTracker);
        public VisitStatus VisitProperty <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref ChangeTracker changeTracker)
            where TProperty : IProperty <TContainer, TValue>
        {
            // Give users a chance to filter based on the data.
            if (IsExcluded <TProperty, TContainer, TValue>(property, ref container))
            {
                return(VisitStatus.Handled);
            }

            var value = property.GetValue(ref container);
            var valueChangeTracker = new ChangeTracker(changeTracker.VersionStorage);

            var status = property.IsContainer
                ? TryVisitContainerWithAdapters(property, ref container, ref value, ref valueChangeTracker)
                : TryVisitValueWithAdapters(property, ref container, ref value, ref valueChangeTracker);

            if (property.IsReadOnly)
            {
                return(status);
            }

            property.SetValue(ref container, value);

            if (valueChangeTracker.IsChanged())
            {
                changeTracker.IncrementVersion <TProperty, TContainer, TValue>(property, ref container);
            }

            return(status);
        }
Пример #23
0
 void ICollectionElementPropertyGetter <TContainer> .VisitCollectionProperty <TProperty, TPropertyValue>(
     TProperty property, ref TContainer container, ref ChangeTracker changeTracker)
 {
     ErrorCode = VisitCollectionPropertyAtPath <TContainer, TProperty, TPropertyValue>(property, ref container,
                                                                                       m_PropertyPath, m_PropertyPathIndex, m_Visitor, ref changeTracker);
 }
        public VisitStatus VisitCollectionProperty <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref ChangeTracker changeTracker)
            where TProperty : ICollectionProperty <TContainer, TValue>
        {
            // Give users a chance to filter based on the data.
            if (IsExcluded <TProperty, TContainer, TValue>(property, ref container))
            {
                return(VisitStatus.Handled);
            }

            var value = property.GetValue(ref container);

            return(TryVisitCollectionWithAdapters(property, ref container, ref value, ref changeTracker));
        }
Пример #25
0
 static VisitErrorCode VisitPropertyAtPath <TContainer, TProperty, TPropertyValue>(TProperty property,
                                                                                   ref TContainer container, PropertyPath propertyPath, int propertyPathIndex, IPropertyVisitor visitor,
                                                                                   ref ChangeTracker changeTracker)
     where TProperty : IProperty <TContainer, TPropertyValue>
 {
     if (propertyPathIndex < propertyPath.PartsCount - 1)
     {
         var sub    = property.GetValue(ref container);
         var status = TryVisitAtPathImpl(ref sub, propertyPath, propertyPathIndex + 1, visitor, ref changeTracker);
         if (status == VisitErrorCode.Ok)
         {
             property.SetValue(ref container, sub);
         }
         return(status);
     }
     else
     {
         visitor.VisitProperty <TProperty, TContainer, TPropertyValue>(property, ref container, ref changeTracker);
     }
     return(VisitErrorCode.Ok);
 }
        VisitStatus TryVisitValueWithAdapters <TProperty, TContainer, TValue>(TProperty property, ref TContainer container, ref TValue value, ref ChangeTracker changeTracker)
            where TProperty : IProperty <TContainer, TValue>
        {
            if (null != m_Adapters)
            {
                for (var i = 0; i < m_Adapters.Count; i++)
                {
                    VisitStatus status;

                    if ((status = m_Adapters[i].TryVisitValue(this, property, ref container, ref value, ref changeTracker)) != VisitStatus.Unhandled)
                    {
                        return(status);
                    }
                }
            }

            return(Visit(property, ref container, ref value, ref changeTracker));
        }
Пример #27
0
        private static VisitErrorCode VisitCollectionPropertyAtPath <TContainer, TProperty, TPropertyValue>(TProperty property,
                                                                                                            ref TContainer container, PropertyPath propertyPath, int propertyPathIndex, IPropertyVisitor visitor,
                                                                                                            ref ChangeTracker changeTracker)
            where TProperty : ICollectionProperty <TContainer, TPropertyValue>
        {
            if (propertyPathIndex < propertyPath.PartsCount - 1 || propertyPath[propertyPathIndex].IsListItem)
            {
                var index = propertyPath[propertyPathIndex].Index;
                if (index >= property.GetCount(ref container))
                {
                    return(VisitErrorCode.InvalidPath);
                }
                var getter = new VisitCollectionItemAtPathGetter <TContainer>(propertyPath, propertyPathIndex, visitor);
                property.GetPropertyAtIndex(ref container, index, ref changeTracker, ref getter);
                return(getter.ErrorCode);
            }

            visitor.VisitCollectionProperty <TProperty, TContainer, TPropertyValue>(property, ref container, ref changeTracker);

            return(VisitErrorCode.Ok);
        }
Пример #28
0
        public static void SetValue <TContainer, TTargetValue>(ref TContainer container, PropertyPath propertyPath,
                                                               int propertyPathIndex, TTargetValue value, ref ChangeTracker changeTracker)
        {
            var status = TrySetValueImpl(ref container, propertyPath, propertyPathIndex, value, ref changeTracker);

            switch (status)
            {
            case VisitErrorCode.InvalidPath: throw new ArgumentException($"Could not set value at `{propertyPath}`");

            case VisitErrorCode.InvalidCast: throw new InvalidCastException($"Could not set value of type {typeof(TTargetValue).Name} at `{propertyPath}`");
            }
        }