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.FindGroups.cs 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System;
  2. using System.Threading;
  3. using Svelto.DataStructures;
  4. using Svelto.ECS.Internal;
  5. namespace Svelto.ECS
  6. {
  7. public partial class EntitiesDB
  8. {
  9. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1>() where T1 : IEntityComponent
  10. {
  11. FasterList<ExclusiveGroupStruct> result = groups.Value;
  12. result.FastClear();
  13. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper
  14. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result1) == false)
  15. return result;
  16. var result1Count = result1.count;
  17. var fasterDictionaryNodes1 = result1.unsafeKeys;
  18. for (int j = 0; j < result1Count; j++)
  19. {
  20. result.Add(new ExclusiveGroupStruct(fasterDictionaryNodes1[j].key));
  21. }
  22. return result;
  23. }
  24. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2>() where T1 : IEntityComponent where T2 : IEntityComponent
  25. {
  26. FasterList<ExclusiveGroupStruct> result = groups.Value;
  27. result.FastClear();
  28. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper
  29. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result1) == false)
  30. return result;
  31. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T2>.wrapper
  32. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result2) == false)
  33. return result;
  34. var result1Count = result1.count;
  35. var result2Count = result2.count;
  36. var fasterDictionaryNodes1 = result1.unsafeKeys;
  37. var fasterDictionaryNodes2 = result2.unsafeKeys;
  38. for (int i = 0; i < result1Count; i++)
  39. {
  40. var groupID = fasterDictionaryNodes1[i].key;
  41. for (int j = 0; j < result2Count; j++)
  42. {
  43. //if the same group is found used with both T1 and T2
  44. if (groupID == fasterDictionaryNodes2[j].key)
  45. {
  46. result.Add(new ExclusiveGroupStruct(groupID));
  47. break;
  48. }
  49. }
  50. }
  51. return result;
  52. }
  53. /// <summary>
  54. /// Remember that this operation os O(N*M*P) where N,M,P are the number of groups where each component
  55. /// is found.
  56. /// </summary>
  57. /// <typeparam name="T1"></typeparam>
  58. /// <typeparam name="T2"></typeparam>
  59. /// <typeparam name="T3"></typeparam>
  60. /// <returns></returns>
  61. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2, T3>()
  62. where T1 : IEntityComponent where T2 : IEntityComponent where T3 : IEntityComponent
  63. {
  64. FasterList<ExclusiveGroupStruct> result = groups.Value;
  65. result.FastClear();
  66. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper
  67. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> groupOfEntities1) == false)
  68. return result;
  69. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T2>.wrapper
  70. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> groupOfEntities2) == false)
  71. return result;
  72. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T3>.wrapper
  73. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> groupOfEntities3) == false)
  74. return result;
  75. var result1Count = groupOfEntities1.count;
  76. var result2Count = groupOfEntities2.count;
  77. var result3Count = groupOfEntities3.count;
  78. var fasterDictionaryNodes1 = groupOfEntities1.unsafeKeys;
  79. var fasterDictionaryNodes2 = groupOfEntities2.unsafeKeys;
  80. var fasterDictionaryNodes3 = groupOfEntities3.unsafeKeys;
  81. //
  82. //TODO: I have to find once for ever a solution to be sure that the entities in the groups match
  83. //Currently this returns group where the entities are found, but the entities may not match in these
  84. //groups.
  85. //Checking the size of the entities is an early check, needed, but not sufficient, as entities components may
  86. //coincidentally match in number but not from which entities they are generated
  87. //foreach group where T1 is found
  88. for (int i = 0; i < result1Count; i++)
  89. {
  90. var groupT1 = fasterDictionaryNodes1[i].key;
  91. //foreach group where T2 is found
  92. for (int j = 0; j < result2Count; ++j)
  93. {
  94. if (groupT1 == fasterDictionaryNodes2[j].key)
  95. {
  96. //foreach group where T3 is found
  97. for (int k = 0; k < result3Count; ++k)
  98. {
  99. if (groupT1 == fasterDictionaryNodes3[k].key)
  100. {
  101. result.Add(new ExclusiveGroupStruct(groupT1));
  102. break;
  103. }
  104. }
  105. break;
  106. }
  107. }
  108. }
  109. return result;
  110. }
  111. internal FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> FindGroups_INTERNAL(Type type)
  112. {
  113. if (groupsPerEntity.ContainsKey(new RefWrapperType(type)) == false)
  114. return _emptyDictionary;
  115. return groupsPerEntity[new RefWrapperType(type)];
  116. }
  117. struct GroupsList
  118. {
  119. static GroupsList()
  120. {
  121. groups = new FasterList<ExclusiveGroupStruct>();
  122. }
  123. static readonly FasterList<ExclusiveGroupStruct> groups;
  124. public static implicit operator FasterList<ExclusiveGroupStruct>(in GroupsList list)
  125. {
  126. return list.reference;
  127. }
  128. FasterList<ExclusiveGroupStruct> reference => groups;
  129. }
  130. static readonly ThreadLocal<GroupsList> groups = new ThreadLocal<GroupsList>();
  131. }
  132. }