From 2a6a7e156a1f5dfb72fea6a59e84ad2fac4e3720 Mon Sep 17 00:00:00 2001 From: Marcus Cazzola Date: Wed, 13 Sep 2023 19:39:20 +0200 Subject: [PATCH 1/5] Added IEnumerable iterator --- SimpleECS/QueryForeachFunctions.cs | 289 +++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) diff --git a/SimpleECS/QueryForeachFunctions.cs b/SimpleECS/QueryForeachFunctions.cs index 7aacb7f..72fb202 100644 --- a/SimpleECS/QueryForeachFunctions.cs +++ b/SimpleECS/QueryForeachFunctions.cs @@ -3278,5 +3278,294 @@ public void Foreach + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e]); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e]); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e]); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e]); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e]); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], c6[e]); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable>> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6) && archetype.TryGetArray(out C7[] c7)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], Tuple.Create(c6[e], c7[e])); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable>> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6) && archetype.TryGetArray(out C7[] c7) && archetype.TryGetArray(out C8[] c8)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], Tuple.Create(c6[e], c7[e], c8[e])); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable>> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; archetype_index++) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6) && archetype.TryGetArray(out C7[] c7) && archetype.TryGetArray(out C8[] c8) && archetype.TryGetArray(out C9[] c9)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], Tuple.Create(c6[e], c7[e], c8[e], c9[e])); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable>> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; archetype_index++) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6) && archetype.TryGetArray(out C7[] c7) && archetype.TryGetArray(out C8[] c8) && archetype.TryGetArray(out C9[] c9) && archetype.TryGetArray(out C10[] c10)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], Tuple.Create(c6[e], c7[e], c8[e], c9[e], c10[e])); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable>> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; archetype_index++) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6) && archetype.TryGetArray(out C7[] c7) && archetype.TryGetArray(out C8[] c8) && archetype.TryGetArray(out C9[] c9) && archetype.TryGetArray(out C10[] c10) && archetype.TryGetArray(out C11[] c11)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], Tuple.Create(c6[e], c7[e], c8[e], c9[e], c10[e], c11[e])); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } + /// + /// iterates over the entities that match the query and returns a tuple of the entity and the components + /// possible to use continue and break + /// NOTE: it is only possible to modity a refernce type in the tuple, like a class. You can not modify a value type, like int, float, bool, etc. + /// + public IEnumerable>> Foreach() + { + if (Update(out var world_info)) + { + world_info.StructureEvents.EnqueueEvents++; + for (int archetype_index = 0; archetype_index < archetype_count; archetype_index++) + { + var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; + int count = archetype.entity_count; + var entities = archetype.entities; + if (count > 0 && archetype.TryGetArray(out C1[] c1) && archetype.TryGetArray(out C2[] c2) && archetype.TryGetArray(out C3[] c3) && archetype.TryGetArray(out C4[] c4) && archetype.TryGetArray(out C5[] c5) && archetype.TryGetArray(out C6[] c6) && archetype.TryGetArray(out C7[] c7) && archetype.TryGetArray(out C8[] c8) && archetype.TryGetArray(out C9[] c9) && archetype.TryGetArray(out C10[] c10) && archetype.TryGetArray(out C11[] c11) && archetype.TryGetArray(out C12[] c12)) + { + for (int e = 0; e < count; ++e) + yield return Tuple.Create(entities[e], c1[e], c2[e], c3[e], c4[e], c5[e], Tuple.Create(c6[e], c7[e], c8[e], c9[e], c10[e], c11[e], c12[e])); + } + } + world_info.StructureEvents.EnqueueEvents--; + } + } } } \ No newline at end of file From 109be46496ae266b3ee7a66ce2a3b361428d3f7f Mon Sep 17 00:00:00 2001 From: Marcus Cazzola Date: Wed, 13 Sep 2023 20:06:27 +0200 Subject: [PATCH 2/5] updated README to have foreach iterator --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index ab5da9f..67381fe 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,28 @@ query.Foreach( (Entity entity, ref int value ) => // you can access the Console.WriteLine($"{entity} value is {value}"); }); +foreach ((Entity entity, int value) in query.Foreach()) // foreach makes so you can use continue and break +{ + if (aa.x > 0) + { + continue; + } + + if (bb.x > 0) + { + break; + } + + Console.WriteLine($"value x is {aa.x} value y is {aa.y}"); +} + +// having more then 5 components makes so you have to put double parenthesis. +// the reason is that a tuple only can hold in 8 values, so you create a second tuple in the tuple +foreach ((var entity, A aa, B bb, C cc, D dd, E ee, (F ff, G gg, H hh, I ii, J jj)) in query.Foreach()) +{ + Console.WriteLine($"value x is {aa.x} value y is {aa.y}"); +} + var all_entities = world.CreateQuery(); // a simple way to match against all entities is to make a query with no filters query.GetEntities(); // returns a copy of all entities currently matching the query From a02e4da29dbaadcc75b85a80f4df05bfb26af240 Mon Sep 17 00:00:00 2001 From: Marcus Cazzola Date: Wed, 13 Sep 2023 20:22:47 +0200 Subject: [PATCH 3/5] changed var to Entity --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 67381fe..c96563b 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ foreach ((Entity entity, int value) in query.Foreach()) // foreach makes so // having more then 5 components makes so you have to put double parenthesis. // the reason is that a tuple only can hold in 8 values, so you create a second tuple in the tuple -foreach ((var entity, A aa, B bb, C cc, D dd, E ee, (F ff, G gg, H hh, I ii, J jj)) in query.Foreach()) +foreach ((Entity entity, A aa, B bb, C cc, D dd, E ee, (F ff, G gg, H hh, I ii, J jj)) in query.Foreach()) { Console.WriteLine($"value x is {aa.x} value y is {aa.y}"); } From d0f6a499138ef2ce8afd64cf3af64efec9280d2e Mon Sep 17 00:00:00 2001 From: Marcus Cazzola Date: Wed, 13 Sep 2023 21:00:43 +0200 Subject: [PATCH 4/5] moved ++ to the other side --- SimpleECS/QueryForeachFunctions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SimpleECS/QueryForeachFunctions.cs b/SimpleECS/QueryForeachFunctions.cs index 72fb202..f090c75 100644 --- a/SimpleECS/QueryForeachFunctions.cs +++ b/SimpleECS/QueryForeachFunctions.cs @@ -3481,7 +3481,7 @@ public IEnumerable>> For if (Update(out var world_info)) { world_info.StructureEvents.EnqueueEvents++; - for (int archetype_index = 0; archetype_index < archetype_count; archetype_index++) + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) { var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; int count = archetype.entity_count; @@ -3505,7 +3505,7 @@ public IEnumerable> if (Update(out var world_info)) { world_info.StructureEvents.EnqueueEvents++; - for (int archetype_index = 0; archetype_index < archetype_count; archetype_index++) + for (int archetype_index = 0; archetype_index < archetype_count; ++archetype_index) { var archetype = world_info.archetypes[matching_archetypes[archetype_index]].data; int count = archetype.entity_count; @@ -3529,7 +3529,7 @@ public IEnumerable Date: Wed, 13 Sep 2023 21:07:21 +0200 Subject: [PATCH 5/5] updated README to be correct --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c96563b..86a2161 100644 --- a/README.md +++ b/README.md @@ -158,17 +158,17 @@ query.Foreach( (Entity entity, ref int value ) => // you can access the foreach ((Entity entity, int value) in query.Foreach()) // foreach makes so you can use continue and break { - if (aa.x > 0) + if (value > 0) { continue; } - if (bb.x > 0) + if (value < 0) { break; } - Console.WriteLine($"value x is {aa.x} value y is {aa.y}"); + Console.WriteLine($"{entity} value is {value}"); } // having more then 5 components makes so you have to put double parenthesis.