/// <inheritdoc /> public override void VisitField(CppField cppField) { if (!cppField.CppType.HasVariableData) { // Ignore field with sized size. // return; } // Variable data field. // WriteLine($"// Serialize variable data field : {cppField.FieldInfo.Name} {cppField.CppType.Name}"); WriteLine("//"); if (cppField.FieldInfo.IsFixedSizedArray()) { // Serialize fixed length array. // FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); WriteLine($"dataSize = this.{cppField.FieldInfo.Name}.SerializeVariableData({arrayAttribute.Length}, buffer, objectOffset + {cppField.CppStructOffset}, dataOffset);"); } else { WriteLine($"dataSize = ((global::Mlos.Core.ICodegenType)this.{cppField.FieldInfo.Name}).SerializeVariableData(buffer, objectOffset + {cppField.CppStructOffset}, dataOffset);"); } WriteLine("totalDataSize += dataSize;"); WriteLine("dataOffset += dataSize;"); WriteLine(); }
/// <inheritdoc /> public override void VisitField(CppField cppField) { // Nothing. // if (!cppField.FieldInfo.FieldType.IsClass && !cppField.FieldInfo.IsFixedSizedArray()) { // Primitive types and structures does not need to be allocated. // return; } Type fieldType = cppField.FieldInfo.FieldType; if (cppField.FieldInfo.IsFixedSizedArray()) { // Create fixed length array. // fieldType = fieldType.GetElementType(); FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); WriteBlock($@"this.{cppField.FieldInfo.Name} = new {fieldType.FullName}[{arrayAttribute.Length}];"); if (fieldType.IsClass) { WriteBlock($@"this.{cppField.FieldInfo.Name}.Create();"); } } else { WriteBlock($@"this.{cppField.FieldInfo.Name} = new {fieldType.FullName}();"); } }
/// <inheritdoc /> public override void VisitField(CppField cppField) { string fieldName = cppField.FieldInfo.Name; string fieldOffset = $"{cppField.CppStructOffset}"; Type fieldType = cppField.FieldInfo.FieldType; if (cppField.FieldInfo.IsFixedSizedArray()) { // When field is array, get element type to use correct proxy type. // fieldType = fieldType.GetElementType(); } // Get the proxy type name. // string cppProxyTypeFullName = CppTypeMapper.GetCppProxyFullTypeName(fieldType); // Write the property, for arrays, use PropertyArrayProxy. // if (cppField.FieldInfo.IsFixedSizedArray()) { // Get the fixed array length and write the property. // FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); WriteLine($"::Mlos::Core::PropertyArrayProxy<{cppProxyTypeFullName}, {arrayAttribute.Length}> {fieldName}() {{ return ::Mlos::Core::PropertyArrayProxy<{cppProxyTypeFullName}, {arrayAttribute.Length}>(buffer, {fieldOffset}); }}"); } else { WriteLine($"{cppProxyTypeFullName} {fieldName}() {{ return {cppProxyTypeFullName}(buffer, {fieldOffset}); }}"); } WriteLine(); }
/// <inheritdoc /> public override void VisitField(CppField cppField) { // Always serialize fixed part of the type. // WriteLine($"// Fixed variable length field : {cppField.FieldInfo.Name} {cppField.CppType.Name}"); WriteLine("//"); if (cppField.FieldInfo.IsFixedSizedArray()) { // Serialize fixed length array. // FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); WriteLine(cppField.CppType.IsCodegenType ? $"this.{cppField.FieldInfo.Name}.SerializeFixedPartCodegenTypeArray({arrayAttribute.Length}, buffer, objectOffset + {cppField.CppStructOffset});" : $"this.{cppField.FieldInfo.Name}.SerializeFixedPartPrimitiveTypeArray({arrayAttribute.Length}, buffer, objectOffset + {cppField.CppStructOffset});"); } else { WriteLine(cppField.CppType.IsCodegenType ? $"((global::Mlos.Core.ICodegenType)this.{cppField.FieldInfo.Name}).SerializeFixedPart(buffer, objectOffset + {cppField.CppStructOffset});" : $"CodegenTypeExtensions.SerializeFixedPart(this.{cppField.FieldInfo.Name}, buffer, objectOffset + {cppField.CppStructOffset});"); } WriteLine(); }
/// <inheritdoc /> public override void VisitField(CppField cppField) { AlignAttribute alignmentAttribute = cppField.FieldInfo.GetCustomAttribute <AlignAttribute>(); string fieldCodeString = alignmentAttribute == null ? string.Empty : $"alignas({alignmentAttribute.Size}) "; if (cppField.FieldInfo.IsFixedSizedArray()) { // Field is a fixed size array. // string cppElementTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.FieldType.GetElementType()); FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); fieldCodeString += $"std::array<{cppElementTypeFullName}, {arrayAttribute.Length}> {cppField.FieldInfo.Name} = {{ }};"; } else { string cppTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.FieldType); fieldCodeString += $"{cppTypeFullName} {cppField.FieldInfo.Name};"; } WriteLine(fieldCodeString); WriteLine(); }
/// <inheritdoc /> public override void VisitField(CppField cppField) { if (!cppField.CppType.HasVariableData) { // Ignore field with sized size. // return; } // Variable length field. // WriteLine($"// Update variable length field : {cppField.FieldInfo.Name} {cppField.CppType.Name}"); WriteLine("//"); if (cppField.FieldInfo.IsFixedSizedArray()) { // Serialize fixed length array. // FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); WriteBlock($@" if (isValid) {{ isValid = this.{cppField.FieldInfo.Name}.VerifyVariableData({arrayAttribute.Length}, objectOffset + {cppField.CppStructOffset}, totalDataSize, ref expectedDataOffset); }}"); } else { WriteBlock($@" if (isValid) {{ isValid = ((global::Mlos.Core.ICodegenProxy)this.{cppField.FieldInfo.Name}).VerifyVariableData(objectOffset + {cppField.CppStructOffset}, totalDataSize, ref expectedDataOffset); }}"); } }
/// <inheritdoc /> public override void VisitField(CppField cppField) { string fieldName = cppField.FieldInfo.Name; if (cppField.FieldInfo.IsFixedSizedArray()) { // Copy fixed length array. // FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); // Use different routine if copying array of primitive elements or array of ICodegenType. // if (cppField.CppType.IsCodegenType) { WriteLine($"{fieldName}.UpdatePropertyProxyArray(proxy.{fieldName}, {arrayAttribute.Length});"); } else { WriteLine($"{fieldName}.UpdateProxyArray(proxy.{fieldName}, {arrayAttribute.Length});"); } } else if (cppField.CppType.IsCodegenType) { WriteLine($"{fieldName}.Update(proxy.{fieldName});"); } else { WriteLine($"{fieldName} = proxy.{fieldName};"); } }
private void DefineCppType(Type sourceType, bool hasVariableSerializableLength, out List <CppField> cppFields) { cppFields = new List <CppField>(); // Build list of structure properties. // Calculate fields offsets for flatten structure. // uint cppStructOffset = 0; // Calculate the type alignment, this is required when type is used as inner type in other types. // uint alignment = 1; // Export public instance fields. // foreach (FieldInfo fieldInfo in sourceType.GetPublicInstanceFields()) { if (sourceType.IsCodegenConfigType() && !fieldInfo.IsScalarSetting()) { AddUntaggedOrNoneScalarPublicSettingRegistryField(sourceType, fieldInfo); continue; } if (!IsSupportedFieldType(fieldInfo, out CppType cppFieldType)) { AddUnsupportedFieldTypeError(sourceType, fieldInfo); continue; } if (!IsValidAlignmentSizeAttribute(fieldInfo, out uint customFieldAlignment)) { AddInvalidAlignmentSizeError(sourceType, fieldInfo); continue; } // Align the field offset and update type aligment. // uint fieldAlignment = customFieldAlignment == 0 ? cppFieldType.Alignment : customFieldAlignment; if (fieldAlignment != 0) { cppStructOffset = CppTypeMapper.AlignSize(cppStructOffset, fieldAlignment); alignment = Math.Max(alignment, fieldAlignment); } // Calculate type size. // uint typeSize = cppFieldType.TypeSize; // Calculate field size in case when we have an array. // if (fieldInfo.IsFixedSizedArray()) { if (!fieldInfo.IsInitOnly) { AddMissingFieldReadonlyModifierError(sourceType, fieldInfo); } if (!sourceType.IsClass) { AddIncorrectDefinitionError(sourceType, fieldInfo); } FixedSizeArrayAttribute arrayAttribute = fieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>(); // Adjust the structure size. // typeSize += typeSize * (arrayAttribute.Length - 1); } cppFields.Add( new CppField { CppStructOffset = cppStructOffset, FieldInfo = fieldInfo, CppType = cppFieldType, }); cppStructOffset += typeSize; } if (CodeGenErrors.Any()) { // We are unable to generate code, return early. // return; } uint paddingSize = 0; // Align structure size unless it has explicitly defined size. // if (sourceType.StructLayoutAttribute.Size == 0) { cppStructOffset = CppTypeMapper.AlignSize(cppStructOffset, alignment); } else { // Explicitly defined size, calculate padding. // paddingSize = (uint)sourceType.StructLayoutAttribute.Size - cppStructOffset; cppStructOffset += paddingSize; } // Check the final structure alignment. // AlignAttribute alignmentAttribute = sourceType.GetCustomAttribute <AlignAttribute>(); if (alignmentAttribute != null) { alignment = alignmentAttribute.Size; } // Define a new Cpp type. // CppTypeMapper.DefineType( sourceType, cppTypeSize: cppStructOffset, aligment: alignment, paddingSize: paddingSize, hasVariableSerializableLength: hasVariableSerializableLength); }