Пример #1
0
        public bool TryAddOrUpdate(TEntity entity, out IEnumerable <TEntity> entitiesToAdd, out IEnumerable <TEntity> entitiesToRemove)
        {
            var newCellHash = this.GetHash(entity);

            SpatialGridCell oldCell = null;

            entitiesToAdd    = Enumerable.Empty <TEntity>();
            entitiesToRemove = Enumerable.Empty <TEntity>();

            var regInfo = this.entities.AddOrUpdate(
                entity.Id,
                (id) => new EntityRegistrationInfo(entity, this.GetCell(newCellHash)),
                (id, oldRegInfo) =>
            {
                oldCell = oldRegInfo.Cell;

                if (newCellHash != oldCell.Hash)
                {
                    oldRegInfo.Cell = this.GetCell(newCellHash);
                }

                return(oldRegInfo);
            });

            // At this point we have three possible states:
            // 1. Entity was registered on the grid for the first time
            // 2. Entity remains on the same cell
            // 3. Entity moved to the other cell
            if (oldCell != null && oldCell.Hash == newCellHash)
            {
                // Entity stays on the same cell, no need to update
                return(false);
            }

            IEnumerable <SpatialGridCell> newCellBlock = this.GetCellWithNeighbors(newCellHash).ToList();

            if (oldCell != null)
            {
                // Entity moved to the other cell
                oldCell.Remove(entity);
                var oldCellBlock = this.GetCellWithNeighbors(oldCell.Hash).ToList();

                entitiesToRemove = oldCellBlock.Except(newCellBlock).SelectMany(cell => cell.Entities).ToList();

                newCellBlock = newCellBlock.Except(oldCellBlock);
            }

            entitiesToAdd = newCellBlock.SelectMany(cell => cell.Entities).ToList();
            regInfo.Cell.Register(entity);

            if (oldCell == null)
            {
                // New entity registered on the grid
                this.EntityRegistered?.Invoke(this, new EntityEventArgs <TEntityId, TEntity>(entity));
            }

            return(true);
        }
Пример #2
0
 public EntityRegistrationInfo(TEntity entity, SpatialGridCell cell)
 {
     this.Entity = entity;
     this.Cell   = cell;
 }