Skip to content
Snippets Groups Projects
Commit a890de42 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Use ArrayList to implement PointerTrackerQueue" into jb-mr1-dev

parents 4ed69eed 7ae1fd02
No related branches found
No related tags found
No related merge requests found
...@@ -34,7 +34,7 @@ import com.android.inputmethod.research.ResearchLogger; ...@@ -34,7 +34,7 @@ import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList; import java.util.ArrayList;
public class PointerTracker implements PointerTrackerQueue.ElementActions { public class PointerTracker implements PointerTrackerQueue.Element {
private static final String TAG = PointerTracker.class.getSimpleName(); private static final String TAG = PointerTracker.class.getSimpleName();
private static final boolean DEBUG_EVENT = false; private static final boolean DEBUG_EVENT = false;
private static final boolean DEBUG_MOVE_EVENT = false; private static final boolean DEBUG_MOVE_EVENT = false;
......
...@@ -18,85 +18,146 @@ package com.android.inputmethod.keyboard.internal; ...@@ -18,85 +18,146 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log; import android.util.Log;
import java.util.Iterator; import java.util.ArrayList;
import java.util.LinkedList;
public class PointerTrackerQueue { public class PointerTrackerQueue {
private static final String TAG = PointerTrackerQueue.class.getSimpleName(); private static final String TAG = PointerTrackerQueue.class.getSimpleName();
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
public interface ElementActions { public interface Element {
public boolean isModifier(); public boolean isModifier();
public boolean isInSlidingKeyInput(); public boolean isInSlidingKeyInput();
public void onPhantomUpEvent(long eventTime); public void onPhantomUpEvent(long eventTime);
} }
// TODO: Use ring buffer instead of {@link LinkedList}. private static final int INITIAL_CAPACITY = 10;
private final LinkedList<ElementActions> mQueue = new LinkedList<ElementActions>(); private final ArrayList<Element> mExpandableArrayOfActivePointers =
new ArrayList<Element>(INITIAL_CAPACITY);
private int mArraySize = 0;
public int size() { public synchronized int size() {
return mQueue.size(); return mArraySize;
} }
public synchronized void add(ElementActions tracker) { public synchronized void add(final Element pointer) {
mQueue.add(tracker); final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
final int arraySize = mArraySize;
if (arraySize < expandableArray.size()) {
expandableArray.set(arraySize, pointer);
} else {
expandableArray.add(pointer);
}
mArraySize = arraySize + 1;
} }
public synchronized void remove(ElementActions tracker) { public synchronized void remove(final Element pointer) {
mQueue.remove(tracker); final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
final int arraySize = mArraySize;
int newSize = 0;
for (int index = 0; index < arraySize; index++) {
final Element element = expandableArray.get(index);
if (element == pointer) {
if (newSize != index) {
Log.w(TAG, "Found duplicated element in remove: " + pointer);
}
continue; // Remove this element from the expandableArray.
}
if (newSize != index) {
// Shift this element toward the beginning of the expandableArray.
expandableArray.set(newSize, element);
}
newSize++;
}
mArraySize = newSize;
} }
public synchronized void releaseAllPointersOlderThan(ElementActions tracker, public synchronized void releaseAllPointersOlderThan(final Element pointer,
long eventTime) { final long eventTime) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "releaseAllPoniterOlderThan: " + tracker + " " + this); Log.d(TAG, "releaseAllPoniterOlderThan: " + pointer + " " + this);
} }
if (!mQueue.contains(tracker)) { final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
return; final int arraySize = mArraySize;
int newSize, index;
for (newSize = index = 0; index < arraySize; index++) {
final Element element = expandableArray.get(index);
if (element == pointer) {
break; // Stop releasing elements.
}
if (!element.isModifier()) {
element.onPhantomUpEvent(eventTime);
continue; // Remove this element from the expandableArray.
}
if (newSize != index) {
// Shift this element toward the beginning of the expandableArray.
expandableArray.set(newSize, element);
}
newSize++;
} }
final Iterator<ElementActions> it = mQueue.iterator(); // Shift rest of the expandableArray.
while (it.hasNext()) { int count = 0;
final ElementActions t = it.next(); for (; index < arraySize; index++) {
if (t == tracker) { final Element element = expandableArray.get(index);
break; if (element == pointer) {
if (count > 0) {
Log.w(TAG, "Found duplicated element in releaseAllPointersOlderThan: "
+ pointer);
}
count++;
} }
if (!t.isModifier()) { if (newSize != index) {
t.onPhantomUpEvent(eventTime); expandableArray.set(newSize, expandableArray.get(index));
it.remove(); newSize++;
} }
} }
mArraySize = newSize;
} }
public void releaseAllPointers(long eventTime) { public void releaseAllPointers(final long eventTime) {
releaseAllPointersExcept(null, eventTime); releaseAllPointersExcept(null, eventTime);
} }
public synchronized void releaseAllPointersExcept(ElementActions tracker, long eventTime) { public synchronized void releaseAllPointersExcept(final Element pointer,
final long eventTime) {
if (DEBUG) { if (DEBUG) {
if (tracker == null) { if (pointer == null) {
Log.d(TAG, "releaseAllPoniters: " + this); Log.d(TAG, "releaseAllPoniters: " + this);
} else { } else {
Log.d(TAG, "releaseAllPoniterExcept: " + tracker + " " + this); Log.d(TAG, "releaseAllPoniterExcept: " + pointer + " " + this);
} }
} }
final Iterator<ElementActions> it = mQueue.iterator(); final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
while (it.hasNext()) { final int arraySize = mArraySize;
final ElementActions t = it.next(); int newSize = 0, count = 0;
if (t != tracker) { for (int index = 0; index < arraySize; index++) {
t.onPhantomUpEvent(eventTime); final Element element = expandableArray.get(index);
it.remove(); if (element == pointer) {
if (count > 0) {
Log.w(TAG, "Found duplicated element in releaseAllPointersExcept: " + pointer);
}
count++;
} else {
element.onPhantomUpEvent(eventTime);
continue; // Remove this element from the expandableArray.
}
if (newSize != index) {
// Shift this element toward the beginning of the expandableArray.
expandableArray.set(newSize, element);
} }
newSize++;
} }
mArraySize = newSize;
} }
public synchronized boolean hasModifierKeyOlderThan(ElementActions tracker) { public synchronized boolean hasModifierKeyOlderThan(final Element pointer) {
final Iterator<ElementActions> it = mQueue.iterator(); final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
while (it.hasNext()) { final int arraySize = mArraySize;
final ElementActions t = it.next(); for (int index = 0; index < arraySize; index++) {
if (t == tracker) { final Element element = expandableArray.get(index);
break; if (element == pointer) {
return false; // Stop searching modifier key.
} }
if (t.isModifier()) { if (element.isModifier()) {
return true; return true;
} }
} }
...@@ -104,8 +165,11 @@ public class PointerTrackerQueue { ...@@ -104,8 +165,11 @@ public class PointerTrackerQueue {
} }
public synchronized boolean isAnyInSlidingKeyInput() { public synchronized boolean isAnyInSlidingKeyInput() {
for (final ElementActions tracker : mQueue) { final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
if (tracker.isInSlidingKeyInput()) { final int arraySize = mArraySize;
for (int index = 0; index < arraySize; index++) {
final Element element = expandableArray.get(index);
if (element.isInSlidingKeyInput()) {
return true; return true;
} }
} }
...@@ -113,12 +177,15 @@ public class PointerTrackerQueue { ...@@ -113,12 +177,15 @@ public class PointerTrackerQueue {
} }
@Override @Override
public String toString() { public synchronized String toString() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
for (final ElementActions tracker : mQueue) { final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
final int arraySize = mArraySize;
for (int index = 0; index < arraySize; index++) {
final Element element = expandableArray.get(index);
if (sb.length() > 0) if (sb.length() > 0)
sb.append(" "); sb.append(" ");
sb.append(tracker.toString()); sb.append(element.toString());
} }
return "[" + sb.toString() + "]"; return "[" + sb.toString() + "]";
} }
......
...@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.internal; ...@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.internal;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
public class PointerTrackerQueueTests extends AndroidTestCase { public class PointerTrackerQueueTests extends AndroidTestCase {
public static class Element implements PointerTrackerQueue.ElementActions { public static class Element implements PointerTrackerQueue.Element {
public static int sPhantomUpCount; public static int sPhantomUpCount;
public static final long NOT_HAPPENED = -1; public static final long NOT_HAPPENED = -1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment