/* * Copyright (C) 2010 The Android Open Source Project * * 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. */ package com.replica.replicaisland; /** * ObjectManagers are "group nodes" in the game graph. They contain child objects, and updating * an object manager invokes update on its children. ObjectManagers themselves are derived from * BaseObject, so they may be strung together into a hierarchy of objects. ObjectManager may * be specialized to implement special types of traversals (e.g. PhasedObjectManager sorts its * children). */ public class ObjectManager extends BaseObject { protected static final int DEFAULT_ARRAY_SIZE = 64; private FixedSizeArray mObjects; private FixedSizeArray mPendingAdditions; private FixedSizeArray mPendingRemovals; public ObjectManager() { super(); mObjects = new FixedSizeArray(DEFAULT_ARRAY_SIZE); mPendingAdditions = new FixedSizeArray(DEFAULT_ARRAY_SIZE); mPendingRemovals = new FixedSizeArray(DEFAULT_ARRAY_SIZE); } public ObjectManager(int arraySize) { super(); mObjects = new FixedSizeArray(arraySize); mPendingAdditions = new FixedSizeArray(arraySize); mPendingRemovals = new FixedSizeArray(arraySize); } @Override public void reset() { commitUpdates(); final int count = mObjects.getCount(); for (int i = 0; i < count; i++) { BaseObject object = mObjects.get(i); object.reset(); } } public void commitUpdates() { final int additionCount = mPendingAdditions.getCount(); if (additionCount > 0) { final Object[] additionsArray = mPendingAdditions.getArray(); for (int i = 0; i < additionCount; i++) { BaseObject object = (BaseObject)additionsArray[i]; mObjects.add(object); } mPendingAdditions.clear(); } final int removalCount = mPendingRemovals.getCount(); if (removalCount > 0) { final Object[] removalsArray = mPendingRemovals.getArray(); for (int i = 0; i < removalCount; i++) { BaseObject object = (BaseObject)removalsArray[i]; mObjects.remove(object, true); } mPendingRemovals.clear(); } } @Override public void update(float timeDelta, BaseObject parent) { commitUpdates(); final int count = mObjects.getCount(); if (count > 0) { final Object[] objectArray = mObjects.getArray(); for (int i = 0; i < count; i++) { BaseObject object = (BaseObject)objectArray[i]; object.update(timeDelta, this); } } } public final FixedSizeArray getObjects() { return mObjects; } public final int getCount() { return mObjects.getCount(); } /** Returns the count after the next commitUpdates() is called. */ public final int getConcreteCount() { return mObjects.getCount() + mPendingAdditions.getCount() - mPendingRemovals.getCount(); } public final BaseObject get(int index) { return mObjects.get(index); } public void add(BaseObject object) { mPendingAdditions.add(object); } public void remove(BaseObject object) { mPendingRemovals.add(object); } public void removeAll() { final int count = mObjects.getCount(); final Object[] objectArray = mObjects.getArray(); for (int i = 0; i < count; i++) { mPendingRemovals.add((BaseObject)objectArray[i]); } mPendingAdditions.clear(); } /** * Finds a child object by its type. Note that this may invoke the class loader and therefore * may be slow. * @param classObject The class type to search for (e.g. BaseObject.class). * @return */ public T findByClass(Class classObject) { T object = null; final int count = mObjects.getCount(); for (int i = 0; i < count; i++) { BaseObject currentObject = mObjects.get(i); if (currentObject.getClass() == classObject) { object = classObject.cast(currentObject); break; } } return object; } protected FixedSizeArray getPendingObjects() { return mPendingAdditions; } }