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.
This commit is contained in:
Loretta 2026-02-15 10:57:09 +01:00
parent 58cf9578c7
commit 1af939ac4d
3 changed files with 16 additions and 45 deletions

View File

@ -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;
}
}

View File

@ -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<TestOrderItem> (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<SharedTag> (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<TOutput>(int value, AcBinarySerializer.BinarySerializationContext<TOutput> 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)]

View File

@ -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
}