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 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; } }
public static bool TryConstructFromData <TDstValue, TSrcValue>(ref TSrcValue srcValue, string typeIdentifierKey, VisitResult result, out TDstValue dstValue) { if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TDstValue))) { dstValue = default; return(false); } // Try to construct based on the source type. if (TypeConstruction.TryConstruct(srcValue.GetType(), out dstValue)) { return(true); } // Try to construct based on the destination type. if (TypeConstruction.TryConstruct(out dstValue)) { return(true); } // If type identifier key option is not set, cannot construct this type. if (string.IsNullOrEmpty(typeIdentifierKey)) { return(false); } // Try to get destination type name from type identifier meta data. if (!PropertyContainer.TryGetValue(ref srcValue, typeIdentifierKey, out string assemblyQualifiedTypeName)) { result.AddLog($"PropertyContainer.Construct failed to construct DstType=[{typeof(TDstValue)}]. SrcValue Property=[{typeIdentifierKey}] was not found."); return(false); } // Verify destination type name is valid. if (string.IsNullOrEmpty(assemblyQualifiedTypeName)) { result.AddException(new InvalidOperationException($"PropertyContainer.Construct failed to construct DstType=[{typeof(TDstValue)}]. SrcValue Property=[{typeIdentifierKey}] contained null or empty type information.")); return(false); } // Try to get destination type. var dstType = Type.GetType(assemblyQualifiedTypeName); if (null == dstType) { result.AddException(new InvalidOperationException($"PropertyContainer.Construct failed to construct DstType=[{typeof(TDstValue)}]. Could not resolve type from TypeName=[{assemblyQualifiedTypeName}].")); return(false); } return(TypeConstruction.TryConstruct(dstType, out dstValue)); }