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
18package com.replica.replicaisland;
19
20import java.util.Comparator;
21
22/**
23 * A derivation of ObjectManager that sorts its children if they are of type PhasedObject.
24 * Sorting is performed on add.
25 */
26public class PhasedObjectManager extends ObjectManager {
27    private final static PhasedObjectComparator sPhasedObjectComparator
28        = new PhasedObjectComparator();
29    private boolean mDirty;
30    private PhasedObject mSearchDummy;  // A dummy object allocated up-front for searching by phase.
31
32    public PhasedObjectManager() {
33        super();
34        mDirty = false;
35        getObjects().setComparator(sPhasedObjectComparator);
36        getPendingObjects().setComparator(sPhasedObjectComparator);
37        mSearchDummy = new PhasedObject();
38    }
39
40    public PhasedObjectManager(int arraySize) {
41        super(arraySize);
42        mDirty = false;
43        getObjects().setComparator(sPhasedObjectComparator);
44        getPendingObjects().setComparator(sPhasedObjectComparator);
45        mSearchDummy = new PhasedObject();
46    }
47
48    @Override
49    public void commitUpdates() {
50        super.commitUpdates();
51        if (mDirty) {
52            getObjects().sort(true);
53            mDirty = false;
54        }
55    }
56
57    @Override
58    public void add(BaseObject object) {
59
60        if (object instanceof PhasedObject) {
61            super.add(object);
62            mDirty = true;
63        } else {
64            // The only reason to restrict PhasedObjectManager to PhasedObjects is so that
65            // the PhasedObjectComparator can assume all of its contents are PhasedObjects and
66            // avoid calling instanceof every time.
67            assert false : "Can't add a non-PhasedObject to a PhasedObjectManager!";
68        }
69    }
70
71    public BaseObject find(int phase) {
72        mSearchDummy.setPhase(phase);
73        int index = getObjects().find(mSearchDummy, false);
74        BaseObject result = null;
75        if (index != -1) {
76            result = getObjects().get(index);
77        } else {
78            index = getPendingObjects().find(mSearchDummy, false);
79            if (index != -1) {
80                result = getPendingObjects().get(index);
81            }
82        }
83        return result;
84    }
85
86    /** Comparator for phased objects. */
87    private static class PhasedObjectComparator implements Comparator<BaseObject>  {
88        public int compare(BaseObject object1, BaseObject object2) {
89            int result = 0;
90            if (object1 != null && object2 != null) {
91                result = ((PhasedObject) object1).phase - ((PhasedObject) object2).phase;
92            } else if (object1 == null && object2 != null) {
93                result = 1;
94            } else if (object2 == null && object1 != null) {
95                result = -1;
96            }
97            return result;
98        }
99    }
100
101}
102