internal static void Construct <TDstContainer, TSrcContainer>(
     ref TDstContainer dstContainer,
     ref TSrcContainer srcContainer,
     VisitResult result,
     PropertyContainerConstructOptions options = default)
 {
     if (RuntimeTypeInfoCache <TDstContainer> .IsAbstractOrInterface() || typeof(TDstContainer) != dstContainer.GetType())
     {
         var propertyBag = PropertyBagResolver.Resolve(dstContainer.GetType());
         var action      = new ConstructAbstractType <TSrcContainer>
         {
             Options           = options,
             Result            = result,
             SrcContainer      = srcContainer,
             DstContainerBoxed = dstContainer
         };
         propertyBag.Cast(ref action);
         dstContainer = (TDstContainer)action.DstContainerBoxed;
     }
     else
     {
         var visitor = new TypeConstructionVisitor <TDstContainer>(dstContainer, result, options);
         Visit(ref srcContainer, ref visitor);
         dstContainer = visitor.Target;
     }
 }
예제 #2
0
            public static VisitErrorCode TryExecute(object container, PropertyPath propertyPath, int propertyPathIndex, int count, ref ChangeTracker changeTracker)
            {
                var action = new SetCountCallback(container, propertyPath, propertyPathIndex, count, ref changeTracker);

                PropertyBagResolver.Resolve(container.GetType()).Cast(ref action);
                changeTracker = action.m_ChangeTracker;
                return(action.m_ErrorCode);
            }
            public static VisitErrorCode TryExecute(object target, PropertyPath propertyName, int index, ref ChangeTracker changeTracker, out TValue value)
            {
                var action = new GetValueFromActualTypeCallback <TValue>(target, propertyName, index, ref changeTracker);

                PropertyBagResolver.Resolve(target.GetType()).Cast(ref action);
                value = action.m_Value;
                return(action.m_ErrorCode);
            }
예제 #4
0
            public static VisitErrorCode TryExecute(object target, PropertyPath propertyName, int index, IPropertyVisitor visitor,
                                                    ref ChangeTracker changeTracker)
            {
                var action = new VisitAtPathCallback(target, propertyName, index, visitor, ref changeTracker);

                PropertyBagResolver.Resolve(target.GetType()).Cast(ref action);
                changeTracker = action.m_ChangeTracker;
                return(action.errorCode);
            }
예제 #5
0
            public static VisitErrorCode TryExecute(object target, PropertyPath propertyName, int index, ref ChangeTracker changeTracker, out int count)
            {
                var action = new GetCountFromActualTypeCallback(target, propertyName, index, ref changeTracker);

                PropertyBagResolver.Resolve(target.GetType()).Cast(ref action);
                changeTracker = action.m_ChangeTracker;
                count         = action.m_Count;
                return(action.m_ErrorCode);
            }
예제 #6
0
            public TransferVisitor(TDstContainer dstContainer, VisitResult result)
            {
                m_Result         = result;
                m_DstContainer   = dstContainer;
                m_DstPropertyBag = PropertyBagResolver.Resolve <TDstContainer>();

                if (null == m_DstPropertyBag)
                {
                    throw new ArgumentException($"No property bag exists for the given Type=[{typeof(TDstContainer)}]");
                }
            }
        public TypeConstructionVisitor(TDstContainer dstContainer, VisitResult result, PropertyContainerConstructOptions options)
        {
            m_Options        = options;
            Result           = result;
            m_DstContainer   = dstContainer;
            m_DstPropertyBag = PropertyBagResolver.Resolve <TDstContainer>();

            if (null == m_DstPropertyBag)
            {
                throw new ArgumentException($"No property bag exists for the given Type=[{typeof(TDstContainer)}]");
            }
        }
 static void DoTransfer <TDestination, TSource>(ref TDestination destination, ref TSource source, ref ChangeTracker changeTracker)
 {
     if (RuntimeTypeInfoCache <TSource> .IsAbstractOrInterface() || typeof(TSource) != source.GetType())
     {
         var propertyBag = PropertyBagResolver.Resolve(source.GetType());
         var action      = new TransferAbstractType <TDestination>
         {
             Destination     = destination,
             SourceContainer = source
         };
         propertyBag.Cast(ref action);
         destination = action.Destination;
     }
     else
     {
         Visit(ref destination, new TransferVisitor <TSource>(source), ref changeTracker);
     }
 }
예제 #9
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);
        }
예제 #10
0
        static VisitErrorCode TrySetCountImpl <TContainer>(ref TContainer container, PropertyPath propertyPath, int propertyPathIndex,
                                                           int count, ref ChangeTracker changeTracker)
        {
            var action = new SetCountAtPathAction <TContainer>(propertyPath, propertyPathIndex, count);

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

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

            return(VisitErrorCode.InvalidPath);
        }
