Group all input-related info into an inner class.

Currently, these variables hold the info about the composing
word, or maybe some outdated info, and it's not very clear
which it is. LatinIME is maintaining the freshness info in
a separate boolean, and uses it throughout the code for many,
many things, leading to much confusion.
The idea in grouping this info is, it can be saved in another
instance and restored later. It can be tested against to know
whether there is actually outdated but kept info or not, and
it should allow to straighten out what is actually currently
being typed. Ultimately, it will eliminate the need for
LatinIME to keep track of the status of the info in the
word composer.

Change-Id: I00e2c690f303f8320c9be35590a6df4583e9e456
This commit is contained in:
Jean Chalard 2011-12-13 22:20:20 +09:00
parent 5a39e527dd
commit 27dff63833

View file

@ -32,15 +32,40 @@ public class WordComposer {
public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE;
public static final int NOT_A_COORDINATE = -1; public static final int NOT_A_COORDINATE = -1;
/** // Storage for all the info about the current input.
* The list of unicode values for each keystroke (including surrounding keys) private static class CharacterStore {
*/ /**
private ArrayList<int[]> mCodes; * The list of unicode values for each keystroke (including surrounding keys)
*/
ArrayList<int[]> mCodes;
int[] mXCoordinates;
int[] mYCoordinates;
StringBuilder mTypedWord;
CharacterStore() {
final int N = BinaryDictionary.MAX_WORD_LENGTH;
mCodes = new ArrayList<int[]>(N);
mTypedWord = new StringBuilder(N);
mXCoordinates = new int[N];
mYCoordinates = new int[N];
}
CharacterStore(final CharacterStore that) {
mCodes = new ArrayList<int[]>(that.mCodes);
mTypedWord = new StringBuilder(that.mTypedWord);
mXCoordinates = Arrays.copyOf(that.mXCoordinates, that.mXCoordinates.length);
mYCoordinates = Arrays.copyOf(that.mYCoordinates, that.mYCoordinates.length);
}
void reset() {
// For better performance than creating a new character store.
mCodes.clear();
mTypedWord.setLength(0);
}
}
private int[] mXCoordinates; // The currently typing word.
private int[] mYCoordinates; // NOTE: this is not reset as soon as the word is committed because it may be needed again
// to resume suggestion if backspaced. TODO: separate cleanly what is actually being
private StringBuilder mTypedWord; // composed and what is kept for possible resuming.
private CharacterStore mCurrentWord;
// An auto-correction for this word out of the dictionary. // An auto-correction for this word out of the dictionary.
private CharSequence mAutoCorrection; private CharSequence mAutoCorrection;
@ -56,11 +81,7 @@ public class WordComposer {
private boolean mIsFirstCharCapitalized; private boolean mIsFirstCharCapitalized;
public WordComposer() { public WordComposer() {
final int N = BinaryDictionary.MAX_WORD_LENGTH; mCurrentWord = new CharacterStore();
mCodes = new ArrayList<int[]>(N);
mTypedWord = new StringBuilder(N);
mXCoordinates = new int[N];
mYCoordinates = new int[N];
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;
mAutoCorrection = null; mAutoCorrection = null;
} }
@ -70,10 +91,7 @@ public class WordComposer {
} }
public void init(WordComposer source) { public void init(WordComposer source) {
mCodes = new ArrayList<int[]>(source.mCodes); mCurrentWord = new CharacterStore(source.mCurrentWord);
mTypedWord = new StringBuilder(source.mTypedWord);
mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length);
mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length);
mCapsCount = source.mCapsCount; mCapsCount = source.mCapsCount;
mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized;
mAutoCapitalized = source.mAutoCapitalized; mAutoCapitalized = source.mAutoCapitalized;
@ -85,8 +103,7 @@ public class WordComposer {
* Clear out the keys registered so far. * Clear out the keys registered so far.
*/ */
public void reset() { public void reset() {
mCodes.clear(); mCurrentWord.reset();
mTypedWord.setLength(0);
mCapsCount = 0; mCapsCount = 0;
mIsFirstCharCapitalized = false; mIsFirstCharCapitalized = false;
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;
@ -98,7 +115,7 @@ public class WordComposer {
* @return the number of keystrokes * @return the number of keystrokes
*/ */
public final int size() { public final int size() {
return mTypedWord.length(); return mCurrentWord.mTypedWord.length();
} }
/** /**
@ -107,15 +124,15 @@ public class WordComposer {
* @return the unicode for the pressed and surrounding keys * @return the unicode for the pressed and surrounding keys
*/ */
public int[] getCodesAt(int index) { public int[] getCodesAt(int index) {
return mCodes.get(index); return mCurrentWord.mCodes.get(index);
} }
public int[] getXCoordinates() { public int[] getXCoordinates() {
return mXCoordinates; return mCurrentWord.mXCoordinates;
} }
public int[] getYCoordinates() { public int[] getYCoordinates() {
return mYCoordinates; return mCurrentWord.mYCoordinates;
} }
private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) {
@ -130,12 +147,12 @@ public class WordComposer {
*/ */
public void add(int primaryCode, int[] codes, int x, int y) { public void add(int primaryCode, int[] codes, int x, int y) {
final int newIndex = size(); final int newIndex = size();
mTypedWord.append((char) primaryCode); mCurrentWord.mTypedWord.append((char) primaryCode);
correctPrimaryJuxtapos(primaryCode, codes); correctPrimaryJuxtapos(primaryCode, codes);
mCodes.add(codes); mCurrentWord.mCodes.add(codes);
if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) {
mXCoordinates[newIndex] = x; mCurrentWord.mXCoordinates[newIndex] = x;
mYCoordinates[newIndex] = y; mCurrentWord.mYCoordinates[newIndex] = y;
} }
mIsFirstCharCapitalized = isFirstCharCapitalized( mIsFirstCharCapitalized = isFirstCharCapitalized(
newIndex, primaryCode, mIsFirstCharCapitalized); newIndex, primaryCode, mIsFirstCharCapitalized);
@ -215,9 +232,9 @@ public class WordComposer {
final int size = size(); final int size = size();
if (size > 0) { if (size > 0) {
final int lastPos = size - 1; final int lastPos = size - 1;
char lastChar = mTypedWord.charAt(lastPos); char lastChar = mCurrentWord.mTypedWord.charAt(lastPos);
mCodes.remove(lastPos); mCurrentWord.mCodes.remove(lastPos);
mTypedWord.deleteCharAt(lastPos); mCurrentWord.mTypedWord.deleteCharAt(lastPos);
if (Character.isUpperCase(lastChar)) mCapsCount--; if (Character.isUpperCase(lastChar)) mCapsCount--;
} }
if (size() == 0) { if (size() == 0) {
@ -226,8 +243,8 @@ public class WordComposer {
if (mTrailingSingleQuotesCount > 0) { if (mTrailingSingleQuotesCount > 0) {
--mTrailingSingleQuotesCount; --mTrailingSingleQuotesCount;
} else { } else {
for (int i = mTypedWord.length() - 1; i >= 0; --i) { for (int i = mCurrentWord.mTypedWord.length() - 1; i >= 0; --i) {
if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break; if (Keyboard.CODE_SINGLE_QUOTE != mCurrentWord.mTypedWord.codePointAt(i)) break;
++mTrailingSingleQuotesCount; ++mTrailingSingleQuotesCount;
} }
} }
@ -239,7 +256,7 @@ public class WordComposer {
* @return the word that was typed so far. Never returns null. * @return the word that was typed so far. Never returns null.
*/ */
public String getTypedWord() { public String getTypedWord() {
return mTypedWord.toString(); return mCurrentWord.mTypedWord.toString();
} }
/** /**