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;
     }
 }
 static ContainerPropertyBag()
 {
     if (!RuntimeTypeInfoCache.IsContainerType(typeof(TContainer)))
     {
         throw new InvalidOperationException($"Failed to create a property bag for Type=[{typeof(TContainer)}]. The type is not a valid container type.");
     }
 }
        public static VisitResult Construct <TDstContainer, TSrcContainer>(ref TDstContainer dstContainer, ref TSrcContainer srcContainer, PropertyContainerConstructOptions options = default)
        {
            if (!RuntimeTypeInfoCache <TSrcContainer> .IsValueType() && srcContainer == null)
            {
                throw new ArgumentNullException(nameof(srcContainer));
            }

            if (!RuntimeTypeInfoCache <TDstContainer> .IsValueType() && dstContainer == null)
            {
                if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TDstContainer)))
                {
                    throw new ArgumentNullException(nameof(dstContainer));
                }

                if (!TypeConstruction.TryConstruct(srcContainer.GetType(), out dstContainer))
                {
                    throw new ArgumentNullException(nameof(dstContainer));
                }
            }

            var result = VisitResult.GetPooled();

            Construct(ref dstContainer, ref srcContainer, result, options);
            return(result);
        }
                public void VisitProperty <TDstElementProperty, TDstElementValue>(
                    TDstElementProperty dstElementProperty,
                    ref TDstContainer dstContainer,
                    ref ChangeTracker changeTracker)
                    where TDstElementProperty : ICollectionElementProperty <TDstContainer, TDstElementValue>
                {
                    if (!dstElementProperty.IsContainer)
                    {
                        return;
                    }

                    if (!RuntimeTypeInfoCache <TSrcElementValue> .IsValueType() && null == SrcElementValue)
                    {
                        dstElementProperty.SetValue(ref dstContainer, default);
                        return;
                    }

                    var dstValue = dstElementProperty.GetValue(ref dstContainer);

                    if (!RuntimeTypeInfoCache <TDstElementValue> .IsValueType() && null == dstValue || SrcElementValue is TDstElementValue && dstValue.GetType() != SrcElementValue.GetType())
                    {
                        if (!TypeConstructionUtility.TryConstructFromData(ref SrcElementValue, Options.TypeIdentifierKey, Result, out dstValue))
                        {
                            return;
                        }
                    }

                    PropertyContainer.Construct(ref dstValue, ref SrcElementValue, Result, Options);

                    dstElementProperty.SetValue(ref dstContainer, dstValue);
                }
