PointerTrackerQueue.java revision 5f282ea9e4a4590fcbab6e27d5fca7dacbb40a6a
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package com.android.inputmethod.keyboard.internal;
18
19import android.util.Log;
20
21import com.android.inputmethod.latin.CollectionUtils;
22
23import java.util.ArrayList;
24
25public class PointerTrackerQueue {
26    private static final String TAG = PointerTrackerQueue.class.getSimpleName();
27    private static final boolean DEBUG = false;
28
29    public interface Element {
30        public boolean isModifier();
31        public boolean isInSlidingKeyInput();
32        public void onPhantomUpEvent(long eventTime);
33    }
34
35    private static final int INITIAL_CAPACITY = 10;
36    private final ArrayList<Element> mExpandableArrayOfActivePointers =
37            CollectionUtils.newArrayList(INITIAL_CAPACITY);
38    private int mArraySize = 0;
39
40    public synchronized int size() {
41        return mArraySize;
42    }
43
44    public synchronized void add(final Element pointer) {
45        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
46        final int arraySize = mArraySize;
47        if (arraySize < expandableArray.size()) {
48            expandableArray.set(arraySize, pointer);
49        } else {
50            expandableArray.add(pointer);
51        }
52        mArraySize = arraySize + 1;
53    }
54
55    public synchronized void remove(final Element pointer) {
56        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
57        final int arraySize = mArraySize;
58        int newSize = 0;
59        for (int index = 0; index < arraySize; index++) {
60            final Element element = expandableArray.get(index);
61            if (element == pointer) {
62                if (newSize != index) {
63                    Log.w(TAG, "Found duplicated element in remove: " + pointer);
64                }
65                continue; // Remove this element from the expandableArray.
66            }
67            if (newSize != index) {
68                // Shift this element toward the beginning of the expandableArray.
69                expandableArray.set(newSize, element);
70            }
71            newSize++;
72        }
73        mArraySize = newSize;
74    }
75
76    public synchronized void releaseAllPointersOlderThan(final Element pointer,
77            final long eventTime) {
78        if (DEBUG) {
79            Log.d(TAG, "releaseAllPoniterOlderThan: " + pointer + " " + this);
80        }
81        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
82        final int arraySize = mArraySize;
83        int newSize, index;
84        for (newSize = index = 0; index < arraySize; index++) {
85            final Element element = expandableArray.get(index);
86            if (element == pointer) {
87                break; // Stop releasing elements.
88            }
89            if (!element.isModifier()) {
90                element.onPhantomUpEvent(eventTime);
91                continue; // Remove this element from the expandableArray.
92            }
93            if (newSize != index) {
94                // Shift this element toward the beginning of the expandableArray.
95                expandableArray.set(newSize, element);
96            }
97            newSize++;
98        }
99        // Shift rest of the expandableArray.
100        int count = 0;
101        for (; index < arraySize; index++) {
102            final Element element = expandableArray.get(index);
103            if (element == pointer) {
104                if (count > 0) {
105                    Log.w(TAG, "Found duplicated element in releaseAllPointersOlderThan: "
106                            + pointer);
107                }
108                count++;
109            }
110            if (newSize != index) {
111                expandableArray.set(newSize, expandableArray.get(index));
112                newSize++;
113            }
114        }
115        mArraySize = newSize;
116    }
117
118    public void releaseAllPointers(final long eventTime) {
119        releaseAllPointersExcept(null, eventTime);
120    }
121
122    public synchronized void releaseAllPointersExcept(final Element pointer,
123            final long eventTime) {
124        if (DEBUG) {
125            if (pointer == null) {
126                Log.d(TAG, "releaseAllPoniters: " + this);
127            } else {
128                Log.d(TAG, "releaseAllPoniterExcept: " + pointer + " " + this);
129            }
130        }
131        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
132        final int arraySize = mArraySize;
133        int newSize = 0, count = 0;
134        for (int index = 0; index < arraySize; index++) {
135            final Element element = expandableArray.get(index);
136            if (element == pointer) {
137                if (count > 0) {
138                    Log.w(TAG, "Found duplicated element in releaseAllPointersExcept: " + pointer);
139                }
140                count++;
141            } else {
142                element.onPhantomUpEvent(eventTime);
143                continue; // Remove this element from the expandableArray.
144            }
145            if (newSize != index) {
146                // Shift this element toward the beginning of the expandableArray.
147                expandableArray.set(newSize, element);
148            }
149            newSize++;
150        }
151        mArraySize = newSize;
152    }
153
154    public synchronized boolean hasModifierKeyOlderThan(final Element pointer) {
155        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
156        final int arraySize = mArraySize;
157        for (int index = 0; index < arraySize; index++) {
158            final Element element = expandableArray.get(index);
159            if (element == pointer) {
160                return false; // Stop searching modifier key.
161            }
162            if (element.isModifier()) {
163                return true;
164            }
165        }
166        return false;
167    }
168
169    public synchronized boolean isAnyInSlidingKeyInput() {
170        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
171        final int arraySize = mArraySize;
172        for (int index = 0; index < arraySize; index++) {
173            final Element element = expandableArray.get(index);
174            if (element.isInSlidingKeyInput()) {
175                return true;
176            }
177        }
178        return false;
179    }
180
181    @Override
182    public synchronized String toString() {
183        final StringBuilder sb = new StringBuilder();
184        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
185        final int arraySize = mArraySize;
186        for (int index = 0; index < arraySize; index++) {
187            final Element element = expandableArray.get(index);
188            if (sb.length() > 0)
189                sb.append(" ");
190            sb.append(element.toString());
191        }
192        return "[" + sb.toString() + "]";
193    }
194}
195