Skip to content

Commit 92bc8bb

Browse files
authored
Handle duplication of serializer TypeName (#47)
1 parent ac4379c commit 92bc8bb

5 files changed

Lines changed: 47 additions & 20 deletions

Runtime/BinaryStorage.Builder.cs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public static BinaryStorage Get(string filePath)
2828
public static Builder Construct(string filePath)
2929
{
3030
ThrowIfFilePathLocked(filePath);
31-
LockFilePathInEditor(filePath);
3231
return new Builder(filePath);
3332
}
3433

@@ -114,12 +113,21 @@ public Builder AddPrimitiveTypes()
114113
/// <param name="typeSerializer">The serializer for the specified type.</param>
115114
/// <returns>The current <see cref="Builder"/> instance for method chaining.</returns>
116115
/// <exception cref="DuplicateTypeSerializerException">Thrown if a serializer for the specified type already exists.</exception>
116+
/// <exception cref="DuplicateTypeSerializerNameException">Thrown if a serializer with the same type name already exists.</exception>
117117
public Builder AddTypeSerializer<T>(TypeSerializer<T> typeSerializer)
118118
{
119-
if (_serializers.Any(c => c is TypedBinarySection<T>))
119+
var otherSerializer = _serializers.FirstOrDefault(c => c is TypedBinarySection<T>)?.Serializer;
120+
if (otherSerializer != null)
120121
{
121-
throw new DuplicateTypeSerializerException(typeof(T), typeSerializer.TypeName, _filePath);
122+
throw new DuplicateTypeSerializerException(typeSerializer, otherSerializer, _filePath);
122123
}
124+
125+
otherSerializer = _serializers.FirstOrDefault(c => c.Serializer.TypeName == typeSerializer.TypeName)?.Serializer;
126+
if (otherSerializer != null)
127+
{
128+
throw new DuplicateTypeSerializerNameException(typeSerializer, otherSerializer, _filePath);
129+
}
130+
123131
_serializers.Add(new TypedBinarySection<T>(typeSerializer));
124132
return this;
125133
}
@@ -217,20 +225,13 @@ public Builder SupportDictionariesOf<TKey, TValue>()
217225
/// <exception cref="IOException"> An I/O error occurred </exception>
218226
public BinaryStorage Build(KeyLoadFailedBehaviour keyLoadFailedBehaviour = KeyLoadFailedBehaviour.IgnoreWithWarning)
219227
{
220-
try
221-
{
222-
var storage = new BinaryStorage(_filePath, _serializers);
223-
storage.AutoSave = _autoSave;
224-
storage.MissingKeyBehavior = _missingKeyBehavior;
225-
storage.TypeMismatchBehaviour = _typeMismatchBehaviour;
226-
storage.LoadDataFromDisk(keyLoadFailedBehaviour);
227-
return storage;
228-
}
229-
catch
230-
{
231-
UnlockFilePathInEditor(_filePath);
232-
throw;
233-
}
228+
var storage = new BinaryStorage(_filePath, _serializers);
229+
storage.AutoSave = _autoSave;
230+
storage.MissingKeyBehavior = _missingKeyBehavior;
231+
storage.TypeMismatchBehaviour = _typeMismatchBehaviour;
232+
storage.LoadDataFromDisk(keyLoadFailedBehaviour);
233+
LockFilePathInEditor(_filePath);
234+
return storage;
234235
}
235236
}
236237
}

Runtime/Exceptions/DuplicateTypeSerializerException.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33

44
namespace Appegy.Storage
55
{
6+
/// <summary>
7+
/// Thrown when a second serializer for the same value type is being registered.
8+
/// </summary>
69
public class DuplicateTypeSerializerException : Exception
710
{
8-
public DuplicateTypeSerializerException(Type type, string typeNameCode, string storagePath)
9-
: base($"You're trying to add second serializer for type {type.Name} ({typeNameCode}) to storage {Path.GetFileName(storagePath)}. This is not allowed")
11+
public DuplicateTypeSerializerException(TypeSerializer newSerializer, TypeSerializer existingSerializer, string storagePath)
12+
: base($"Duplicate serializer detected in '{Path.GetFileName(storagePath)}'. " +
13+
$"Attempted: {newSerializer.GetType().Name} (TypeName: '{newSerializer.TypeName}'); " +
14+
$"Already registered: {existingSerializer.GetType().Name} (TypeName: '{existingSerializer.TypeName}').")
1015
{
1116
}
1217
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.IO;
3+
4+
namespace Appegy.Storage
5+
{
6+
/// <summary>
7+
/// Thrown when a serializer with a TypeName that is already in use is being registered.
8+
/// </summary>
9+
public class DuplicateTypeSerializerNameException : Exception
10+
{
11+
public DuplicateTypeSerializerNameException(TypeSerializer newSerializer, TypeSerializer existingSerializer, string storagePath)
12+
: base($"TypeName collision detected in '{Path.GetFileName(storagePath)}'. " +
13+
$"Attempted: {newSerializer.GetType().Name} (TypeName: '{newSerializer.TypeName}'); " +
14+
$"Conflicting: {existingSerializer.GetType().Name} (TypeName: '{existingSerializer.TypeName}').")
15+
{
16+
}
17+
}
18+
}

Runtime/Exceptions/DuplicateTypeSerializerNameException.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Serialization/UnityTypesSerializers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Appegy.Storage
66
internal class QuaternionSerializer : EquatableTypeSerializer<Quaternion>
77
{
88
public static QuaternionSerializer Shared { get; } = new();
9-
public override string TypeName => "vector2f";
9+
public override string TypeName => "quaternion";
1010

1111
public override void WriteTo(BinaryWriter writer, Quaternion value)
1212
{

0 commit comments

Comments
 (0)