Esempio n. 5
0
                    public void VisitProperty <TDstElementProperty, TDstElementValue>(
                        TDstElementProperty dstElementProperty,
                        ref TDstContainer dstContainer,
                        ref ChangeTracker changeTracker)
                        where TDstElementProperty : ICollectionElementProperty <TDstContainer, TDstElementValue>
                    {
                        if (dstElementProperty.IsReadOnly)
                        {
                            return;
                        }

                        if (!RuntimeTypeInfoCache <TSrcElementValue> .IsValueType() && null == SrcElementValue)
                        {
                            dstElementProperty.SetValue(ref dstContainer, default);
                        }
                        else if (TypeConversion.TryConvert <TSrcElementValue, TDstElementValue>(SrcElementValue, out var dstElementValue))
                        {
                            dstElementProperty.SetValue(ref dstContainer, dstElementValue);
                        }
                        else if (dstElementProperty.IsContainer)
                        {
                            dstElementValue = dstElementProperty.GetValue(ref dstContainer);

                            if (RuntimeTypeInfoCache <TDstElementValue> .IsValueType() || null != dstElementValue)
                            {
                                Transfer(ref dstElementValue, ref SrcElementValue, Result);
                            }

                            dstElementProperty.SetValue(ref dstContainer, dstElementValue);
                        }
                        else
                        {
                            Result.AddLog($"PropertyContainer.Transfer ContainerType=[{typeof(TDstContainer)}] PropertyName=[{dstElementProperty.GetName()}] could not be transferred.");
                        }
                    }
            public void VisitCollectionProperty <TDstProperty, TDstValue>(
                TDstProperty dstProperty,
                ref TDstContainer dstContainer,
                ref ChangeTracker changeTracker)
                where TDstProperty : ICollectionProperty <TDstContainer, TDstValue>
            {
                if (!RuntimeTypeInfoCache <TSrcValue> .IsValueType() && null == SrcValue)
                {
                    dstProperty.SetValue(ref dstContainer, default);
                    return;
                }

                var dstValue = dstProperty.GetValue(ref dstContainer);

                if (!RuntimeTypeInfoCache <TDstValue> .IsValueType() && null == dstValue)
                {
                    if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TDstValue)))
                    {
                        return;
                    }

                    if (TypeConstruction.TryConstruct(SrcValue.GetType(), out dstValue))
                    {
                        dstProperty.SetValue(ref dstContainer, dstValue);
                    }
                    else if (TypeConstruction.TryConstruct(out dstValue))
                    {
                        dstProperty.SetValue(ref dstContainer, dstValue);
                    }
                    else if (typeof(TDstValue).IsArray)
                    {
                        dstValue = (TDstValue)Activator.CreateInstance(typeof(TDstValue), SrcProperty.GetCount(ref SrcContainer));
                        dstProperty.SetValue(ref dstContainer, dstValue);
                    }
                }

                var srcCount = SrcProperty.GetCount(ref SrcContainer);
                var dstCount = dstProperty.GetCount(ref dstContainer);

                if (srcCount != dstCount)
                {
                    dstProperty.SetCount(ref dstContainer, srcCount);
                }

                for (var i = 0; i < srcCount; i++)
                {
                    var action = new SrcCollectionElementGetter <TDstProperty, TDstValue>
                    {
                        Options      = Options,
                        Result       = Result,
                        DstProperty  = dstProperty,
                        DstContainer = dstContainer,
                        Index        = i
                    };

                    SrcProperty.GetPropertyAtIndex(ref SrcContainer, i, ref changeTracker, ref action);

                    dstContainer = action.DstContainer;
                }
            }
Esempio n. 7
0
            public CollectionElementProperty(ArrayProperty <TContainer, TElement> property, int index, IPropertyAttributeCollection attributes = null)
            {
                m_Property  = property;
                IsContainer = RuntimeTypeInfoCache <TElement> .IsContainerType();

                Attributes = attributes;
                Index      = index;
            }
