Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EntitiesDB.SerializationDescriptorMap.cs 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using Svelto.Common;
  6. using Svelto.ECS.Serialization;
  7. namespace Svelto.ECS
  8. {
  9. partial class EnginesRoot
  10. {
  11. sealed class SerializationDescriptorMap
  12. {
  13. /// <summary>
  14. /// Here we want to register all the EntityDescriptors that need to be serialized for network play.
  15. ///
  16. /// Remember! This needs to in sync across different clients and server as the values are serialized across
  17. /// the network also want this to not change so we can save to a DB
  18. /// </summary>
  19. internal SerializationDescriptorMap()
  20. {
  21. _descriptors = new Dictionary<uint, ISerializableEntityDescriptor>();
  22. _factories = new Dictionary<uint, IDeserializationFactory>();
  23. using (new StandardProfiler("Assemblies Scan"))
  24. {
  25. Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
  26. Type d1 = typeof(DefaultVersioningFactory<>);
  27. foreach (Assembly assembly in assemblies)
  28. {
  29. foreach (Type type in GetTypesSafe(assembly))
  30. {
  31. if (type != null && type.IsClass && type.IsAbstract == false && type.BaseType != null
  32. && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition()
  33. == typeof(SerializableEntityDescriptor<>))
  34. {
  35. var descriptor = Activator.CreateInstance(type) as ISerializableEntityDescriptor;
  36. RegisterEntityDescriptor(descriptor, type, d1);
  37. }
  38. }
  39. }
  40. }
  41. }
  42. static IEnumerable<Type> GetTypesSafe(Assembly assembly)
  43. {
  44. try
  45. {
  46. Type[] types = assembly.GetTypes();
  47. return types;
  48. }
  49. catch (ReflectionTypeLoadException e)
  50. {
  51. return e.Types;
  52. }
  53. }
  54. void RegisterEntityDescriptor(ISerializableEntityDescriptor descriptor, Type type, Type d1)
  55. {
  56. if (descriptor == null)
  57. return;
  58. uint descriptorHash = descriptor.hash;
  59. #if DEBUG && !PROFILE_SVELTO
  60. if (_descriptors.ContainsKey(descriptorHash))
  61. {
  62. throw new Exception($"Hash Collision of '{descriptor.GetType()}' against " +
  63. $"'{_descriptors[descriptorHash]} ::: {descriptorHash}'");
  64. }
  65. #endif
  66. _descriptors[descriptorHash] = descriptor;
  67. Type[] typeArgs = {type};
  68. var makeGenericType = d1.MakeGenericType(typeArgs);
  69. var instance = Activator.CreateInstance(makeGenericType);
  70. _factories.Add(descriptorHash, instance as IDeserializationFactory);
  71. }
  72. public ISerializableEntityDescriptor GetDescriptorFromHash(uint descriptorHash)
  73. {
  74. #if DEBUG && !PROFILE_SVELTO
  75. DBC.ECS.Check.Require(_descriptors.ContainsKey(descriptorHash),
  76. $"Could not find descriptor linked to hash, wrong deserialization size? '{ descriptorHash}'!");
  77. #endif
  78. return _descriptors[descriptorHash];
  79. }
  80. public IDeserializationFactory GetSerializationFactory(uint descriptorHash)
  81. {
  82. #if DEBUG && !PROFILE_SVELTO
  83. DBC.ECS.Check.Require(_descriptors.ContainsKey(descriptorHash),
  84. $"Could not find descriptor linked to descriptor hash, wrong deserialization size? '{ descriptorHash}'!");
  85. DBC.ECS.Check.Require(_factories.ContainsKey(descriptorHash),
  86. $"Could not find factory linked to hash '{ _descriptors[descriptorHash]}'!");
  87. #endif
  88. return _factories[descriptorHash];
  89. }
  90. public void RegisterSerializationFactory<Descriptor>(IDeserializationFactory deserializationFactory)
  91. where Descriptor : ISerializableEntityDescriptor, new()
  92. {
  93. _factories[SerializationEntityDescriptorTemplate<Descriptor>.hash] = deserializationFactory;
  94. }
  95. readonly Dictionary<uint, ISerializableEntityDescriptor> _descriptors;
  96. readonly Dictionary<uint, IDeserializationFactory> _factories;
  97. }
  98. /// <summary>
  99. /// The map of serializable entity hashes to the serializable entity builders (to know the entity structs
  100. /// to serialize)
  101. /// </summary>
  102. SerializationDescriptorMap serializationDescriptorMap { get; }
  103. }
  104. }