예제 #11
0
        internal static VisitErrorCode TryGetCountImpl <TContainer>(ref TContainer container, PropertyPath propertyPath, int propertyPathIndex,
                                                                    ref ChangeTracker changeTracker, out int count)
        {
            var action = new GetCountAtPathGetter <TContainer>(propertyPath, propertyPathIndex);

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

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

            count = -1;
            return(VisitErrorCode.InvalidPath);
        }
        static VisitErrorCode TryGetValueImpl <TContainer, TTargetValue>(ref TContainer container, PropertyPath propertyPath,
                                                                         int propertyPathIndex, ref ChangeTracker changeTracker, out TTargetValue value)
        {
            var action = new GetValueAtPathAction <TContainer, TTargetValue>(propertyPath, propertyPathIndex);

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

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

            value = default;
            return(VisitErrorCode.InvalidPath);
        }
예제 #13
0
        public VisitStatus VisitCollectionProperty <TDestinationProperty, TDestinationContainer, TDestinationValue>(TDestinationProperty dstProperty,
                                                                                                                    ref TDestinationContainer dstContainer, ref ChangeTracker propertyChangeTracker)
            where TDestinationProperty : ICollectionProperty <TDestinationContainer, TDestinationValue>
        {
            var sourcePropertyBag = PropertyBagResolver.Resolve <TSourceContainer>();

            if (null == sourcePropertyBag)
            {
                throw new Exception();
            }

            var transfer = new TransferCollectionAction <TDestinationProperty, TDestinationContainer, TDestinationValue>
            {
                DstProperty  = dstProperty,
                DstContainer = dstContainer
            };

            sourcePropertyBag.FindProperty(dstProperty.GetName(), ref m_SrcContainer, ref propertyChangeTracker, ref transfer);
            dstContainer = transfer.DstContainer;

            return(VisitStatus.Handled);
        }
예제 #14
0
        /// <summary>
        /// Gets the value of the property with the given name for the given container.
        /// </summary>
        /// <param name="container">The container hosting the data.</param>
        /// <param name="name">The property name to get.</param>
        /// <param name="value">Contains the value if the property is found and the type can be converted; otherwise this is set to default.</param>
        /// <returns>True if the property was found and the value was converted.</returns>
        public static bool TryGetValue <TContainer, TValue>(ref TContainer container, string name, out TValue value)
        {
            var propertyBag = PropertyBagResolver.Resolve <TContainer>();

            if (null == propertyBag)
            {
                value = default;
                return(false);
            }

            var changeTracker = new ChangeTracker();
            var action        = new GetValueAction <TContainer, TValue>();

            if (!PropertyBagResolver.Resolve <TContainer>().FindProperty(name, ref container, ref changeTracker, ref action))
            {
                value = default;
                return(false);
            }

            value = action.DstValue;
            return(action.Result == k_ResultSuccess);
        }
예제 #15
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)}]");
            }
        }
예제 #16
0
        /// <summary>
        /// Gets the value of the property with the given name for the given container.
        /// </summary>
        /// <param name="container">The container hosting the data.</param>
        /// <param name="name">The property name to get.</param>
        /// <returns>The value of the property converted to the given type.</returns>
        public static TValue GetValue <TContainer, TValue>(ref TContainer container, string name)
        {
            var propertyBag = PropertyBagResolver.Resolve <TContainer>();

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

            var changeTracker = new ChangeTracker();
            var action        = new GetValueAction <TContainer, TValue>();

            if (!PropertyBagResolver.Resolve <TContainer>().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 get ValueType=[{typeof(TValue)}] from property Name=[{name}] for ContainerType=[{typeof(TContainer)}]");
            }

            return(action.DstValue);
        }
예제 #17
0
 static void Transfer <TDstContainer, TSrcContainer>(
     ref TDstContainer dstContainer,
     ref TSrcContainer srcContainer,
     VisitResult result)
 {
     if (RuntimeTypeInfoCache <TDstContainer> .IsAbstractOrInterface() || typeof(TDstContainer) != dstContainer.GetType())
     {
         var propertyBag = PropertyBagResolver.Resolve(dstContainer.GetType());
         var action      = new TransferAbstractType <TSrcContainer>
         {
             Result            = result,
             SrcContainer      = srcContainer,
             DstContainerBoxed = dstContainer
         };
         propertyBag.Cast(ref action);
         dstContainer = (TDstContainer)action.DstContainerBoxed;
     }
     else
     {
         var visitor = new TransferVisitor <TDstContainer>(dstContainer, result);
         Visit(ref srcContainer, ref visitor);
         dstContainer = visitor.Target;
     }
 }