Esempio n. 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GeneratePropertyBagsForTypeAttribute"/> attribute.
        /// </summary>
        /// <param name="type">The type to generate a property bag for.</param>
        /// <exception cref="ArgumentException">The specified type is not a valid container type.</exception>
        public GeneratePropertyBagsForTypeAttribute(Type type)
        {
            if (!RuntimeTypeInfoCache.IsContainerType(type))
            {
                throw new ArgumentException($"{type.Name} is not a valid container type.");
            }

            Type = type;
        }
        /// <summary>
        /// Tries to visit the specified <paramref name="container"/> by ref using the specified <paramref name="visitor"/>.
        /// </summary>
        /// <param name="visitor">The visitor.</param>
        /// <param name="container">The container to visit.</param>
        /// <param name="errorCode">When this method returns, contains the error code.</param>
        /// <typeparam name="TContainer">The declared container type.</typeparam>
        /// <returns><see langword="true"/> if the visitation succeeded; <see langword="false"/> otherwise.</returns>
        public static bool TryAccept <TContainer>(IPropertyBagVisitor visitor, ref TContainer container, out VisitErrorCode errorCode)
        {
            if (!RuntimeTypeInfoCache <TContainer> .IsContainerType)
            {
                errorCode = VisitErrorCode.InvalidContainerType;
                return(false);
            }

            // Can not visit a null container.
            if (RuntimeTypeInfoCache <TContainer> .CanBeNull)
            {
                if (EqualityComparer <TContainer> .Default.Equals(container, default))
                {
                    errorCode = VisitErrorCode.NullContainer;
                    return(false);
                }
            }

            if (!RuntimeTypeInfoCache <TContainer> .IsValueType && typeof(TContainer) != container.GetType())
            {
                if (!RuntimeTypeInfoCache.IsContainerType(container.GetType()))
                {
                    errorCode = VisitErrorCode.InvalidContainerType;
                    return(false);
                }

                var properties = PropertyBagStore.GetPropertyBag(container.GetType());

                if (null == properties)
                {
                    errorCode = VisitErrorCode.MissingPropertyBag;
                    return(false);
                }

                // At this point the generic parameter is useless to us since it's not the correct type.
                // Instead we need to retrieve the untyped property bag and accept on that. Since we don't know the type
                // We need to box the container and let the property bag cast it internally.
                var boxed = (object)container;
                properties.Accept(visitor, ref boxed);
                container = (TContainer)boxed;
            }
            else
            {
                var properties = PropertyBagStore.GetPropertyBag <TContainer>();

                if (null == properties)
                {
                    errorCode = VisitErrorCode.MissingPropertyBag;
                    return(false);
                }

                PropertyBag.AcceptWithSpecializedVisitor(properties, visitor, ref container);
            }

            errorCode = VisitErrorCode.Ok;
            return(true);
        }
        public static void Transfer <TDestination, TSource>(ref TDestination destination, ref TSource source, ref ChangeTracker changeTracker)
        {
            if (!RuntimeTypeInfoCache <TDestination> .IsValueType() && destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            DoTransfer(ref destination, ref source, ref changeTracker);
        }
Esempio n. 11
0
        public UnmanagedProperty(string name, int offset, bool readOnly = false, IPropertyAttributeCollection attributes = null)
        {
            m_Name      = name;
            Offset      = offset;
            IsReadOnly  = readOnly;
            IsContainer = RuntimeTypeInfoCache <TValue> .IsContainerType();

            Attributes = attributes;
        }
Esempio n. 12
0
        public ListProperty(string name, Getter getter, Setter setter, IPropertyAttributeCollection attributes = null)
        {
            m_Name       = name;
            m_Getter     = getter;
            m_Setter     = setter;
            m_Attributes = attributes;

            if (RuntimeTypeInfoCache <TElement> .IsArray())
            {
                throw new Exception("ArrayProperty`2 does not support array of array");
            }
        }
Esempio n. 13
0
        public static VisitResult Transfer <TDstContainer, TSrcContainer>(ref TDstContainer dstContainer, ref TSrcContainer srcContainer)
        {
            if (!RuntimeTypeInfoCache <TDstContainer> .IsValueType() && dstContainer == null)
            {
                throw new ArgumentNullException(nameof(dstContainer));
            }

            var result = VisitResult.GetPooled();

            Transfer(ref dstContainer, ref srcContainer, result);
            return(result);
        }
Esempio n. 14
0
                public void VisitCollectionProperty <TDstProperty, TDstValue>(
                    TDstProperty dstProperty,
                    ref TDstContainer dstContainer,
                    ref ChangeTracker changeTracker)
                    where TDstProperty : ICollectionProperty <TDstContainer, TDstValue>
                {
                    if (dstProperty.IsReadOnly)
                    {
                        return;
                    }

                    var dstValue = dstProperty.GetValue(ref dstContainer);

                    if (!RuntimeTypeInfoCache <TSrcValue> .IsValueType() && null == SrcValue)
                    {
                        dstProperty.SetValue(ref dstContainer, default);
                    }
                    else if (RuntimeTypeInfoCache <TSrcValue> .IsValueType() || null != dstValue)
                    {
                        var srcCount = SrcProperty.GetCount(ref SrcContainer);
                        var dstCount = dstProperty.GetCount(ref dstContainer);

                        if (srcCount != dstCount)
                        {
                            dstProperty.SetCount(ref dstContainer, srcCount);
                        }

                        for (var i = 0; i < srcCount; i++)
                        {
                            var action = new SrcCollectionElementGetter <TDstProperty, TDstValue>
                            {
                                Result       = Result,
                                DstProperty  = dstProperty,
                                DstContainer = dstContainer,
                                Index        = i
                            };

                            SrcProperty.GetPropertyAtIndex(ref SrcContainer, i, ref changeTracker, ref action);

                            dstContainer = action.DstContainer;
                        }
                    }
                    else
                    {
                        Result.AddLog($"PropertyContainer.Transfer ContainerType=[{typeof(TDstContainer)}] PropertyName=[{dstProperty.GetName()}] could not be transferred.");
                    }
                }
 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);
     }
 }
Esempio n. 16
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;
     }
 }