Highlight text shown in editor asynchronously
This commit is contained in:
parent
f4896086fb
commit
5851f92daa
@ -26,6 +26,8 @@ import static java.lang.Math.min;
|
|||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
@ -47,9 +49,59 @@ import javax.inject.Singleton;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class Editor {
|
public class Editor {
|
||||||
|
|
||||||
|
private class AsyncHighlighter extends AsyncTask<Void, Void, EditorState> {
|
||||||
|
@NonNull
|
||||||
|
private final EditorState oldState;
|
||||||
|
@Nonnull
|
||||||
|
private final EditorState newState;
|
||||||
|
private final boolean force;
|
||||||
|
@Nullable
|
||||||
|
private final EditorTextProcessor processor;
|
||||||
|
@Nonnull
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
AsyncHighlighter(@NonNull EditorState oldState, @Nonnull EditorState newState, boolean force,
|
||||||
|
@Nullable EditorTextProcessor processor) {
|
||||||
|
this.oldState = oldState;
|
||||||
|
this.newState = newState;
|
||||||
|
this.text = newState.getTextString();
|
||||||
|
this.force = force;
|
||||||
|
this.processor = processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldAsync() {
|
||||||
|
return !TextUtils.isEmpty(text) && processor != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
protected EditorState doInBackground(Void... params) {
|
||||||
|
if (processor == null) {
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
final TextProcessorEditorResult res = processor.process(newState.getTextString());
|
||||||
|
return EditorState.create(res.getCharSequence(), newState.selection + res.getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(@Nonnull EditorState state) {
|
||||||
|
if (highlighterTask != this) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Editor.this.state = state;
|
||||||
|
if (view != null) {
|
||||||
|
view.setState(state);
|
||||||
|
}
|
||||||
|
bus.post(new ChangedEvent(oldState, state, force));
|
||||||
|
highlighterTask = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final EditorTextProcessor textProcessor;
|
private final EditorTextProcessor textProcessor;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
private AsyncHighlighter highlighterTask;
|
||||||
|
@Nullable
|
||||||
private EditorView view;
|
private EditorView view;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private EditorState state = EditorState.empty();
|
private EditorState state = EditorState.empty();
|
||||||
@ -101,16 +153,30 @@ public class Editor {
|
|||||||
|
|
||||||
private void onTextChanged(@Nonnull EditorState newState, boolean force) {
|
private void onTextChanged(@Nonnull EditorState newState, boolean force) {
|
||||||
Check.isMainThread();
|
Check.isMainThread();
|
||||||
if (textProcessor != null) {
|
asyncHighlightText(newState, force);
|
||||||
final TextProcessorEditorResult result = textProcessor.process(newState.getTextString());
|
|
||||||
newState = EditorState.create(result.getCharSequence(), newState.selection + result.getOffset());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cancelAsyncHighlightText() {
|
||||||
|
if (highlighterTask == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
highlighterTask.cancel(false);
|
||||||
|
highlighterTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void asyncHighlightText(@NonNull EditorState newState, boolean force) {
|
||||||
|
// synchronous operation should continue working regardless of the highlighter
|
||||||
final EditorState oldState = state;
|
final EditorState oldState = state;
|
||||||
state = newState;
|
state = newState;
|
||||||
if (view != null) {
|
|
||||||
view.setState(newState);
|
cancelAsyncHighlightText();
|
||||||
|
highlighterTask = new AsyncHighlighter(oldState, newState, force, textProcessor);
|
||||||
|
if (highlighterTask.shouldAsync()) {
|
||||||
|
highlighterTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
bus.post(new ChangedEvent(oldState, newState, force));
|
highlighterTask.onPostExecute(newState);
|
||||||
|
Check.isNull(highlighterTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
Loading…
Reference in New Issue
Block a user