1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.replica.replicaisland; 18 19 /** 20 * ObjectManagers are "group nodes" in the game graph. They contain child objects, and updating 21 * an object manager invokes update on its children. ObjectManagers themselves are derived from 22 * BaseObject, so they may be strung together into a hierarchy of objects. ObjectManager may 23 * be specialized to implement special types of traversals (e.g. PhasedObjectManager sorts its 24 * children). 25 */ 26 public class ObjectManager extends BaseObject { 27 protected static final int DEFAULT_ARRAY_SIZE = 64; 28 29 private FixedSizeArray<BaseObject> mObjects; 30 private FixedSizeArray<BaseObject> mPendingAdditions; 31 private FixedSizeArray<BaseObject> mPendingRemovals; 32 33 public ObjectManager() { 34 super(); 35 mObjects = new FixedSizeArray<BaseObject>(DEFAULT_ARRAY_SIZE); 36 mPendingAdditions = new FixedSizeArray<BaseObject>(DEFAULT_ARRAY_SIZE); 37 mPendingRemovals = new FixedSizeArray<BaseObject>(DEFAULT_ARRAY_SIZE); 38 } 39 40 public ObjectManager(int arraySize) { 41 super(); 42 mObjects = new FixedSizeArray<BaseObject>(arraySize); 43 mPendingAdditions = new FixedSizeArray<BaseObject>(arraySize); 44 mPendingRemovals = new FixedSizeArray<BaseObject>(arraySize); 45 } 46 47 @Override 48 public void reset() { 49 commitUpdates(); 50 final int count = mObjects.getCount(); 51 for (int i = 0; i < count; i++) { 52 BaseObject object = mObjects.get(i); 53 object.reset(); 54 } 55 } 56 57 public void commitUpdates() { 58 final int additionCount = mPendingAdditions.getCount(); 59 if (additionCount > 0) { 60 final Object[] additionsArray = mPendingAdditions.getArray(); 61 for (int i = 0; i < additionCount; i++) { 62 BaseObject object = (BaseObject)additionsArray[i]; 63 mObjects.add(object); 64 } 65 mPendingAdditions.clear(); 66 } 67 68 final int removalCount = mPendingRemovals.getCount(); 69 if (removalCount > 0) { 70 final Object[] removalsArray = mPendingRemovals.getArray(); 71 72 for (int i = 0; i < removalCount; i++) { 73 BaseObject object = (BaseObject)removalsArray[i]; 74 mObjects.remove(object, true); 75 } 76 mPendingRemovals.clear(); 77 } 78 } 79 80 @Override 81 public void update(float timeDelta, BaseObject parent) { 82 commitUpdates(); 83 final int count = mObjects.getCount(); 84 if (count > 0) { 85 final Object[] objectArray = mObjects.getArray(); 86 for (int i = 0; i < count; i++) { 87 BaseObject object = (BaseObject)objectArray[i]; 88 object.update(timeDelta, this); 89 } 90 } 91 } 92 93 public final FixedSizeArray<BaseObject> getObjects() { 94 return mObjects; 95 } 96 97 public final int getCount() { 98 return mObjects.getCount(); 99 } 100 101 /** Returns the count after the next commitUpdates() is called. */ 102 public final int getConcreteCount() { 103 return mObjects.getCount() + mPendingAdditions.getCount() - mPendingRemovals.getCount(); 104 } 105 106 public final BaseObject get(int index) { 107 return mObjects.get(index); 108 } 109 110 public void add(BaseObject object) { 111 mPendingAdditions.add(object); 112 } 113 114 public void remove(BaseObject object) { 115 mPendingRemovals.add(object); 116 } 117 118 public void removeAll() { 119 final int count = mObjects.getCount(); 120 final Object[] objectArray = mObjects.getArray(); 121 for (int i = 0; i < count; i++) { 122 mPendingRemovals.add((BaseObject)objectArray[i]); 123 } 124 mPendingAdditions.clear(); 125 } 126 127 /** 128 * Finds a child object by its type. Note that this may invoke the class loader and therefore 129 * may be slow. 130 * @param classObject The class type to search for (e.g. BaseObject.class). 131 * @return 132 */ 133 public <T> T findByClass(Class<T> classObject) { 134 T object = null; 135 final int count = mObjects.getCount(); 136 for (int i = 0; i < count; i++) { 137 BaseObject currentObject = mObjects.get(i); 138 if (currentObject.getClass() == classObject) { 139 object = classObject.cast(currentObject); 140 break; 141 } 142 } 143 return object; 144 } 145 146 protected FixedSizeArray<BaseObject> getPendingObjects() { 147 return mPendingAdditions; 148 } 149 150 } 151