Save history states
This commit is contained in:
parent
5813f41f4c
commit
5c663e7b24
@ -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) {
|
||||
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user