using Svelto.DataStructures; namespace Svelto.ECS { /// /// NOTE THESE ENUMERABLES EXIST TO AVOID BOILERPLATE CODE AS THEY SKIP 0 SIZED GROUPS /// However if the normal pattern with the double foreach is used, this is not necessary /// Note: atm cannot be ref structs because they are returned in a valuetuple /// /// /// /// /// public readonly ref struct GroupsEnumerable where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent where T3 : struct, IEntityComponent where T4 : struct, IEntityComponent { public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList groups) { _db = db; _groups = groups; } public ref struct GroupsIterator { public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList groups) : this() { _groups = groups; _indexGroup = -1; _entitiesDB = db; } public bool MoveNext() { //attention, the while is necessary to skip empty groups while (++_indexGroup < _groups.count) { var exclusiveGroupStruct = _groups[_indexGroup]; if (!exclusiveGroupStruct.IsEnabled()) continue; var entityCollection = _entitiesDB.QueryEntities(exclusiveGroupStruct); if (entityCollection.count == 0) continue; _buffers = entityCollection; break; } var moveNext = _indexGroup < _groups.count; if (moveNext == false) Reset(); return moveNext; } public void Reset() { _indexGroup = -1; } public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]); public bool isValid => _indexGroup != -1; readonly LocalFasterReadOnlyList _groups; int _indexGroup; EntityCollection _buffers; readonly EntitiesDB _entitiesDB; } public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); } readonly EntitiesDB _db; readonly LocalFasterReadOnlyList _groups; public readonly ref struct RefCurrent { public RefCurrent(in EntityCollection buffers, ExclusiveGroupStruct group) { _buffers = buffers; _group = group; } public void Deconstruct(out EntityCollection buffers, out ExclusiveGroupStruct group) { buffers = _buffers; group = _group; } public readonly EntityCollection _buffers; public readonly ExclusiveGroupStruct _group; } } public readonly ref struct GroupsEnumerable where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent where T3 : struct, IEntityComponent { public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList groups) { _db = db; _groups = groups; } public ref struct GroupsIterator { public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList groups) : this() { _groups = groups; _indexGroup = -1; _entitiesDB = db; } public bool MoveNext() { //attention, the while is necessary to skip empty groups while (++_indexGroup < _groups.count) { var exclusiveGroupStruct = _groups[_indexGroup]; if (!exclusiveGroupStruct.IsEnabled()) continue; EntityCollection entityCollection = _entitiesDB.QueryEntities(exclusiveGroupStruct); if (entityCollection.count == 0) continue; _buffers = entityCollection; break; } var moveNext = _indexGroup < _groups.count; if (moveNext == false) Reset(); return moveNext; } public void Reset() { _indexGroup = -1; } public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]); public bool isValid => _indexGroup != -1; readonly LocalFasterReadOnlyList _groups; int _indexGroup; EntityCollection _buffers; readonly EntitiesDB _entitiesDB; } //todo: there is a steep cost to pay to copy these structs, one day I may need to investigate this more. //the structs are quite big, in the order of 100+ bytes. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); } readonly EntitiesDB _db; readonly LocalFasterReadOnlyList _groups; public readonly ref struct RefCurrent { public RefCurrent(in EntityCollection buffers, ExclusiveGroupStruct group) { _buffers = buffers; _group = group; } public void Deconstruct(out EntityCollection buffers, out ExclusiveGroupStruct group) { buffers = _buffers; group = _group; } public readonly EntityCollection _buffers; public readonly ExclusiveGroupStruct _group; } } public readonly ref struct GroupsEnumerable where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent { public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList groups) { _db = db; _groups = groups; } public ref struct GroupsIterator { public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList groups) : this() { _db = db; _groups = groups; _indexGroup = -1; } public bool MoveNext() { //attention, the while is necessary to skip empty groups while (++_indexGroup < _groups.count) { var exclusiveGroupStruct = _groups[_indexGroup]; if (!exclusiveGroupStruct.IsEnabled()) continue; var entityCollection = _db.QueryEntities(exclusiveGroupStruct); if (entityCollection.count == 0) continue; _buffers = entityCollection; break; } var moveNext = _indexGroup < _groups.count; if (moveNext == false) Reset(); return moveNext; } public void Reset() { _indexGroup = -1; } public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]); public bool isValid => _indexGroup != -1; readonly EntitiesDB _db; readonly LocalFasterReadOnlyList _groups; int _indexGroup; EntityCollection _buffers; } public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); } readonly EntitiesDB _db; readonly LocalFasterReadOnlyList _groups; public readonly ref struct RefCurrent { public RefCurrent(in EntityCollection buffers, ExclusiveGroupStruct group) { _buffers = buffers; _group = group; } public void Deconstruct(out EntityCollection buffers, out ExclusiveGroupStruct group) { buffers = _buffers; group = _group; } public readonly EntityCollection _buffers; public readonly ExclusiveGroupStruct _group; } } public readonly ref struct GroupsEnumerable where T1 : struct, IEntityComponent { public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList groups) { _db = db; _groups = groups; } public ref struct GroupsIterator { public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList groups) : this() { _db = db; _groups = groups; _indexGroup = -1; } public bool MoveNext() { //attention, the while is necessary to skip empty groups while (++_indexGroup < _groups.count) { var exclusiveGroupStruct = _groups[_indexGroup]; if (!exclusiveGroupStruct.IsEnabled()) continue; var entityCollection = _db.QueryEntities(exclusiveGroupStruct); if (entityCollection.count == 0) continue; _buffer = entityCollection; break; } var moveNext = _indexGroup < _groups.count; if (moveNext == false) Reset(); return moveNext; } public void Reset() { _indexGroup = -1; } public RefCurrent Current => new RefCurrent(_buffer, _groups[_indexGroup]); public bool isValid => _indexGroup != -1; readonly EntitiesDB _db; readonly LocalFasterReadOnlyList _groups; int _indexGroup; EntityCollection _buffer; } public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); } readonly EntitiesDB _db; readonly LocalFasterReadOnlyList _groups; public readonly ref struct RefCurrent { public RefCurrent(in EntityCollection buffers, in ExclusiveGroupStruct group) { _buffers = buffers; _group = group; } public void Deconstruct(out EntityCollection buffers, out ExclusiveGroupStruct group) { buffers = _buffers; group = _group; } public void Deconstruct(out EntityCollection buffers) { buffers = _buffers; } internal readonly EntityCollection _buffers; internal readonly ExclusiveGroupStruct _group; } } }