Constant save refactored

This commit is contained in:
Sergey Solovyev
2012-10-02 01:07:19 +04:00
parent fb42a3ebe9
commit 9b6e3337c5
30 changed files with 1762 additions and 1581 deletions

View File

@@ -1,68 +1,71 @@
package org.solovyev.android.calculator;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.history.HistoryControl;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 16:38
*/
public interface Calculator extends CalculatorEventContainer, HistoryControl<CalculatorHistoryState> {
void init();
/*
**********************************************************************
*
* CALCULATIONS
*
**********************************************************************
*/
void evaluate();
void evaluate(@NotNull Long sequenceId);
void simplify();
@NotNull
CalculatorEventData evaluate(@NotNull JsclOperation operation,
@NotNull String expression);
@NotNull
CalculatorEventData evaluate(@NotNull JsclOperation operation,
@NotNull String expression,
@NotNull Long sequenceId);
/*
**********************************************************************
*
* CONVERSION
*
**********************************************************************
*/
boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to);
@NotNull
CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to);
/*
**********************************************************************
*
* EVENTS
*
**********************************************************************
*/
@NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data);
@NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId);
}
package org.solovyev.android.calculator;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.history.HistoryControl;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 16:38
*/
public interface Calculator extends CalculatorEventContainer, HistoryControl<CalculatorHistoryState> {
void init();
/*
**********************************************************************
*
* CALCULATIONS
*
**********************************************************************
*/
void evaluate();
void evaluate(@NotNull Long sequenceId);
void simplify();
@NotNull
CalculatorEventData evaluate(@NotNull JsclOperation operation,
@NotNull String expression);
@NotNull
CalculatorEventData evaluate(@NotNull JsclOperation operation,
@NotNull String expression,
@NotNull Long sequenceId);
/*
**********************************************************************
*
* CONVERSION
*
**********************************************************************
*/
boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to);
@NotNull
CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to);
/*
**********************************************************************
*
* EVENTS
*
**********************************************************************
*/
@NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data);
@NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Object source);
@NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId);
}

View File

@@ -1,98 +1,103 @@
package org.solovyev.android.calculator;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
/**
* User: Solovyev_S
* Date: 24.09.12
* Time: 16:48
*/
public class CalculatorConversionEventDataImpl implements CalculatorConversionEventData {
@NotNull
private CalculatorEventData calculatorEventData;
@NotNull
private NumeralBase fromNumeralBase;
@NotNull
private NumeralBase toNumeralBase;
@NotNull
private Generic value;
@NotNull
private CalculatorDisplayViewState displayState;
private CalculatorConversionEventDataImpl() {
}
@NotNull
public static CalculatorConversionEventData newInstance(@NotNull CalculatorEventData calculatorEventData,
@NotNull Generic value,
@NotNull NumeralBase from,
@NotNull NumeralBase to,
@NotNull CalculatorDisplayViewState displayViewState) {
final CalculatorConversionEventDataImpl result = new CalculatorConversionEventDataImpl();
result.calculatorEventData = calculatorEventData;
result.value = value;
result.displayState = displayViewState;
result.fromNumeralBase = from;
result.toNumeralBase = to;
return result;
}
@Override
public long getEventId() {
return calculatorEventData.getEventId();
}
@Override
@NotNull
public Long getSequenceId() {
return calculatorEventData.getSequenceId();
}
@Override
public boolean isAfter(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfter(that);
}
@Override
public boolean isSameSequence(@NotNull CalculatorEventData that) {
return calculatorEventData.isSameSequence(that);
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfterSequence(that);
}
@NotNull
@Override
public CalculatorDisplayViewState getDisplayState() {
return this.displayState;
}
@Override
@NotNull
public NumeralBase getFromNumeralBase() {
return fromNumeralBase;
}
@Override
@NotNull
public NumeralBase getToNumeralBase() {
return toNumeralBase;
}
@Override
@NotNull
public Generic getValue() {
return value;
}
}
package org.solovyev.android.calculator;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
/**
* User: Solovyev_S
* Date: 24.09.12
* Time: 16:48
*/
public class CalculatorConversionEventDataImpl implements CalculatorConversionEventData {
@NotNull
private CalculatorEventData calculatorEventData;
@NotNull
private NumeralBase fromNumeralBase;
@NotNull
private NumeralBase toNumeralBase;
@NotNull
private Generic value;
@NotNull
private CalculatorDisplayViewState displayState;
private CalculatorConversionEventDataImpl() {
}
@NotNull
public static CalculatorConversionEventData newInstance(@NotNull CalculatorEventData calculatorEventData,
@NotNull Generic value,
@NotNull NumeralBase from,
@NotNull NumeralBase to,
@NotNull CalculatorDisplayViewState displayViewState) {
final CalculatorConversionEventDataImpl result = new CalculatorConversionEventDataImpl();
result.calculatorEventData = calculatorEventData;
result.value = value;
result.displayState = displayViewState;
result.fromNumeralBase = from;
result.toNumeralBase = to;
return result;
}
@Override
public long getEventId() {
return calculatorEventData.getEventId();
}
@Override
@NotNull
public Long getSequenceId() {
return calculatorEventData.getSequenceId();
}
@Override
public Object getSource() {
return calculatorEventData.getSource();
}
@Override
public boolean isAfter(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfter(that);
}
@Override
public boolean isSameSequence(@NotNull CalculatorEventData that) {
return calculatorEventData.isSameSequence(that);
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfterSequence(that);
}
@NotNull
@Override
public CalculatorDisplayViewState getDisplayState() {
return this.displayState;
}
@Override
@NotNull
public NumeralBase getFromNumeralBase() {
return fromNumeralBase;
}
@Override
@NotNull
public NumeralBase getToNumeralBase() {
return toNumeralBase;
}
@Override
@NotNull
public Generic getValue() {
return value;
}
}

