From 1af939ac4d90319d5332a2afe1298bcefce230ea Mon Sep 17 00:00:00 2001 From: Loretta Date: Sun, 15 Feb 2026 10:57:09 +0100 Subject: [PATCH] Support markerless serialization for bool and enum types Extend markerless serialization to Boolean and Enum types in AcBinarySourceGenerator and generated writers. Updated IsMarkerlessType and EmitMarkerlessWrite to handle these types directly. Refactored generated code to write DateTime, int, enum, and decimal properties without type markers or property skip checks. Simplified OnStringInterned debug callback in AcBinarySerializer. These changes reduce serialization overhead and improve performance for supported types. --- .../AcBinarySourceGenerator.cs | 5 +- .../GeneratedWriters/TestOrderWriter.cs | 50 +++---------------- .../Binaries/AcBinarySerializer.cs | 6 ++- 3 files changed, 16 insertions(+), 45 deletions(-) diff --git a/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs b/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs index 699838e..719df13 100644 --- a/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs +++ b/AyCode.Core.Serializers.SourceGenerator/AcBinarySourceGenerator.cs @@ -183,7 +183,8 @@ public class AcBinarySourceGenerator : IIncrementalGenerator PropertyTypeKind.Byte or PropertyTypeKind.UInt16 or PropertyTypeKind.UInt32 or PropertyTypeKind.UInt64 or PropertyTypeKind.Double or PropertyTypeKind.Single or PropertyTypeKind.Decimal or PropertyTypeKind.DateTime or PropertyTypeKind.Guid or - PropertyTypeKind.TimeSpan or PropertyTypeKind.DateTimeOffset => true, + PropertyTypeKind.TimeSpan or PropertyTypeKind.DateTimeOffset or + PropertyTypeKind.Boolean or PropertyTypeKind.Enum => true, _ => false }; @@ -209,6 +210,8 @@ public class AcBinarySourceGenerator : IIncrementalGenerator case PropertyTypeKind.UInt64: sb.AppendLine($"{i}context.WriteVarULong({a});"); break; case PropertyTypeKind.TimeSpan: sb.AppendLine($"{i}context.WriteRaw({a}.Ticks);"); break; case PropertyTypeKind.DateTimeOffset: sb.AppendLine($"{i}context.WriteDateTimeOffsetBits({a});"); break; + case PropertyTypeKind.Boolean: sb.AppendLine($"{i}context.WriteByte({a} ? (byte)1 : (byte)0);"); break; + case PropertyTypeKind.Enum: sb.AppendLine($"{i}context.WriteVarInt((int){a});"); break; } } diff --git a/AyCode.Core.Tests/GeneratedWriters/TestOrderWriter.cs b/AyCode.Core.Tests/GeneratedWriters/TestOrderWriter.cs index 779dee3..a96a150 100644 --- a/AyCode.Core.Tests/GeneratedWriters/TestOrderWriter.cs +++ b/AyCode.Core.Tests/GeneratedWriters/TestOrderWriter.cs @@ -38,12 +38,11 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter // Category: SharedCategory? (complex, nullable) WriteComplexOrNull(obj.Category, context, nextDepth); - // CreatedAt: DateTime - context.WriteByte(BinaryTypeCode.DateTime); + // CreatedAt: DateTime (markerless) context.WriteDateTimeBits(obj.CreatedAt); - // Id: int - WriteInt32OrSkip(obj.Id, context); + // Id: int (markerless) + context.WriteVarInt(obj.Id); // Items: List (collection) WriteComplexOrNull(obj.Items, context, nextDepth); @@ -81,49 +80,14 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter // SecondaryTag: SharedTag? (complex, nullable) WriteComplexOrNull(obj.SecondaryTag, context, nextDepth); - // Status: TestStatus (enum) - context.WriteByte(BinaryTypeCode.Enum); - var enumVal = (int)obj.Status; - if (BinaryTypeCode.TryEncodeTinyInt(enumVal, out var tinyEnum)) - context.WriteByte(tinyEnum); - else - { - context.WriteByte(BinaryTypeCode.Int32); - context.WriteVarInt(enumVal); - } + // Status: TestStatus (enum, markerless) + context.WriteVarInt((int)obj.Status); // Tags: List (collection) WriteComplexOrNull(obj.Tags, context, nextDepth); - // TotalAmount: decimal - if (obj.TotalAmount == 0m) - context.WriteByte(BinaryTypeCode.PropertySkip); - else - { - context.WriteByte(BinaryTypeCode.Decimal); - context.WriteDecimalBits(obj.TotalAmount); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteInt32OrSkip(int value, AcBinarySerializer.BinarySerializationContext context) - where TOutput : struct, IBinaryOutputBase - { - if (value == 0) - { - context.WriteByte(BinaryTypeCode.PropertySkip); - return; - } - - if (BinaryTypeCode.TryEncodeTinyInt(value, out var tiny)) - { - context.WriteByte(BinaryTypeCode.Int32); - context.WriteByte(tiny); - return; - } - - context.WriteByte(BinaryTypeCode.Int32); - context.WriteVarInt(value); + // TotalAmount: decimal (markerless) + context.WriteDecimalBits(obj.TotalAmount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs index c5f63ec..fa94686 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs @@ -935,8 +935,12 @@ public static partial class AcBinarySerializer } // CacheIndex < 0 or not found → single occurrence, fall through to FixStr/String path #if DEBUG + //context.OnStringInterned?.Invoke( + // context.CurrentProperty != null ? $"{context.CurrentProperty.DeclaringType.Name}.{context.CurrentProperty.Name}" : null, + // value); + context.OnStringInterned?.Invoke( - context.CurrentProperty != null ? $"{context.CurrentProperty.DeclaringType.Name}.{context.CurrentProperty.Name}" : null, + null, value); #endif }