From 36799b2aa2982ec17341cd2c5ed81e608bcee8c6 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 29 Oct 2014 11:37:21 +0900 Subject: Move InputPointers and ResizableIntArray to common Bug: 18108776 Change-Id: Ie5c0430aa41a8d6c58bf510a10173223d7dfe9fe --- .../inputmethod/latin/common/InputPointers.java | 157 +++++++++++++++++++++ .../latin/common/ResizableIntArray.java | 155 ++++++++++++++++++++ 2 files changed, 312 insertions(+) create mode 100644 common/src/com/android/inputmethod/latin/common/InputPointers.java create mode 100644 common/src/com/android/inputmethod/latin/common/ResizableIntArray.java (limited to 'common/src/com/android/inputmethod/latin') diff --git a/common/src/com/android/inputmethod/latin/common/InputPointers.java b/common/src/com/android/inputmethod/latin/common/InputPointers.java new file mode 100644 index 000000000..40131aca4 --- /dev/null +++ b/common/src/com/android/inputmethod/latin/common/InputPointers.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.common; + +import com.android.inputmethod.annotations.UsedForTesting; + +// TODO: This class is not thread-safe. +public final class InputPointers { + private static final boolean DEBUG_TIME = false; + + private final int mDefaultCapacity; + private final ResizableIntArray mXCoordinates; + private final ResizableIntArray mYCoordinates; + private final ResizableIntArray mPointerIds; + private final ResizableIntArray mTimes; + + public InputPointers(int defaultCapacity) { + mDefaultCapacity = defaultCapacity; + mXCoordinates = new ResizableIntArray(defaultCapacity); + mYCoordinates = new ResizableIntArray(defaultCapacity); + mPointerIds = new ResizableIntArray(defaultCapacity); + mTimes = new ResizableIntArray(defaultCapacity); + } + + private void fillWithLastTimeUntil(final int index) { + final int fromIndex = mTimes.getLength(); + // Fill the gap with the latest time. + // See {@link #getTime(int)} and {@link #isValidTimeStamps()}. + if (fromIndex <= 0) { + return; + } + final int fillLength = index - fromIndex + 1; + if (fillLength <= 0) { + return; + } + final int lastTime = mTimes.get(fromIndex - 1); + mTimes.fill(lastTime, fromIndex, fillLength); + } + + public void addPointerAt(int index, int x, int y, int pointerId, int time) { + mXCoordinates.addAt(index, x); + mYCoordinates.addAt(index, y); + mPointerIds.addAt(index, pointerId); + if (DEBUG_TIME) { + fillWithLastTimeUntil(index); + } + mTimes.addAt(index, time); + } + + @UsedForTesting + public void addPointer(int x, int y, int pointerId, int time) { + mXCoordinates.add(x); + mYCoordinates.add(y); + mPointerIds.add(pointerId); + mTimes.add(time); + } + + public void set(InputPointers ip) { + mXCoordinates.set(ip.mXCoordinates); + mYCoordinates.set(ip.mYCoordinates); + mPointerIds.set(ip.mPointerIds); + mTimes.set(ip.mTimes); + } + + public void copy(InputPointers ip) { + mXCoordinates.copy(ip.mXCoordinates); + mYCoordinates.copy(ip.mYCoordinates); + mPointerIds.copy(ip.mPointerIds); + mTimes.copy(ip.mTimes); + } + + /** + * Append the times, x-coordinates and y-coordinates in the specified {@link ResizableIntArray} + * to the end of this. + * @param pointerId the pointer id of the source. + * @param times the source {@link ResizableIntArray} to read the event times from. + * @param xCoordinates the source {@link ResizableIntArray} to read the x-coordinates from. + * @param yCoordinates the source {@link ResizableIntArray} to read the y-coordinates from. + * @param startPos the starting index of the data in {@code times} and etc. + * @param length the number of data to be appended. + */ + public void append(int pointerId, ResizableIntArray times, ResizableIntArray xCoordinates, + ResizableIntArray yCoordinates, int startPos, int length) { + if (length == 0) { + return; + } + mXCoordinates.append(xCoordinates, startPos, length); + mYCoordinates.append(yCoordinates, startPos, length); + mPointerIds.fill(pointerId, mPointerIds.getLength(), length); + mTimes.append(times, startPos, length); + } + + /** + * Shift to the left by elementCount, discarding elementCount pointers at the start. + * @param elementCount how many elements to shift. + */ + public void shift(final int elementCount) { + mXCoordinates.shift(elementCount); + mYCoordinates.shift(elementCount); + mPointerIds.shift(elementCount); + mTimes.shift(elementCount); + } + + public void reset() { + final int defaultCapacity = mDefaultCapacity; + mXCoordinates.reset(defaultCapacity); + mYCoordinates.reset(defaultCapacity); + mPointerIds.reset(defaultCapacity); + mTimes.reset(defaultCapacity); + } + + public int getPointerSize() { + return mXCoordinates.getLength(); + } + + public int[] getXCoordinates() { + return mXCoordinates.getPrimitiveArray(); + } + + public int[] getYCoordinates() { + return mYCoordinates.getPrimitiveArray(); + } + + public int[] getPointerIds() { + return mPointerIds.getPrimitiveArray(); + } + + /** + * Gets the time each point was registered, in milliseconds, relative to the first event in the + * sequence. + * @return The time each point was registered, in milliseconds, relative to the first event in + * the sequence. + */ + public int[] getTimes() { + return mTimes.getPrimitiveArray(); + } + + @Override + public String toString() { + return "size=" + getPointerSize() + " id=" + mPointerIds + " time=" + mTimes + + " x=" + mXCoordinates + " y=" + mYCoordinates; + } +} diff --git a/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java b/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java new file mode 100644 index 000000000..ea23d8a33 --- /dev/null +++ b/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.common; + +import java.util.Arrays; + +// TODO: This class is not thread-safe. +public final class ResizableIntArray { + private int[] mArray; + private int mLength; + + public ResizableIntArray(final int capacity) { + reset(capacity); + } + + public int get(final int index) { + if (index < mLength) { + return mArray[index]; + } + throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index); + } + + public void addAt(final int index, final int val) { + if (index < mLength) { + mArray[index] = val; + } else { + mLength = index; + add(val); + } + } + + public void add(final int val) { + final int currentLength = mLength; + ensureCapacity(currentLength + 1); + mArray[currentLength] = val; + mLength = currentLength + 1; + } + + /** + * Calculate the new capacity of {@code mArray}. + * @param minimumCapacity the minimum capacity that the {@code mArray} should have. + * @return the new capacity that the {@code mArray} should have. Returns zero when there is no + * need to expand {@code mArray}. + */ + private int calculateCapacity(final int minimumCapacity) { + final int currentCapcity = mArray.length; + if (currentCapcity < minimumCapacity) { + final int nextCapacity = currentCapcity * 2; + // The following is the same as return Math.max(minimumCapacity, nextCapacity); + return minimumCapacity > nextCapacity ? minimumCapacity : nextCapacity; + } + return 0; + } + + private void ensureCapacity(final int minimumCapacity) { + final int newCapacity = calculateCapacity(minimumCapacity); + if (newCapacity > 0) { + // TODO: Implement primitive array pool. + mArray = Arrays.copyOf(mArray, newCapacity); + } + } + + public int getLength() { + return mLength; + } + + public void setLength(final int newLength) { + ensureCapacity(newLength); + mLength = newLength; + } + + public void reset(final int capacity) { + // TODO: Implement primitive array pool. + mArray = new int[capacity]; + mLength = 0; + } + + public int[] getPrimitiveArray() { + return mArray; + } + + public void set(final ResizableIntArray ip) { + // TODO: Implement primitive array pool. + mArray = ip.mArray; + mLength = ip.mLength; + } + + public void copy(final ResizableIntArray ip) { + final int newCapacity = calculateCapacity(ip.mLength); + if (newCapacity > 0) { + // TODO: Implement primitive array pool. + mArray = new int[newCapacity]; + } + System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength); + mLength = ip.mLength; + } + + public void append(final ResizableIntArray src, final int startPos, final int length) { + if (length == 0) { + return; + } + final int currentLength = mLength; + final int newLength = currentLength + length; + ensureCapacity(newLength); + System.arraycopy(src.mArray, startPos, mArray, currentLength, length); + mLength = newLength; + } + + public void fill(final int value, final int startPos, final int length) { + if (startPos < 0 || length < 0) { + throw new IllegalArgumentException("startPos=" + startPos + "; length=" + length); + } + final int endPos = startPos + length; + ensureCapacity(endPos); + Arrays.fill(mArray, startPos, endPos, value); + if (mLength < endPos) { + mLength = endPos; + } + } + + /** + * Shift to the left by elementCount, discarding elementCount pointers at the start. + * @param elementCount how many elements to shift. + */ + public void shift(final int elementCount) { + System.arraycopy(mArray, elementCount, mArray, 0, mLength - elementCount); + mLength -= elementCount; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < mLength; i++) { + if (i != 0) { + sb.append(","); + } + sb.append(mArray[i]); + } + return "[" + sb + "]"; + } +} -- cgit v1.2.3-83-g751a