public Ecosystem AddHandler(EcosystemHandler handler) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } if (handler.SubscribesTo == null || !handler.SubscribesTo.Any()) { throw new ArgumentException($"At least one component must be subscribed to in {handler.GetType()}!"); } if (this._locksByHandler.ContainsKey(handler)) { throw new ArgumentException($"{handler.GetType()} has already been added!"); } // Collect a set of bitPositions that will be used to build a BitLock for this type combination var bitPositions = new List <ushort>(); foreach (var type in handler.SubscribesTo) { var bitPosition = this.GetOrAssignBitPosition(type); bitPositions.Add(bitPosition); } // Create a BitLock for the handler, and store the handler along with its BitLock var bitLock = this.CreateAndIndexBitLock(bitPositions); this._locksByHandler.Add(handler, bitLock); // Next, find all the entities currently in the Ecosystem that have the components that will fit this lock, // then index them by this lock. So when the handler says "give me all the entities I need to handle", we // already have that list cached. var entitiesByThisLock = new HashSet <Entity>(ReferenceEqualityComparer <Entity> .Default); this._entitiesByLock.Add(bitLock, entitiesByThisLock); if (this._entitiesById.Any()) { foreach (var entityById in this._entitiesById) { if (entityById.Value.HasAllComponents(handler.SubscribesTo.ToArray())) // todo: separate method overload for HasAllComponents? { entitiesByThisLock.Add(entityById.Value); } } } handler._timer = this._timer; return(this); }
public Ecosystem RemoveHandler(EcosystemHandler handler) { if (!this._locksByHandler.TryGetValue(handler, out var bitLock)) { // The handler wasn't registered in the first place return(this); } this._locksByHandler.Remove(handler); this._entitiesByLock.Remove(bitLock); this.DeindexBitLock(bitLock); handler._timer = null; return(this); }