/// <summary> /// Update the position of a monitor. /// </summary> /// <param name="monitor">The monitor whose position has changed.</param> /// <param name="previousRegion">The previous area that the monitor was watching.</param> /// <param name="currentRegion">The new area that the monitor is watching.</param> public void UpdateMonitor(IQuadTreeMonitor <TItem> monitor, Bound previousRegion, Bound currentRegion) { // convert the bounds to rectangles Rect previousRect = new Rect(previousRegion); Rect currentRect = new Rect(currentRegion); Rect merged = Rect.Merge(previousRect, currentRect); IterateChunks(merged, node => { bool previousContains = previousRect.Colliding(node.MonitoredRegion); bool currentContains = currentRect.Colliding(node.MonitoredRegion); // the monitor is no longer interested in this chunk if (previousContains && currentContains == false) { node.Remove(monitor, previousRegion); } // the monitor is still interested in this chunk else if (previousContains && currentContains) { node.Update(monitor, previousRegion, currentRegion); } // the monitor is now interested in this chunk, but was not before else if (previousContains == false && currentContains) { node.Add(monitor, currentRegion); } }); }
public void Update(IQuadTreeMonitor <T> monitor, Bound previousRegion, Bound currentRegion) { // update the stored monitor for (int i = 0; i < _monitors.Length; ++i) { if (ReferenceEquals(_monitors[i].Monitor, monitor)) { _monitors[i].Region = currentRegion; break; } } // update the monitor for (int i = 0; i < _items.Length; ++i) { StoredItem item = _items[i]; bool containedPrevious = previousRegion.Contains(item.Position); bool containedCurrent = currentRegion.Contains(item.Position); // the monitor was previously interested but no longer is if (containedPrevious && containedCurrent == false) { monitor.OnExit(item.Item); } // the monitor was not previous interested but now is else if (containedPrevious == false && containedCurrent) { monitor.OnEnter(item.Item); } } }
public void Add(IQuadTreeMonitor <T> monitor, Bound monitoredRegion) { _monitors.Add(new StoredMonitor(monitor, monitoredRegion)); // check to see if the monitor is interested in any of our stored items for (int i = 0; i < _items.Length; ++i) { StoredItem item = _items[i]; if (monitoredRegion.Contains(item.Position)) { monitor.OnEnter(item.Item); } } }
public void Remove(IQuadTreeMonitor <T> monitor, Bound monitoredRegion) { // remove the stored monitor for (int i = 0; i < _monitors.Length; ++i) { if (ReferenceEquals(_monitors[i].Monitor, monitor)) { _monitors.Remove(i); break; } } // remove all stored items from the monitor for (int i = 0; i < _items.Length; ++i) { StoredItem item = _items[i]; if (monitoredRegion.Contains(item.Position)) { monitor.OnExit(item.Item); } } }
/// <summary> /// Removes the given monitor from the quad tree. It will receive a series of OnExit calls /// during this Remove call. /// </summary> /// <param name="monitor">The monitor to remove.</param> /// <param name="monitoredRegion">The region that the monitor was monitoring.</param> public void RemoveMonitor(IQuadTreeMonitor <TItem> monitor, Bound monitoredRegion) { IterateChunks(monitoredRegion, node => { node.Remove(monitor, monitoredRegion); }); }
public StoredMonitor(IQuadTreeMonitor <T> monitor, Bound region) { Monitor = monitor; Region = region; }