1cfd74d65d832137e20e193c960802afba73b5d38sm/*
23c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Copyright (C) 2010 The Android Open Source Project
3cfd74d65d832137e20e193c960802afba73b5d38sm *
4cfd74d65d832137e20e193c960802afba73b5d38sm * Licensed under the Apache License, Version 2.0 (the "License");
5cfd74d65d832137e20e193c960802afba73b5d38sm * you may not use this file except in compliance with the License.
6cfd74d65d832137e20e193c960802afba73b5d38sm * You may obtain a copy of the License at
7cfd74d65d832137e20e193c960802afba73b5d38sm *
8cfd74d65d832137e20e193c960802afba73b5d38sm *      http://www.apache.org/licenses/LICENSE-2.0
9cfd74d65d832137e20e193c960802afba73b5d38sm *
10cfd74d65d832137e20e193c960802afba73b5d38sm * Unless required by applicable law or agreed to in writing, software
11cfd74d65d832137e20e193c960802afba73b5d38sm * distributed under the License is distributed on an "AS IS" BASIS,
12cfd74d65d832137e20e193c960802afba73b5d38sm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cfd74d65d832137e20e193c960802afba73b5d38sm * See the License for the specific language governing permissions and
14cfd74d65d832137e20e193c960802afba73b5d38sm * limitations under the License.
15cfd74d65d832137e20e193c960802afba73b5d38sm */
16cfd74d65d832137e20e193c960802afba73b5d38sm
17cfd74d65d832137e20e193c960802afba73b5d38smpackage com.replica.replicaisland;
18cfd74d65d832137e20e193c960802afba73b5d38sm
19cfd74d65d832137e20e193c960802afba73b5d38sm/**
20cfd74d65d832137e20e193c960802afba73b5d38sm * A game component that can swap other components in and out of its parent game object.  The
21cfd74d65d832137e20e193c960802afba73b5d38sm * purpose of the ChangeComponentsComponent is to allow game objects to have different "modes"
22cfd74d65d832137e20e193c960802afba73b5d38sm * defined by different combinations of GameComponents.  ChangeComponentsComponent manages the
23cfd74d65d832137e20e193c960802afba73b5d38sm * switching in and out of those modes by activating and deactivating specific game components.
24cfd74d65d832137e20e193c960802afba73b5d38sm */
25cfd74d65d832137e20e193c960802afba73b5d38smpublic class ChangeComponentsComponent extends GameComponent {
26cfd74d65d832137e20e193c960802afba73b5d38sm    private final static int MAX_COMPONENT_SWAPS = 16;
27cfd74d65d832137e20e193c960802afba73b5d38sm    private FixedSizeArray<GameComponent> mComponentsToInsert;
28cfd74d65d832137e20e193c960802afba73b5d38sm    private FixedSizeArray<GameComponent> mComponentsToRemove;
29cfd74d65d832137e20e193c960802afba73b5d38sm    private boolean mPingPong;
30cfd74d65d832137e20e193c960802afba73b5d38sm    private boolean mActivated;
31cfd74d65d832137e20e193c960802afba73b5d38sm    private boolean mCurrentlySwapped;
32cfd74d65d832137e20e193c960802afba73b5d38sm    private GameObject.ActionType mSwapOnAction;
33cfd74d65d832137e20e193c960802afba73b5d38sm    private GameObject.ActionType mLastAction;
34cfd74d65d832137e20e193c960802afba73b5d38sm
35cfd74d65d832137e20e193c960802afba73b5d38sm    public ChangeComponentsComponent() {
36cfd74d65d832137e20e193c960802afba73b5d38sm        super();
37cfd74d65d832137e20e193c960802afba73b5d38sm
38cfd74d65d832137e20e193c960802afba73b5d38sm        mComponentsToInsert = new FixedSizeArray<GameComponent>(MAX_COMPONENT_SWAPS);
39cfd74d65d832137e20e193c960802afba73b5d38sm        mComponentsToRemove = new FixedSizeArray<GameComponent>(MAX_COMPONENT_SWAPS);
40cfd74d65d832137e20e193c960802afba73b5d38sm
41cfd74d65d832137e20e193c960802afba73b5d38sm        reset();
42cfd74d65d832137e20e193c960802afba73b5d38sm    }
43cfd74d65d832137e20e193c960802afba73b5d38sm
44cfd74d65d832137e20e193c960802afba73b5d38sm    @Override
45cfd74d65d832137e20e193c960802afba73b5d38sm    public void reset() {
46cfd74d65d832137e20e193c960802afba73b5d38sm
47cfd74d65d832137e20e193c960802afba73b5d38sm        GameObjectFactory factory = sSystemRegistry.gameObjectFactory;
48cfd74d65d832137e20e193c960802afba73b5d38sm        // GameComponents hanging out in the mComponentsToInsert list are not part of the object
49cfd74d65d832137e20e193c960802afba73b5d38sm        // hierarchy, so we need to manually release them.
50cfd74d65d832137e20e193c960802afba73b5d38sm        if (factory != null) {
51cfd74d65d832137e20e193c960802afba73b5d38sm            FixedSizeArray<GameComponent> unrelasedComponents = mComponentsToInsert;
52cfd74d65d832137e20e193c960802afba73b5d38sm            if (mActivated) {
53cfd74d65d832137e20e193c960802afba73b5d38sm                if (!mPingPong) {
54cfd74d65d832137e20e193c960802afba73b5d38sm                    // if we've activated and are not set to ping pong, the contents of
55cfd74d65d832137e20e193c960802afba73b5d38sm                    // mComponentsToInsert have already been inserted into the object and
56cfd74d65d832137e20e193c960802afba73b5d38sm                    // will be cleaned up with all the other of the object's components.
57cfd74d65d832137e20e193c960802afba73b5d38sm                    // In that case, mComponentsToRemove contains objects that need manual
58cfd74d65d832137e20e193c960802afba73b5d38sm                    // clean up.
59cfd74d65d832137e20e193c960802afba73b5d38sm                    unrelasedComponents = mComponentsToRemove;
60cfd74d65d832137e20e193c960802afba73b5d38sm                }
61cfd74d65d832137e20e193c960802afba73b5d38sm            }
62cfd74d65d832137e20e193c960802afba73b5d38sm            final int inactiveComponentCount = unrelasedComponents.getCount();
63cfd74d65d832137e20e193c960802afba73b5d38sm            for (int x = 0; x < inactiveComponentCount; x++) {
64cfd74d65d832137e20e193c960802afba73b5d38sm                GameComponent component = unrelasedComponents.get(x);
65cfd74d65d832137e20e193c960802afba73b5d38sm                if (!component.shared) {
66cfd74d65d832137e20e193c960802afba73b5d38sm                    factory.releaseComponent(component);
67cfd74d65d832137e20e193c960802afba73b5d38sm                }
68cfd74d65d832137e20e193c960802afba73b5d38sm            }
69cfd74d65d832137e20e193c960802afba73b5d38sm        }
70cfd74d65d832137e20e193c960802afba73b5d38sm        mComponentsToInsert.clear();
71cfd74d65d832137e20e193c960802afba73b5d38sm        mComponentsToRemove.clear();
72cfd74d65d832137e20e193c960802afba73b5d38sm        mPingPong = false;
73cfd74d65d832137e20e193c960802afba73b5d38sm        mActivated = false;
74cfd74d65d832137e20e193c960802afba73b5d38sm        mCurrentlySwapped = false;
75cfd74d65d832137e20e193c960802afba73b5d38sm        mSwapOnAction = GameObject.ActionType.INVALID;
76cfd74d65d832137e20e193c960802afba73b5d38sm        mLastAction = GameObject.ActionType.INVALID;
77cfd74d65d832137e20e193c960802afba73b5d38sm    }
78cfd74d65d832137e20e193c960802afba73b5d38sm
79cfd74d65d832137e20e193c960802afba73b5d38sm
80cfd74d65d832137e20e193c960802afba73b5d38sm
81cfd74d65d832137e20e193c960802afba73b5d38sm    @Override
82cfd74d65d832137e20e193c960802afba73b5d38sm	public void update(float timeDelta, BaseObject parent) {
83cfd74d65d832137e20e193c960802afba73b5d38sm		if (mSwapOnAction != GameObject.ActionType.INVALID) {
84cfd74d65d832137e20e193c960802afba73b5d38sm			GameObject parentObject = (GameObject)parent;
85cfd74d65d832137e20e193c960802afba73b5d38sm			GameObject.ActionType currentAction = parentObject.getCurrentAction();
86cfd74d65d832137e20e193c960802afba73b5d38sm			if (currentAction != mLastAction) {
87cfd74d65d832137e20e193c960802afba73b5d38sm				mLastAction = currentAction;
88cfd74d65d832137e20e193c960802afba73b5d38sm				if (currentAction == mSwapOnAction) {
89cfd74d65d832137e20e193c960802afba73b5d38sm					activate(parentObject);
90cfd74d65d832137e20e193c960802afba73b5d38sm				}
91cfd74d65d832137e20e193c960802afba73b5d38sm			}
92cfd74d65d832137e20e193c960802afba73b5d38sm		}
93cfd74d65d832137e20e193c960802afba73b5d38sm	}
94cfd74d65d832137e20e193c960802afba73b5d38sm
95cfd74d65d832137e20e193c960802afba73b5d38sm	public void addSwapInComponent(GameComponent component) {
96cfd74d65d832137e20e193c960802afba73b5d38sm        mComponentsToInsert.add(component);
97cfd74d65d832137e20e193c960802afba73b5d38sm    }
98cfd74d65d832137e20e193c960802afba73b5d38sm
99cfd74d65d832137e20e193c960802afba73b5d38sm    public void addSwapOutComponent(GameComponent component) {
100cfd74d65d832137e20e193c960802afba73b5d38sm        mComponentsToRemove.add(component);
101cfd74d65d832137e20e193c960802afba73b5d38sm    }
102cfd74d65d832137e20e193c960802afba73b5d38sm
103cfd74d65d832137e20e193c960802afba73b5d38sm    public void setPingPongBehavior(boolean pingPong) {
104cfd74d65d832137e20e193c960802afba73b5d38sm        mPingPong = pingPong;
105cfd74d65d832137e20e193c960802afba73b5d38sm    }
106cfd74d65d832137e20e193c960802afba73b5d38sm
107cfd74d65d832137e20e193c960802afba73b5d38sm    public void setSwapAction(GameObject.ActionType action) {
108cfd74d65d832137e20e193c960802afba73b5d38sm    	mSwapOnAction = action;
109cfd74d65d832137e20e193c960802afba73b5d38sm    }
110cfd74d65d832137e20e193c960802afba73b5d38sm
111cfd74d65d832137e20e193c960802afba73b5d38sm    /** Inserts and removes components added to the swap-in and swap-out list, respectively.
112cfd74d65d832137e20e193c960802afba73b5d38sm     * Unless mPingPong is set, this may only be called once.
113cfd74d65d832137e20e193c960802afba73b5d38sm     * @param parent  The parent object to swap components on.
114cfd74d65d832137e20e193c960802afba73b5d38sm     */
115cfd74d65d832137e20e193c960802afba73b5d38sm    public void activate(GameObject parent) {
116cfd74d65d832137e20e193c960802afba73b5d38sm        if (!mActivated || mPingPong) {
117cfd74d65d832137e20e193c960802afba73b5d38sm            final int removeCount = mComponentsToRemove.getCount();
118cfd74d65d832137e20e193c960802afba73b5d38sm            for (int x = 0; x < removeCount; x++) {
119cfd74d65d832137e20e193c960802afba73b5d38sm                parent.remove(mComponentsToRemove.get(x));
120cfd74d65d832137e20e193c960802afba73b5d38sm            }
121cfd74d65d832137e20e193c960802afba73b5d38sm
122cfd74d65d832137e20e193c960802afba73b5d38sm            final int addCount = mComponentsToInsert.getCount();
123cfd74d65d832137e20e193c960802afba73b5d38sm            for (int x = 0; x < addCount; x++) {
124cfd74d65d832137e20e193c960802afba73b5d38sm                parent.add(mComponentsToInsert.get(x));
125cfd74d65d832137e20e193c960802afba73b5d38sm            }
126cfd74d65d832137e20e193c960802afba73b5d38sm
127cfd74d65d832137e20e193c960802afba73b5d38sm            mActivated = true;
128cfd74d65d832137e20e193c960802afba73b5d38sm            mCurrentlySwapped = !mCurrentlySwapped;
129cfd74d65d832137e20e193c960802afba73b5d38sm            if (mPingPong) {
130cfd74d65d832137e20e193c960802afba73b5d38sm                FixedSizeArray<GameComponent> swap = mComponentsToInsert;
131cfd74d65d832137e20e193c960802afba73b5d38sm                mComponentsToInsert = mComponentsToRemove;
132cfd74d65d832137e20e193c960802afba73b5d38sm                mComponentsToRemove = swap;
133cfd74d65d832137e20e193c960802afba73b5d38sm            }
134cfd74d65d832137e20e193c960802afba73b5d38sm        }
135cfd74d65d832137e20e193c960802afba73b5d38sm    }
136cfd74d65d832137e20e193c960802afba73b5d38sm
137cfd74d65d832137e20e193c960802afba73b5d38sm    public boolean getCurrentlySwapped() {
138cfd74d65d832137e20e193c960802afba73b5d38sm        return mCurrentlySwapped;
139cfd74d65d832137e20e193c960802afba73b5d38sm    }
140cfd74d65d832137e20e193c960802afba73b5d38sm}
141