/// <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();
        }
Exemple #2
0
        /// <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();
        }
Exemple #4
0
        /// <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};");
            }
        }
Exemple #8
0
        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);
        }