Mirror of Svelto.ECS because we're a fan of it
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

124 linhas
5.2KB

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