/** * Copyright 2008 - 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.3.3 */ package loon.component; import java.util.Iterator; import loon.utils.LIterator; import loon.utils.ObjectMap; import loon.utils.ObjectMap.Entries; import loon.utils.ObjectMap.Entry; import loon.utils.ObjectSet; import loon.utils.SortedList; import loon.utils.TArray; public class CollisionManager implements CollisionChecker { private ObjectMap<String, SortedList<Actor>> freeObjects = new ObjectMap<String, SortedList<Actor>>(); private ObjectSet<String> collisionClasses = new ObjectSet<String>(); private CollisionChecker collisionChecker = new BSPCollisionChecker(); @Override public void initialize(int cellSize) { this.collisionChecker.initialize(cellSize); } @Override public void clear() { synchronized (CollisionManager.class) { if (collisionChecker != null) { collisionChecker.dispose(); collisionChecker.clear(); } if (freeObjects != null) { freeObjects.clear(); } if (collisionClasses != null) { collisionClasses.clear(); } } } private void makeCollisionObjects(String flag, boolean includeSubclasses) { if (flag == null) { Entries<String, SortedList<Actor>> entries = this.freeObjects .entries(); for (; entries.hasNext();) { Entry<String, SortedList<Actor>> entry = entries.next(); LIterator<Actor> itr = (entry.value).listIterator(); for (; itr.hasNext();) { Actor actor = itr.next(); this.collisionChecker.addObject(actor); } this.collisionClasses.add(entry.key); } this.freeObjects.clear(); } else if (!this.collisionClasses.contains(flag)) { SortedList<Actor> entries2 = this.freeObjects.remove(flag); if (entries2 != null) { this.collisionClasses.add(flag); LIterator<Actor> it = entries2.listIterator(); for (; it.hasNext();) { Actor entry1 = it.next(); this.collisionChecker.addObject(entry1); } } } if (includeSubclasses) { Entries<String, SortedList<Actor>> entries = this.freeObjects .entries(); for (; entries.hasNext();) { Entry<String, SortedList<Actor>> entry = entries.next(); if (flag != null && flag.equals(entry.key)) { this.makeCollisionObjects(entry.key, false); } } } } private void prepareForCollision(Actor actor, String flag) { this.makeCollisionObjects(actor.getFlag(), false); this.makeCollisionObjects(flag, true); } @Override public void addObject(Actor actor) { String flag = actor.getFlag(); if (this.collisionClasses.contains(flag)) { this.collisionChecker.addObject(actor); } else { SortedList<Actor> classSet = this.freeObjects.get(flag); if (classSet == null) { classSet = new SortedList<Actor>(); this.freeObjects.put(flag, classSet); } classSet.add(actor); } } @Override public TArray<Actor> getIntersectingObjects(Actor actor, String flag) { synchronized (CollisionManager.class) { this.prepareForCollision(actor, flag); return this.collisionChecker.getIntersectingObjects(actor, flag); } } @Override public TArray<Actor> getNeighbours(Actor actor, float distance, boolean diag, String flag) { synchronized (CollisionManager.class) { this.prepareForCollision(actor, flag); return this.collisionChecker.getNeighbours(actor, distance, diag, flag); } } @Override public TArray<Actor> getObjects(String flag) { TArray<Actor> result = this.collisionChecker.getObjects(flag); Entries<String, SortedList<Actor>> entries = this.freeObjects.entries(); for (; entries.hasNext();) { Entry<String, SortedList<Actor>> entry = entries.next(); if (flag == null || flag.equals(entry.key)) { for (LIterator<Actor> it = entry.value.listIterator(); it .hasNext();) { result.add(it.next()); } } } return result; } @Override public TArray<Actor> getObjectsAt(float x, float y, String flag) { this.makeCollisionObjects(flag, true); return this.collisionChecker.getObjectsAt(x, y, flag); } @Override public TArray<Actor> getObjectsInRange(float x, float y, float r, String flag) { this.makeCollisionObjects(flag, true); return this.collisionChecker.getObjectsInRange(x, y, r, flag); } @Override public TArray<Actor> getObjectsList() { return this.getObjects((String) null); } @Override public Actor getOnlyIntersectingObject(Actor object, String flag) { this.prepareForCollision(object, flag); return this.collisionChecker.getOnlyIntersectingObject(object, flag); } @Override public Actor getOnlyObjectAt(Actor object, float dx, float dy, String flag) { this.prepareForCollision(object, flag); return this.collisionChecker.getOnlyObjectAt(object, dx, dy, flag); } @Override public void removeObject(Actor object) { SortedList<Actor> classSet = this.freeObjects.get(object .getFlag()); if (classSet != null) { classSet.remove(object); } else { this.collisionChecker.removeObject(object); } } public void removeObject(String flag) { SortedList<Actor> classSet = this.freeObjects.get(flag); if (collisionClasses != null) { collisionClasses.remove(flag); } if (classSet != null) { classSet.remove(flag); } } @Override public void updateObjectLocation(Actor object, float oldX, float oldY) { if (!this.freeObjects.containsKey(object.getFlag())) { this.collisionChecker.updateObjectLocation(object, oldX, oldY); } } @Override public void updateObjectSize(Actor object) { if (!this.freeObjects.containsKey(object.getFlag())) { this.collisionChecker.updateObjectSize(object); } } @Override public void dispose() { if (freeObjects != null) { freeObjects.clear(); freeObjects = null; } if (collisionClasses != null) { collisionClasses.clear(); collisionClasses = null; } if (collisionChecker != null) { collisionChecker.dispose(); collisionChecker.clear(); collisionChecker = null; } } @Override public Iterator<Actor> getActorsIterator() { return collisionChecker.getActorsIterator(); } @Override public TArray<Actor> getActorsList() { return collisionChecker.getActorsList(); } }