/** * 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.action.sprite.painting; import java.util.Comparator; import loon.action.sprite.SpriteBatch; import loon.utils.InsertionSorter; import loon.utils.TArray; import loon.utils.timer.GameTime; public final class GameComponentCollection { private TArray<IGameComponent> collections; private TArray<IGameComponent> collectionsToUpdate; private TArray<IGameComponent> collectionsToDraw; private final static Comparator<IGameComponent> igameDrawComparator = new Comparator<IGameComponent>() { public int compare(IGameComponent one, IGameComponent two) { if (one instanceof DrawableGameComponent && two instanceof DrawableGameComponent) { return ((DrawableGameComponent) one).getDrawOrder() - ((DrawableGameComponent) two).getDrawOrder(); } return 0; } }; private final static Comparator<IGameComponent> igameUpdateComparator = new Comparator<IGameComponent>() { public int compare(IGameComponent one, IGameComponent two) { if (one instanceof GameComponent && two instanceof GameComponent) { return ((GameComponent) one).getUpdateOrder() - ((GameComponent) two).getUpdateOrder(); } return 0; } }; private final static InsertionSorter<IGameComponent> _gameComponentSort = new InsertionSorter<IGameComponent>(); public GameComponentCollection() { this.collections = new TArray<IGameComponent>(); this.collectionsToUpdate = new TArray<IGameComponent>(); this.collectionsToDraw = new TArray<IGameComponent>(); } public int size() { return collections.size; } public void sortDraw() { _gameComponentSort.sort(collections, igameDrawComparator); } public void sortUpdate() { _gameComponentSort.sort(collections, igameUpdateComparator); } public TArray<IGameComponent> list() { return new TArray<IGameComponent>(collections); } public IGameComponent get(int idx) { return collections.get(idx); } void draw(SpriteBatch batch, GameTime gameTime) { if (isClear) { return; } if (collectionsToDraw.size > 0) { collectionsToDraw.clear(); } for (IGameComponent drawable : collections) { collectionsToDraw.add(drawable); } for (IGameComponent drawable : collectionsToDraw) { if (drawable instanceof IDrawable) { IDrawable comp = (IDrawable) drawable; comp.draw(batch, gameTime); } } } void load() { isClear = false; for (IGameComponent comp : collections) { comp.initialize(); } } void update(GameTime gameTime) { if (isClear) { return; } if (collectionsToUpdate.size > 0) { collectionsToUpdate.clear(); } for (IGameComponent drawable : collections) { collectionsToUpdate.add(drawable); } IGameComponent drawable; int screenIndex; for (; collectionsToUpdate.size > 0;) { screenIndex = collectionsToUpdate.size - 1; drawable = collectionsToUpdate.get(screenIndex); collectionsToUpdate.removeIndex(screenIndex); if (drawable instanceof IUpdateable) { IUpdateable comp = (IUpdateable) drawable; comp.update(gameTime); } } } private boolean isClear; public void clear() { if (!isClear) { synchronized (GameComponentCollection.class) { collections.clear(); collectionsToUpdate.clear(); collectionsToDraw.clear(); isClear = true; } } } public boolean add(IGameComponent gc) { if (isClear) { return false; } gc.initialize(); boolean result = collections.add(gc); if (gc != null && Added != null) { Added.invoke(gc); } if (gc instanceof DrawableGameComponent) { if (((DrawableGameComponent) gc).getDrawOrder() != 0) { sortDraw(); } } return result; } public boolean add(IGameComponent gc, int index) { if (isClear) { return false; } gc.initialize(); boolean result = collections.add(gc); for (int i = 0; i < collections.size; i++) { if (collections.get(i) instanceof DrawableGameComponent) { if (i == index) { ((DrawableGameComponent) collections.get(i)) .setEnabled(true); } else { ((DrawableGameComponent) collections.get(i)) .setEnabled(false); } } } if (gc != null && Added != null) { Added.invoke(gc); } if (gc instanceof DrawableGameComponent) { if (((DrawableGameComponent) gc).getDrawOrder() != 0) { sortDraw(); } } return result; } public boolean remove(IGameComponent gc) { if (isClear) { return false; } boolean result = false; if (gc != null && gc instanceof DrawableGameComponent) { DrawableGameComponent comp = (DrawableGameComponent) gc; comp.unloadContent(); result = collections.remove(gc); collectionsToUpdate.remove(gc); if (Removed != null) { Removed.invoke(gc); } } return result; } public boolean removeAt(int idx) { if (isClear) { return false; } IGameComponent comp = collections.removeIndex(idx); boolean result = (comp != null); if (result) { if (comp instanceof DrawableGameComponent) { ((DrawableGameComponent) comp).unloadContent(); } collectionsToUpdate.remove(comp); if (Removed != null) { Removed.invoke(comp); } } return result; } private ComponentEvent Added; private ComponentEvent Removed; public ComponentEvent getAdded() { return Added; } public void setAdded(ComponentEvent added) { Added = added; } public ComponentEvent getRemoved() { return Removed; } public void setRemoved(ComponentEvent removed) { Removed = removed; } }