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.

98 lines
4.8KB

  1. using System;
  2. using System.Collections.Generic;
  3. using Svelto.DataStructures.Experimental;
  4. using Svelto.ECS.Internal;
  5. using Svelto.ECS.Schedulers;
  6. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  7. using Svelto.ECS.Profiler;
  8. #endif
  9. namespace Svelto.ECS
  10. {
  11. public partial class EnginesRoot : IDisposable
  12. {
  13. void SubmitEntityViews()
  14. {
  15. int numberOfReenteringLoops = 0;
  16. //are there new entities built to process?
  17. while ( _newEntitiesBuiltToProcess > 0)
  18. {
  19. //use other as source from now on
  20. //current will be use to write new entityViews
  21. _groupedEntityToAdd.Swap();
  22. //Note: if N entity of the same type are added on the same frame
  23. //the Add callback is called N times on the same frame.
  24. //if the Add calback builds a new entity, that entity will not
  25. //be available in the database until the N callbacks are done
  26. //solving it could be complicated as callback and database update
  27. //must be interleaved.
  28. if (_groupedEntityToAdd.other.Count > 0)
  29. AddEntityViewsToTheDBAndSuitableEngines(_groupedEntityToAdd.other);
  30. //other can be cleared now, but let's avoid deleting the dictionary every time
  31. _groupedEntityToAdd.ClearOther();
  32. if (numberOfReenteringLoops > 5)
  33. throw new Exception("possible infinite loop found creating Entities inside IEntityViewsEngine Add method, please consider building entities outside IEntityViewsEngine Add method");
  34. _newEntitiesBuiltToProcess = 0;
  35. numberOfReenteringLoops++;
  36. }
  37. }
  38. //todo: groupsToSubmit can be simplified as data structure?
  39. void AddEntityViewsToTheDBAndSuitableEngines(Dictionary<int, Dictionary<Type, ITypeSafeDictionary>> groupsOfEntitiesToSubmit)
  40. {
  41. //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
  42. foreach (var groupOfEntitiesToSubmit in groupsOfEntitiesToSubmit)
  43. {
  44. Dictionary<Type, ITypeSafeDictionary> groupDB;
  45. int groupID = groupOfEntitiesToSubmit.Key;
  46. //if the group doesn't exist in the current DB let's create it first
  47. if (_groupEntityDB.TryGetValue(groupID, out groupDB) == false)
  48. groupDB = _groupEntityDB[groupID] = new Dictionary<Type, ITypeSafeDictionary>();
  49. //add the entityViews in the group
  50. foreach (var entityViewTypeSafeDictionary in groupOfEntitiesToSubmit.Value)
  51. {
  52. ITypeSafeDictionary dbDic;
  53. FasterDictionary<int, ITypeSafeDictionary> groupedGroup = null;
  54. if (groupDB.TryGetValue(entityViewTypeSafeDictionary.Key, out dbDic) == false)
  55. dbDic = groupDB[entityViewTypeSafeDictionary.Key] = entityViewTypeSafeDictionary.Value.Create();
  56. if (_groupedGroups.TryGetValue(entityViewTypeSafeDictionary.Key, out groupedGroup) == false)
  57. groupedGroup = _groupedGroups[entityViewTypeSafeDictionary.Key] = new FasterDictionary<int, ITypeSafeDictionary>();
  58. //Fill the DB with the entity views generate this frame.
  59. dbDic.FillWithIndexedEntities(entityViewTypeSafeDictionary.Value);
  60. groupedGroup[groupID] = dbDic;
  61. }
  62. }
  63. //then submit everything in the engines, so that the DB is up to date
  64. //with all the entity views and struct created by the entity built
  65. foreach (var groupToSubmit in groupsOfEntitiesToSubmit)
  66. {
  67. foreach (var entityViewsPerType in groupToSubmit.Value)
  68. {
  69. entityViewsPerType.Value.AddEntitiesToEngines(_entityEngines);
  70. }
  71. }
  72. }
  73. //one datastructure rule them all:
  74. //split by group
  75. //split by type per group. It's possible to get all the entities of a give type T per group thanks
  76. //to the FasterDictionary capabilities OR it's possible to get a specific entityView indexed by
  77. //ID. This ID doesn't need to be the EGID, it can be just the entityID
  78. readonly Dictionary<int, Dictionary<Type, ITypeSafeDictionary>> _groupEntityDB;
  79. readonly Dictionary<Type, FasterDictionary<int, ITypeSafeDictionary>> _groupedGroups; //yes I am being sarcastic
  80. readonly DoubleBufferedEntitiesToAdd<Dictionary<int, Dictionary<Type, ITypeSafeDictionary>>> _groupedEntityToAdd;
  81. readonly EntitySubmissionScheduler _scheduler;
  82. }
  83. }