View File

@@ -1,17 +1,9 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 9/21/12
* Time: 9:49 PM
*/
public interface CalculatorDisplayChangeEventData {
@NotNull
CalculatorDisplayViewState getOldState();
@NotNull
CalculatorDisplayViewState getNewState();
public interface CalculatorDisplayChangeEventData extends Change<CalculatorDisplayViewState> {
}

View File

@@ -22,13 +22,13 @@ public class CalculatorDisplayChangeEventDataImpl implements CalculatorDisplayCh
@NotNull
@Override
public CalculatorDisplayViewState getOldState() {
public CalculatorDisplayViewState getOldValue() {
return this.oldState;
}
@NotNull
@Override
public CalculatorDisplayViewState getNewState() {
public CalculatorDisplayViewState getNewValue() {
return this.newState;
}
}

View File

@@ -1,17 +1,9 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: Solovyev_S
* Date: 21.09.12
* Time: 13:46
*/
public interface CalculatorEditorChangeEventData {
@NotNull
CalculatorEditorViewState getOldState();
@NotNull
CalculatorEditorViewState getNewState();
}
package org.solovyev.android.calculator;
/**
* User: Solovyev_S
* Date: 21.09.12
* Time: 13:46
*/
public interface CalculatorEditorChangeEventData extends Change<CalculatorEditorViewState>{
}

View File

@@ -23,13 +23,13 @@ public class CalculatorEditorChangeEventDataImpl implements CalculatorEditorChan
@NotNull
@Override
public CalculatorEditorViewState getOldState() {
public CalculatorEditorViewState getOldValue() {
return this.oldState;
}
@NotNull
@Override
public CalculatorEditorViewState getNewState() {
public CalculatorEditorViewState getNewValue() {
return this.newState;
}
}

View File

@@ -1,67 +1,72 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 10:01 PM
*/
public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData {
@NotNull
private final CalculatorEventData calculatorEventData;
@NotNull
private final JsclOperation operation;
@NotNull
private final String expression;
public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData,
@NotNull JsclOperation operation,
@NotNull String expression) {
this.calculatorEventData = calculatorEventData;
this.operation = operation;
this.expression = expression;
}
@NotNull
@Override
public JsclOperation getOperation() {
return this.operation;
}
@NotNull
@Override
public String getExpression() {
return this.expression;
}
@Override
public long getEventId() {
return calculatorEventData.getEventId();
}
@NotNull
@Override
public Long getSequenceId() {
return calculatorEventData.getSequenceId();
}
@Override
public boolean isAfter(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfter(that);
}
@Override
public boolean isSameSequence(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isSameSequence(that);
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isAfterSequence(that);
}
}
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 10:01 PM
*/
public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData {
@NotNull
private final CalculatorEventData calculatorEventData;
@NotNull
private final JsclOperation operation;
@NotNull
private final String expression;
public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData,
@NotNull JsclOperation operation,
@NotNull String expression) {
this.calculatorEventData = calculatorEventData;
this.operation = operation;
this.expression = expression;
}
@NotNull
@Override
public JsclOperation getOperation() {
return this.operation;
}
@NotNull
@Override
public String getExpression() {
return this.expression;
}
@Override
public long getEventId() {
return calculatorEventData.getEventId();
}
@NotNull
@Override
public Long getSequenceId() {
return calculatorEventData.getSequenceId();
}
@Override
public Object getSource() {
return calculatorEventData.getSource();
}
@Override
public boolean isAfter(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfter(that);
}
@Override
public boolean isSameSequence(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isSameSequence(that);
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isAfterSequence(that);
}
}

View File

@@ -1,24 +1,28 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 18:18
*/
public interface CalculatorEventData {
// the higher id => the later event
long getEventId();
// the higher id => the later event
@NotNull
Long getSequenceId();
boolean isAfter(@NotNull CalculatorEventData that);
boolean isSameSequence(@NotNull CalculatorEventData that);
boolean isAfterSequence(@NotNull CalculatorEventData that);
}
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 18:18
*/
public interface CalculatorEventData {
// the higher id => the later event
long getEventId();
// the higher id => the later event
@NotNull
Long getSequenceId();
@Nullable
Object getSource();
boolean isAfter(@NotNull CalculatorEventData that);
boolean isSameSequence(@NotNull CalculatorEventData that);
boolean isAfterSequence(@NotNull CalculatorEventData that);
}

View File

@@ -1,75 +1,89 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 18:18
*/
class CalculatorEventDataImpl implements CalculatorEventData {
private static final long NO_SEQUENCE = -1L;
private final long eventId;
@NotNull
private Long sequenceId = NO_SEQUENCE;
private CalculatorEventDataImpl(long id, @NotNull Long sequenceId) {
this.eventId = id;
this.sequenceId = sequenceId;
}
@NotNull
static CalculatorEventData newInstance(long id, @NotNull Long sequenceId) {
return new CalculatorEventDataImpl(id, sequenceId);
}
@Override
public long getEventId() {
return this.eventId;
}
@NotNull
@Override
public Long getSequenceId() {
return this.sequenceId;
}
@Override
public boolean isAfter(@NotNull CalculatorEventData that) {
return this.eventId > that.getEventId();
}
@Override
public boolean isSameSequence(@NotNull CalculatorEventData that) {
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId());
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CalculatorEventDataImpl)) return false;
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
if (eventId != that.eventId) return false;
if (!sequenceId.equals(that.sequenceId))
return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (eventId ^ (eventId >>> 32));
result = 31 * result + (sequenceId.hashCode());
return result;
}
}
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 18:18
*/
class CalculatorEventDataImpl implements CalculatorEventData {
private static final long NO_SEQUENCE = -1L;
private final long eventId;
@NotNull
private Long sequenceId = NO_SEQUENCE;
private final Object source;
private CalculatorEventDataImpl(long id, @NotNull Long sequenceId, @Nullable Object source) {
this.eventId = id;
this.sequenceId = sequenceId;
this.source = source;
}
@NotNull
static CalculatorEventData newInstance(long id, @NotNull Long sequenceId) {
return new CalculatorEventDataImpl(id, sequenceId, null);
}
@NotNull
static CalculatorEventData newInstance(long id, @NotNull Long sequenceId, @NotNull Object source) {
return new CalculatorEventDataImpl(id, sequenceId, source);
}
@Override
public long getEventId() {
return this.eventId;
}
@NotNull
@Override
public Long getSequenceId() {
return this.sequenceId;
}
@Override
public Object getSource() {
return this.source;
}
@Override
public boolean isAfter(@NotNull CalculatorEventData that) {
return this.eventId > that.getEventId();
}
@Override
public boolean isSameSequence(@NotNull CalculatorEventData that) {
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId());
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CalculatorEventDataImpl)) return false;
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
if (eventId != that.eventId) return false;
if (!sequenceId.equals(that.sequenceId))
return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (eventId ^ (eventId >>> 32));
result = 31 * result + (sequenceId.hashCode());
return result;
}
}

