1 /* 2 * Copyright (C) 2012 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 package com.android.inputmethod.latin.common; 18 19 import com.android.inputmethod.annotations.UsedForTesting; 20 21 import javax.annotation.Nonnull; 22 23 // TODO: This class is not thread-safe. 24 public final class InputPointers { 25 private static final boolean DEBUG_TIME = false; 26 27 private final int mDefaultCapacity; 28 private final ResizableIntArray mXCoordinates; 29 private final ResizableIntArray mYCoordinates; 30 private final ResizableIntArray mPointerIds; 31 private final ResizableIntArray mTimes; 32 33 public InputPointers(final int defaultCapacity) { 34 mDefaultCapacity = defaultCapacity; 35 mXCoordinates = new ResizableIntArray(defaultCapacity); 36 mYCoordinates = new ResizableIntArray(defaultCapacity); 37 mPointerIds = new ResizableIntArray(defaultCapacity); 38 mTimes = new ResizableIntArray(defaultCapacity); 39 } 40 41 private void fillWithLastTimeUntil(final int index) { 42 final int fromIndex = mTimes.getLength(); 43 // Fill the gap with the latest time. 44 // See {@link #getTime(int)} and {@link #isValidTimeStamps()}. 45 if (fromIndex <= 0) { 46 return; 47 } 48 final int fillLength = index - fromIndex + 1; 49 if (fillLength <= 0) { 50 return; 51 } 52 final int lastTime = mTimes.get(fromIndex - 1); 53 mTimes.fill(lastTime, fromIndex, fillLength); 54 } 55 56 public void addPointerAt(final int index, final int x, final int y, final int pointerId, 57 final int time) { 58 mXCoordinates.addAt(index, x); 59 mYCoordinates.addAt(index, y); 60 mPointerIds.addAt(index, pointerId); 61 if (DEBUG_TIME) { 62 fillWithLastTimeUntil(index); 63 } 64 mTimes.addAt(index, time); 65 } 66 67 @UsedForTesting 68 public void addPointer(final int x, final int y, final int pointerId, final int time) { 69 mXCoordinates.add(x); 70 mYCoordinates.add(y); 71 mPointerIds.add(pointerId); 72 mTimes.add(time); 73 } 74 75 public void set(@Nonnull final InputPointers ip) { 76 mXCoordinates.set(ip.mXCoordinates); 77 mYCoordinates.set(ip.mYCoordinates); 78 mPointerIds.set(ip.mPointerIds); 79 mTimes.set(ip.mTimes); 80 } 81 82 public void copy(@Nonnull final InputPointers ip) { 83 mXCoordinates.copy(ip.mXCoordinates); 84 mYCoordinates.copy(ip.mYCoordinates); 85 mPointerIds.copy(ip.mPointerIds); 86 mTimes.copy(ip.mTimes); 87 } 88 89 /** 90 * Append the times, x-coordinates and y-coordinates in the specified {@link ResizableIntArray} 91 * to the end of this. 92 * @param pointerId the pointer id of the source. 93 * @param times the source {@link ResizableIntArray} to read the event times from. 94 * @param xCoordinates the source {@link ResizableIntArray} to read the x-coordinates from. 95 * @param yCoordinates the source {@link ResizableIntArray} to read the y-coordinates from. 96 * @param startPos the starting index of the data in {@code times} and etc. 97 * @param length the number of data to be appended. 98 */ 99 public void append(final int pointerId, @Nonnull final ResizableIntArray times, 100 @Nonnull final ResizableIntArray xCoordinates, 101 @Nonnull final ResizableIntArray yCoordinates, final int startPos, final int length) { 102 if (length == 0) { 103 return; 104 } 105 mXCoordinates.append(xCoordinates, startPos, length); 106 mYCoordinates.append(yCoordinates, startPos, length); 107 mPointerIds.fill(pointerId, mPointerIds.getLength(), length); 108 mTimes.append(times, startPos, length); 109 } 110 111 /** 112 * Shift to the left by elementCount, discarding elementCount pointers at the start. 113 * @param elementCount how many elements to shift. 114 */ 115 @UsedForTesting 116 public void shift(final int elementCount) { 117 mXCoordinates.shift(elementCount); 118 mYCoordinates.shift(elementCount); 119 mPointerIds.shift(elementCount); 120 mTimes.shift(elementCount); 121 } 122 123 public void reset() { 124 final int defaultCapacity = mDefaultCapacity; 125 mXCoordinates.reset(defaultCapacity); 126 mYCoordinates.reset(defaultCapacity); 127 mPointerIds.reset(defaultCapacity); 128 mTimes.reset(defaultCapacity); 129 } 130 131 public int getPointerSize() { 132 return mXCoordinates.getLength(); 133 } 134 135 @Nonnull 136 public int[] getXCoordinates() { 137 return mXCoordinates.getPrimitiveArray(); 138 } 139 140 @Nonnull 141 public int[] getYCoordinates() { 142 return mYCoordinates.getPrimitiveArray(); 143 } 144 145 @Nonnull 146 public int[] getPointerIds() { 147 return mPointerIds.getPrimitiveArray(); 148 } 149 150 /** 151 * Gets the time each point was registered, in milliseconds, relative to the first event in the 152 * sequence. 153 * @return The time each point was registered, in milliseconds, relative to the first event in 154 * the sequence. 155 */ 156 @Nonnull 157 public int[] getTimes() { 158 return mTimes.getPrimitiveArray(); 159 } 160 161 @Override 162 public String toString() { 163 return "size=" + getPointerSize() + " id=" + mPointerIds + " time=" + mTimes 164 + " x=" + mXCoordinates + " y=" + mYCoordinates; 165 } 166 } 167