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.

92 lines
4.1KB

  1. using System;
  2. using System.Collections.Generic;
  3. using Svelto.ECS.Internal;
  4. using Svelto.ECS.Schedulers;
  5. #if ENGINE_PROFILER_ENABLED && UNITY_EDITOR
  6. using Svelto.ECS.Profiler;
  7. #endif
  8. namespace Svelto.ECS
  9. {
  10. public partial class EnginesRoot : IDisposable
  11. {
  12. void SubmitEntityViews()
  13. {
  14. bool newEntityViewsHaveBeenAddedWhileIterating = _groupedEntityToAdd.current.Count > 0;
  15. int numberOfReenteringLoops = 0;
  16. while (newEntityViewsHaveBeenAddedWhileIterating)
  17. {
  18. //use other as source from now on
  19. //current will be use to write new entityViews
  20. _groupedEntityToAdd.Swap();
  21. //Note: if N entity of the same type are added on the same frame
  22. //the Add callback is called N times on the same frame.
  23. //if the Add calback builds a new entity, that entity will not
  24. //be available in the database until the N callbacks are done
  25. //solving it could be complicated as callback and database update
  26. //must be interleaved.
  27. if (_groupedEntityToAdd.other.Count > 0)
  28. AddEntityViewsToTheDBAndSuitableEngines(_groupedEntityToAdd.other);
  29. //other can be cleared now
  30. _groupedEntityToAdd.other.Clear();
  31. //has current new entityViews?
  32. newEntityViewsHaveBeenAddedWhileIterating = _groupedEntityToAdd.current.Count > 0;
  33. if (numberOfReenteringLoops > 5)
  34. throw new Exception("possible infinite loop found creating Entities inside IEntityViewsEngine Add method, please consider building entities outside IEntityViewsEngine Add method");
  35. numberOfReenteringLoops++;
  36. }
  37. }
  38. //todo: groupsToSubmit can be semplified 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. if (groupDB.TryGetValue(entityViewTypeSafeDictionary.Key, out dbDic) == false)
  54. dbDic = groupDB[entityViewTypeSafeDictionary.Key] = entityViewTypeSafeDictionary.Value.Create();
  55. //type safe copy
  56. dbDic.FillWithIndexedEntityViews(entityViewTypeSafeDictionary.Value);
  57. }
  58. }
  59. //then submit everything in the engines, so that the DB is up to date
  60. //with all the entity views and struct created by the entity built
  61. foreach (var groupToSubmit in groupsOfEntitiesToSubmit)
  62. {
  63. foreach (var entityViewsPerType in groupToSubmit.Value)
  64. {
  65. entityViewsPerType.Value.AddEntityViewsToEngines(_entityEngines);
  66. }
  67. }
  68. }
  69. //one datastructure rule them all:
  70. //split by group
  71. //split by type per group. It's possible to get all the entities of a give type T per group thanks
  72. //to the FasterDictionary capabilitiies OR it's possible to get a specific entityView indexed by
  73. //ID. This ID doesn't need to be the EGID, it can be just the entityID
  74. readonly DoubleBufferedEntityViews<Dictionary<int, Dictionary<Type, ITypeSafeDictionary>>> _groupedEntityToAdd;
  75. readonly EntitySubmissionScheduler _scheduler;
  76. }
  77. }