public static void CarryOverAutoPropagateValues <TSource, TTarget>(TSource source, TTarget target) { var sourceType = typeof(TSource); var sourceMembers = RTLReflectionTools.SynthesizableMembers(sourceType); var targetType = typeof(TTarget); var targetMembers = RTLReflectionTools.SynthesizableMembers(targetType); foreach (var m in targetMembers) { var targetValue = m.GetValue(target); if (targetValue != null) { return; } var sourceMember = sourceMembers.SingleOrDefault(s => s == m); if (sourceMember == null) { throw new Exception($"Member value is null on target ({targetType}.{m.Name}). Source type {sourceType.Name} does not contain fallback member"); } var carryOverValue = sourceMember.GetValue(source); if (carryOverValue == null) { throw new Exception($"Member value is null on target ({targetType}.{m.Name}). Source type {sourceType.Name} returned null fallback value"); } var backingField = getBackingField(target, m); backingField.SetValue(target, carryOverValue); } }
public static T RecurviseResetToDefaults <T>(T value) { var type = value.GetType(); foreach (var m in RTLReflectionTools.SynthesizableMembers(type)) { var memberType = m.GetMemberType(); var memberValue = m.GetValue(value); var backingField = getBackingField(value, m); if (memberValue is RTLBitArray bitArray) { backingField.SetValue(value, new RTLBitArray().Resized(bitArray.Size).TypeChanged(bitArray.DataType)); continue; } if (RTLModuleHelper.IsSynthesizableSignalType(memberType)) { if (RTLReflectionTools.TryGetNullableType(memberType, out var actualType)) { backingField.SetValue(value, Activator.CreateInstance(actualType)); } else { backingField.SetValue(value, Activator.CreateInstance(memberType)); } continue; } if (RTLModuleHelper.IsSynthesizableObject(memberType)) { RecurviseResetToDefaults(memberValue); continue; } if (RTLModuleHelper.IsSynthesizableArrayType(memberType)) { var emptyArray = Array.CreateInstance(memberType.GetElementType(), (memberValue as Array).Length); backingField.SetValue(value, emptyArray); continue; } } return(value); }
protected virtual IEnumerable <VCDVariable> ToVCDVariables(string name, object value, bool includeToolkitTypes = false) { if (value == null) { return(Enumerable.Empty <VCDVariable>()); } var recursivePrefix = string.IsNullOrEmpty(name) ? "" : $"{name}_"; switch (value) { case Enum v: return(new[] { new VCDVariable($"{name}ToString", value.ToString(), VCDSizeOfValue("")), new VCDVariable($"{name}", value, VCDSizeOfValue(value)) }); case RTLBitArray b: return(new[] { new VCDVariable($"{name}", value, VCDSizeOfValue(value)) }); default: var valueType = value.GetType(); if (value.GetType().IsClass) { var result = new List <VCDVariable>(); var props = RTLReflectionTools.SynthesizableMembers(valueType, includeToolkitTypes); foreach (var m in props) { var memberValue = m.GetValue(value) ?? RTLModuleHelper.Activate(m.GetMemberType()); result.AddRange(ToVCDVariables(m, memberValue, recursivePrefix)); } return(result); } if (valueType.IsConstructedGenericType) { var genericType = valueType.GetGenericTypeDefinition(); // TODO: something smarter then this if (genericType.Name.StartsWith("ValueTuple`")) { var result = new List <VCDVariable>(); var props = RTLReflectionTools.SynthesizableMembers(valueType, includeToolkitTypes).Where(m => m.Name.StartsWith("Item")); foreach (var m in props) { var memberValue = m.GetValue(value) ?? RTLModuleHelper.Activate(m.GetMemberType()); result.AddRange(ToVCDVariables(m, memberValue, recursivePrefix)); } return(result); } } return(new[] { new VCDVariable($"{name}", value, VCDSizeOfValue(value)) }); } }