Skip to content

Commit 3358086

Browse files
committed
Unduplicate some code
1 parent ff86824 commit 3358086

File tree

5 files changed

+48
-86
lines changed

5 files changed

+48
-86
lines changed

Codecs/Binary.cs

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -377,38 +377,10 @@ public Datamodel Decode(string encoding, int encoding_version, string format, in
377377
var id_bits = Reader.ReadBytes(16);
378378
var id = new Guid(BitConverter.IsLittleEndian ? id_bits : id_bits.Reverse().ToArray());
379379

380-
Element? elem = null;
381-
var matchedType = types.TryGetValue(type, out var classType);
382-
383-
if(matchedType && classType != null && reflectionParams.AttemptReflection)
384-
{
385-
var isElementDerived = Element.IsElementDerived(classType);
386-
if (isElementDerived && classType.Name == type)
387-
{
388-
Type derivedType = classType;
389-
390-
ConstructorInfo? constructor = typeof(Element).GetConstructor(
391-
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
392-
null,
393-
[typeof(Datamodel), typeof(string), typeof(Guid), typeof(string)],
394-
null
395-
);
396-
397-
if (constructor == null)
398-
{
399-
throw new InvalidOperationException("Failed to get constructor while attemption reflection based deserialisation");
400-
}
401-
402-
object uninitializedObject = RuntimeHelpers.GetUninitializedObject(derivedType);
403-
constructor.Invoke(uninitializedObject, [dm, name, id, type]);
404-
405-
elem = (Element?)uninitializedObject;
406-
}
407-
}
408-
409-
if (elem == null)
380+
if (!CodecUtilities.TryConstructCustomElement(types, dm, type, name, id, out _))
410381
{
411-
elem = new Element(dm, name, id, type);
382+
// note: constructing an element, adds it to the datamodel.AllElements
383+
_ = new Element(dm, name, id, type);
412384
}
413385
}
414386

@@ -423,7 +395,7 @@ public Datamodel Decode(string encoding, int encoding_version, string format, in
423395
foreach (var i in Enumerable.Range(0, num_attrs))
424396
{
425397
var name = StringDict.ReadString(Reader);
426-
if (defer_mode == DeferredMode.Automatic && reflectionParams.AttemptReflection == false)
398+
if (defer_mode == DeferredMode.Automatic)
427399
{
428400
CodecUtilities.AddDeferredAttribute(elem, name, Reader.BaseStream.Position);
429401
SkipAttribute(Reader);

Codecs/KeyValues2.cs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -509,35 +509,8 @@ string Decode_NextToken(StreamReader reader)
509509
var id = new Guid(elem_id);
510510
if (elem_class != "$prefix_element$")
511511
{
512-
var matchedType = types.TryGetValue(elem_class, out var classType);
513-
514-
if (matchedType && classType != null && reflectionParams.AttemptReflection)
515-
{
516-
var isElementDerived = Element.IsElementDerived(classType);
517-
if (isElementDerived && classType.Name == elem_class)
518-
{
519-
Type derivedType = classType;
520-
521-
ConstructorInfo? constructor = typeof(Element).GetConstructor(
522-
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
523-
null,
524-
[typeof(Datamodel), typeof(string), typeof(Guid), typeof(string)],
525-
null
526-
);
527-
528-
if (constructor == null)
529-
{
530-
throw new InvalidOperationException("Failed to get constructor while attemption reflection based deserialisation");
531-
}
532-
533-
object uninitializedObject = RuntimeHelpers.GetUninitializedObject(derivedType);
534-
constructor.Invoke(uninitializedObject, [dataModel, elem_name, new Guid(elem_id), elem_class]);
535-
536-
elem = (Element?)uninitializedObject;
537-
}
538-
}
539-
540-
elem ??= new Element(dataModel, elem_name, new Guid(elem_id), elem_class);
512+
CodecUtilities.TryConstructCustomElement(types, dataModel, elem_class, elem_name, id, out elem);
513+
elem ??= new Element(dataModel, elem_name, id, elem_class);
541514
}
542515

543516
continue;

Element.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -388,27 +388,6 @@ public bool Equals(Element? other)
388388
{
389389
return other != null && ID == other.ID;
390390
}
391-
392-
public static bool IsElementDerived(Type type)
393-
{
394-
var elementType = typeof(Element);
395-
396-
while (type.BaseType != elementType)
397-
{
398-
var baseType = type.BaseType;
399-
400-
if (baseType != null)
401-
{
402-
type = baseType;
403-
}
404-
else
405-
{
406-
return type == elementType;
407-
}
408-
}
409-
410-
return type.BaseType == elementType;
411-
}
412391
}
413392

414393
namespace TypeConverters

Format/Attribute.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ public sealed class DMProperty : System.Attribute
88
{
99
/// <param name="name">The name to use for serialization.</param>
1010
/// <param name="optional">Ignore serialization if property is on the default value.</param>
11-
public DMProperty(string name = "", bool optional = false)
11+
public DMProperty(string? name = null, bool optional = false)
1212
{
1313
Name = name;
1414
Optional = optional;
1515
}
1616

17-
public string Name { get; }
17+
public string? Name { get; }
1818
public bool Optional { get; }
1919
}

ICodec.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Numerics;
55
using System.Reflection;
66
using System.Collections.Generic;
7+
using System.Runtime.CompilerServices;
78

89
namespace Datamodel.Codecs
910
{
@@ -198,18 +199,55 @@ public static Dictionary<string, Type> GetReflectionTypes(ReflectionParams refle
198199
{
199200
foreach (var classType in assembly.DefinedTypes)
200201
{
201-
types.TryAdd(classType.Name, classType);
202+
if (classType.IsSubclassOf(typeof(Element)))
203+
{
204+
types.TryAdd(classType.Name, classType);
205+
}
202206
}
203207
}
204208

205209
foreach (var type in reflectionParams.AdditionalTypes)
206210
{
207-
types.TryAdd(type.Name, type);
211+
if (type.IsSubclassOf(typeof(Element)))
212+
{
213+
types.TryAdd(type.Name, type);
214+
}
208215
}
209216
}
210217

211218
return types;
212219
}
220+
221+
public static bool TryConstructCustomElement(Dictionary<string, Type> types, Datamodel dataModel, string elem_class, string elem_name, Guid elem_id, out Element? elem)
222+
{
223+
var matchedType = types.TryGetValue(elem_class, out var classType);
224+
225+
if (!matchedType || classType is null)
226+
{
227+
elem = null;
228+
return false;
229+
}
230+
231+
Type derivedType = classType;
232+
233+
ConstructorInfo? constructor = typeof(Element).GetConstructor(
234+
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
235+
null,
236+
[typeof(Datamodel), typeof(string), typeof(Guid), typeof(string)],
237+
null
238+
);
239+
240+
if (constructor == null)
241+
{
242+
throw new InvalidOperationException("Failed to get constructor while attemption reflection based deserialisation");
243+
}
244+
245+
object uninitializedObject = RuntimeHelpers.GetUninitializedObject(derivedType);
246+
constructor.Invoke(uninitializedObject, [dataModel, elem_name, elem_id, elem_class]);
247+
248+
elem = (Element?)uninitializedObject;
249+
return true;
250+
}
213251
}
214252

215253
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]

0 commit comments

Comments
 (0)