Save history states

This commit is contained in:
serso 2016-01-12 14:26:29 +01:00
parent 5813f41f4c
commit 5c663e7b24
6 changed files with 90 additions and 13 deletions

View File

@ -70,6 +70,7 @@ import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -136,6 +137,15 @@ public final class App {
return new Thread(r, "Init");
}
});
@Nonnull
private static final Executor background = Executors.newFixedThreadPool(5, new ThreadFactory() {
@NonNull
private final AtomicInteger counter = new AtomicInteger();
@Override
public Thread newThread(@Nonnull Runnable r) {
return new Thread(r, "Background #" + counter.getAndIncrement());
}
});
private App() {
throw new AssertionError();
@ -271,6 +281,11 @@ public final class App {
return initThread;
}
@Nonnull
public static Executor getBackground() {
return background;
}
@Nonnull
public static Preferences.Gui.Theme getThemeFor(@Nonnull Context context) {
if (context instanceof CalculatorOnscreenService) {

View File

@ -105,4 +105,13 @@ public class DisplayState {
json.put(JSON_TEXT, text);
return json;
}
@Override
public String toString() {
return "DisplayState{" +
"valid=" + valid +
", sequence=" + sequence +
", operation=" + operation +
'}';
}
}

View File

@ -23,9 +23,11 @@
package org.solovyev.android.calculator;
import android.text.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.solovyev.android.Check;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -35,7 +37,7 @@ public class EditorState {
public static final long NO_SEQUENCE = -1;
private static final String JSON_TEXT = "t";
private static final String JSON_SELECTION = "s";
private static long counter = NO_SEQUENCE + 1;
private static AtomicLong counter = new AtomicLong(NO_SEQUENCE + 1);
public final long sequence;
@Nonnull
@ -49,8 +51,7 @@ public class EditorState {
}
private EditorState(@Nonnull CharSequence text, int selection) {
Check.isMainThread();
this.sequence = counter++;
this.sequence = counter.getAndIncrement();
this.text = text;
this.selection = selection;
}
@ -91,11 +92,20 @@ public class EditorState {
return TextUtils.equals(text, that.text) && selection == that.selection;
}
@Override
public String toString() {
return "EditorState{" +
"sequence=" + sequence +
", text=" + text +
", selection=" + selection +
'}';
}
@Nonnull
public String toJson() throws JSONException {
public JSONObject toJson() throws JSONException {
final JSONObject json = new JSONObject();
json.put(JSON_TEXT, getTextString());
json.put(JSON_SELECTION, selection);
return json.toString();
return json;
}
}

View File

@ -23,6 +23,7 @@
package org.solovyev.android.calculator.history;
import android.content.SharedPreferences;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.text.TextUtils;
@ -54,10 +55,16 @@ import javax.annotation.Nullable;
public class History {
public static final String TAG = App.subTag("History");
@NonNull
private final Runnable writeCurrent = new WriteTask(true);
@NonNull
private final Runnable writeSaved = new WriteTask(false);
@Nonnull
private final HistoryList current = new HistoryList();
@Nonnull
private final List<HistoryState> saved = new ArrayList<>();
@Nonnull
private final Handler handler = App.getHandler();
@Nullable
private EditorState lastEditorState;
private boolean initialized;
@ -131,9 +138,11 @@ public class History {
migrateOldHistory();
final List<HistoryState> currentStates = loadStates(getCurrentHistoryFile());
final List<HistoryState> savedStates = loadStates(getSavedHistoryFile());
App.getHandler().post(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
Check.isTrue(current.isEmpty());
Check.isTrue(saved.isEmpty());
current.addAll(currentStates);
saved.addAll(savedStates);
initialized = true;
@ -155,11 +164,13 @@ public class History {
}
private void onCurrentChanged() {
// todo serso: implement
handler.removeCallbacks(writeCurrent);
handler.postDelayed(writeCurrent, 500);
}
private void onSavedChanged() {
// todo serso: implement
handler.removeCallbacks(writeSaved);
handler.postDelayed(writeSaved, 500);
}
@Nonnull
@ -184,10 +195,10 @@ public class History {
@Nonnull
public List<HistoryState> getSaved() {
Check.isMainThread();
return Collections.unmodifiableList(saved);
return new ArrayList<>(saved);
}
private boolean isIntermediate(@Nonnull String newerText,
private static boolean isIntermediate(@Nonnull String newerText,
@Nonnull String olderText) {
final int diff = newerText.length() - olderText.length();
if (diff == 1) {
@ -268,4 +279,27 @@ public class History {
addCurrent(HistoryState.newBuilder(lastEditorState, e.newState).build());
lastEditorState = null;
}
private class WriteTask implements Runnable {
private final boolean current;
public WriteTask(boolean current) {
this.current = current;
}
@Override
public void run() {
Check.isMainThread();
// don't need to save intermediate states, thus {@link History#getCurrent}
final List<HistoryState> states = current ? getCurrent() : getSaved();
App.getBackground().execute(new Runnable() {
@Override
public void run() {
final File file = current ? getCurrentHistoryFile() : getSavedHistoryFile();
final JSONArray array = HistoryList.toJson(states);
FileSaver.save(file, array.toString());
}
});
}
}
}

View File

@ -81,6 +81,16 @@ public class HistoryState {
return this.editor.same(that.editor) && this.display.same(that.display);
}
@Override
public String toString() {
return "HistoryState{" +
"editor=" + editor +
", display=" + display +
", time=" + time +
", comment='" + comment + '\'' +
'}';
}
public static final class Builder extends HistoryState {
private boolean built;

View File

@ -26,7 +26,6 @@ import org.solovyev.android.calculator.CalculatorFragmentType;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.R;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
@ -45,7 +44,7 @@ public class SavedHistoryFragment extends BaseHistoryFragment {
@Nonnull
@Override
protected List<HistoryState> getHistoryItems() {
return new ArrayList<>(Locator.getInstance().getHistory().getSaved());
return Locator.getInstance().getHistory().getSaved();
}
@Override