View File

@@ -106,7 +106,16 @@ public enum CalculatorEventType {
use_function,
// @NotNull Operator
use_operator;
use_operator,
// @NotNull IConstant
constant_added,
// @NotNull Change<IConstant>
constant_changed,
// @NotNull IConstant
constant_removed;
public boolean isOfType(@NotNull CalculatorEventType... types) {
for (CalculatorEventType type : types) {

View File

@@ -60,6 +60,12 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
return CalculatorEventDataImpl.newInstance(eventId, eventId);
}
@NotNull
private CalculatorEventData nextEventData(@NotNull Object source) {
long eventId = counter.incrementAndGet();
return CalculatorEventDataImpl.newInstance(eventId, eventId, source);
}
@NotNull
private CalculatorEventData nextEventData(@NotNull Long sequenceId) {
long eventId = counter.incrementAndGet();
@@ -353,6 +359,16 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
return eventData;
}
@NotNull
@Override
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Object source) {
final CalculatorEventData eventData = nextEventData(source);
fireCalculatorEvent(eventData, calculatorEventType, data);
return eventData;
}
@NotNull
@Override
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Long sequenceId) {
@@ -378,11 +394,11 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
case editor_state_changed:
final CalculatorEditorChangeEventData changeEventData = (CalculatorEditorChangeEventData) data;
final String newText = changeEventData.getNewState().getText();
final String oldText = changeEventData.getOldState().getText();
final String newText = changeEventData.getNewValue().getText();
final String oldText = changeEventData.getOldValue().getText();
if (!newText.equals(oldText)) {
evaluate(JsclOperation.numeric, changeEventData.getNewState().getText(), calculatorEventData.getSequenceId());
evaluate(JsclOperation.numeric, changeEventData.getNewValue().getText(), calculatorEventData.getSequenceId());
}
break;

View File

@@ -1,7 +1,11 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import java.util.List;
/**
* User: serso
@@ -11,4 +15,8 @@ import org.solovyev.common.msg.Message;
public interface CalculatorNotifier {
void showMessage(@NotNull Message message);
void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters);
void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters);
}

View File

@@ -0,0 +1,18 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 10/1/12
* Time: 11:16 PM
*/
public interface Change<T> {
@NotNull
T getOldValue();
@NotNull
T getNewValue();
}

View File

@@ -0,0 +1,42 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 10/1/12
* Time: 11:18 PM
*/
public class ChangeImpl<T> implements Change<T> {
@NotNull
private T oldValue;
@NotNull
private T newValue;
private ChangeImpl() {
}
@NotNull
public static <T> Change<T> newInstance(@NotNull T oldValue, @NotNull T newValue) {
final ChangeImpl<T> result = new ChangeImpl<T>();
result.oldValue = oldValue;
result.newValue = newValue;
return result;
}
@NotNull
@Override
public T getOldValue() {
return this.oldValue;
}
@NotNull
@Override
public T getNewValue() {
return this.newValue;
}
}

View File

@@ -1,7 +1,11 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import java.util.List;
/**
* User: serso
@@ -13,4 +17,12 @@ public class DummyCalculatorNotifier implements CalculatorNotifier {
@Override
public void showMessage(@NotNull Message message) {
}
@Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters) {
}
@Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) {
}
}

View File

@@ -1,234 +1,234 @@
package org.solovyev.android.calculator.history;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.*;
import org.solovyev.common.history.HistoryAction;
import org.solovyev.common.history.HistoryHelper;
import org.solovyev.common.history.SimpleHistoryHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.solovyev.android.calculator.CalculatorEventType.display_state_changed;
import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed;
import static org.solovyev.android.calculator.CalculatorEventType.manual_calculation_requested;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 16:12
*/
public class CalculatorHistoryImpl implements CalculatorHistory {
private final AtomicInteger counter = new AtomicInteger(0);
@NotNull
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
@NotNull
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>();
@NotNull
private volatile CalculatorEventData lastEventData = CalculatorUtils.createFirstEventDataId();
@NotNull
private final Object lastEventDataLock = new Object();
@Nullable
private volatile CalculatorEditorViewState lastEditorViewState;
public CalculatorHistoryImpl(@NotNull Calculator calculator) {
calculator.addCalculatorEventListener(this);
}
@Override
public boolean isEmpty() {
synchronized (history) {
return this.history.isEmpty();
}
}
@Override
public CalculatorHistoryState getLastHistoryState() {
synchronized (history) {
return this.history.getLastHistoryState();
}
}
@Override
public boolean isUndoAvailable() {
synchronized (history) {
return history.isUndoAvailable();
}
}
@Override
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
synchronized (history) {
return history.undo(currentState);
}
}
@Override
public boolean isRedoAvailable() {
return history.isRedoAvailable();
}
@Override
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
synchronized (history) {
return history.redo(currentState);
}
}
@Override
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
synchronized (history) {
return history.isActionAvailable(historyAction);
}
}
@Override
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
synchronized (history) {
return history.doAction(historyAction, currentState);
}
}
@Override
public void addState(@Nullable CalculatorHistoryState currentState) {
synchronized (history) {
history.addState(currentState);
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.history_state_added, currentState);
}
}
@NotNull
@Override
public List<CalculatorHistoryState> getStates() {
synchronized (history) {
return history.getStates();
}
}
@Override
public void clear() {
synchronized (history) {
this.history.clear();
}
}
@Override
@NotNull
public List<CalculatorHistoryState> getSavedHistory() {
return Collections.unmodifiableList(savedHistory);
}
@Override
@NotNull
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
if (historyState.isSaved()) {
return historyState;
} else {
final CalculatorHistoryState savedState = historyState.clone();
savedState.setId(counter.incrementAndGet());
savedState.setSaved(true);
savedHistory.add(savedState);
return savedState;
}
}
@Override
public void load() {
// todo serso: create saved/loader class
}
@Override
public void save() {
// todo serso: create saved/loader class
}
@Override
public void fromXml(@NotNull String xml) {
clearSavedHistory();
HistoryUtils.fromXml(xml, this.savedHistory);
for (CalculatorHistoryState historyState : savedHistory) {
historyState.setSaved(true);
historyState.setId(counter.incrementAndGet());
}
}
@Override
public String toXml() {
return HistoryUtils.toXml(this.savedHistory);
}
@Override
public void clearSavedHistory() {
this.savedHistory.clear();
}
@Override
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
this.savedHistory.remove(historyState);
}
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorEventType calculatorEventType,
@Nullable Object data) {
if (calculatorEventType.isOfType(editor_state_changed, display_state_changed, manual_calculation_requested)) {
boolean sameSequence = false;
boolean afterSequence = false;
boolean processEvent = false;
synchronized (this.lastEventDataLock) {
if (calculatorEventData.isAfter(this.lastEventData)) {
sameSequence = calculatorEventData.isSameSequence(this.lastEventData);
if (!sameSequence) {
afterSequence = calculatorEventData.isAfterSequence(this.lastEventData);
processEvent = afterSequence;
} else {
processEvent = true;
}
}
}
if (processEvent) {
this.lastEventData = calculatorEventData;
switch (calculatorEventType) {
case manual_calculation_requested:
lastEditorViewState = (CalculatorEditorViewState) data;
break;
case editor_state_changed:
final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data;
lastEditorViewState = editorChangeData.getNewState();
break;
case display_state_changed:
if (sameSequence) {
if (lastEditorViewState != null) {
final CalculatorEditorViewState editorViewState = lastEditorViewState;
final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data;
final CalculatorDisplayViewState displayViewState = displayChangeData.getNewState();
addState(CalculatorHistoryState.newInstance(editorViewState, displayViewState));
}
} else {
lastEditorViewState = null;
}
break;
}
}
}
}
}
package org.solovyev.android.calculator.history;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.*;
import org.solovyev.common.history.HistoryAction;
import org.solovyev.common.history.HistoryHelper;
import org.solovyev.common.history.SimpleHistoryHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.solovyev.android.calculator.CalculatorEventType.display_state_changed;
import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed;
import static org.solovyev.android.calculator.CalculatorEventType.manual_calculation_requested;
/**
* User: Solovyev_S
* Date: 20.09.12
* Time: 16:12
*/
public class CalculatorHistoryImpl implements CalculatorHistory {
private final AtomicInteger counter = new AtomicInteger(0);
@NotNull
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
@NotNull
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>();
@NotNull
private volatile CalculatorEventData lastEventData = CalculatorUtils.createFirstEventDataId();
@NotNull
private final Object lastEventDataLock = new Object();
@Nullable
private volatile CalculatorEditorViewState lastEditorViewState;
public CalculatorHistoryImpl(@NotNull Calculator calculator) {
calculator.addCalculatorEventListener(this);
}
@Override
public boolean isEmpty() {
synchronized (history) {
return this.history.isEmpty();
}
}
@Override
public CalculatorHistoryState getLastHistoryState() {
synchronized (history) {
return this.history.getLastHistoryState();
}
}
@Override
public boolean isUndoAvailable() {
synchronized (history) {
return history.isUndoAvailable();
}
}
@Override
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
synchronized (history) {
return history.undo(currentState);
}
}
@Override
public boolean isRedoAvailable() {
return history.isRedoAvailable();
}
@Override
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
synchronized (history) {
return history.redo(currentState);
}
}
@Override
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
synchronized (history) {
return history.isActionAvailable(historyAction);
}
}
@Override
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
synchronized (history) {
return history.doAction(historyAction, currentState);
}
}
@Override
public void addState(@Nullable CalculatorHistoryState currentState) {
synchronized (history) {
history.addState(currentState);
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.history_state_added, currentState);
}
}
@NotNull
@Override
public List<CalculatorHistoryState> getStates() {
synchronized (history) {
return history.getStates();
}
}
@Override
public void clear() {
synchronized (history) {
this.history.clear();
}
}
@Override
@NotNull
public List<CalculatorHistoryState> getSavedHistory() {
return Collections.unmodifiableList(savedHistory);
}
@Override
@NotNull
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
if (historyState.isSaved()) {
return historyState;
} else {
final CalculatorHistoryState savedState = historyState.clone();
savedState.setId(counter.incrementAndGet());
savedState.setSaved(true);
savedHistory.add(savedState);
return savedState;
}
}
@Override
public void load() {
// todo serso: create saved/loader class
}
@Override
public void save() {
// todo serso: create saved/loader class
}
@Override
public void fromXml(@NotNull String xml) {
clearSavedHistory();
HistoryUtils.fromXml(xml, this.savedHistory);
for (CalculatorHistoryState historyState : savedHistory) {
historyState.setSaved(true);
historyState.setId(counter.incrementAndGet());
}
}
@Override
public String toXml() {
return HistoryUtils.toXml(this.savedHistory);
}
@Override
public void clearSavedHistory() {
this.savedHistory.clear();
}
@Override
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
this.savedHistory.remove(historyState);
}
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorEventType calculatorEventType,
@Nullable Object data) {
if (calculatorEventType.isOfType(editor_state_changed, display_state_changed, manual_calculation_requested)) {
boolean sameSequence = false;
boolean afterSequence = false;
boolean processEvent = false;
synchronized (this.lastEventDataLock) {
if (calculatorEventData.isAfter(this.lastEventData)) {
sameSequence = calculatorEventData.isSameSequence(this.lastEventData);
if (!sameSequence) {
afterSequence = calculatorEventData.isAfterSequence(this.lastEventData);
processEvent = afterSequence;
} else {
processEvent = true;
}
}
}
if (processEvent) {
this.lastEventData = calculatorEventData;
switch (calculatorEventType) {
case manual_calculation_requested:
lastEditorViewState = (CalculatorEditorViewState) data;
break;
case editor_state_changed:
final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data;
lastEditorViewState = editorChangeData.getNewValue();
break;
case display_state_changed:
if (sameSequence) {
if (lastEditorViewState != null) {
final CalculatorEditorViewState editorViewState = lastEditorViewState;
final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data;
final CalculatorDisplayViewState displayViewState = displayChangeData.getNewValue();
addState(CalculatorHistoryState.newInstance(editorViewState, displayViewState));
}
} else {
lastEditorViewState = null;
}
break;
}
}
}
}
}