Skip to content

Commit

Permalink
Merge 9293b8a into a6225fc
Browse files Browse the repository at this point in the history
  • Loading branch information
garylyp committed Oct 9, 2019
2 parents a6225fc + 9293b8a commit fa5d182
Show file tree
Hide file tree
Showing 11 changed files with 376 additions and 4 deletions.
15 changes: 13 additions & 2 deletions src/main/java/seedu/exercise/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
import static seedu.exercise.logic.parser.CliSyntax.PREFIX_UNIT;

import seedu.exercise.logic.commands.exceptions.CommandException;
import seedu.exercise.logic.commands.history.EventHistory;
import seedu.exercise.model.Model;
import seedu.exercise.model.exercise.Exercise;

/**
* Adds an exercise to the exercise book.
*/
public class AddCommand extends Command {
public class AddCommand extends Command implements UndoableCommand {

public static final String COMMAND_WORD = "add";

Expand All @@ -41,13 +42,22 @@ public class AddCommand extends Command {
private final Exercise toAdd;

/**
* Creates an AddCommand to add the specified {@code Person}
* Creates an AddCommand to add the specified {@code Exercise}
*/
public AddCommand(Exercise exercise) {
requireNonNull(exercise);
toAdd = exercise;
}

/**
* Returns the exercise to be added to the Exercise Book.
*
* @return exercise that is passed into constructor of AddCommand
*/
public Exercise getExercise() {
return toAdd;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
Expand All @@ -57,6 +67,7 @@ public CommandResult execute(Model model) throws CommandException {
}

model.addExercise(toAdd);
EventHistory.getInstance().addCommandToUndoStack(this);
return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd));
}

Expand Down
16 changes: 14 additions & 2 deletions src/main/java/seedu/exercise/logic/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
import seedu.exercise.commons.core.Messages;
import seedu.exercise.commons.core.index.Index;
import seedu.exercise.logic.commands.exceptions.CommandException;
import seedu.exercise.logic.commands.history.EventHistory;
import seedu.exercise.model.Model;
import seedu.exercise.model.exercise.Exercise;

/**
* Deletes a exercise identified using it's displayed index from the exercise book.
*/
public class DeleteCommand extends Command {
public class DeleteCommand extends Command implements UndoableCommand {

public static final String COMMAND_WORD = "delete";

Expand All @@ -25,6 +26,7 @@ public class DeleteCommand extends Command {
public static final String MESSAGE_DELETE_EXERCISE_SUCCESS = "Deleted Exercise: %1$s";

private final Index targetIndex;
private Exercise exerciseToDelete;

public DeleteCommand(Index targetIndex) {
this.targetIndex = targetIndex;
Expand All @@ -39,11 +41,21 @@ public CommandResult execute(Model model) throws CommandException {
throw new CommandException(Messages.MESSAGE_INVALID_EXERCISE_DISPLAYED_INDEX);
}

Exercise exerciseToDelete = lastShownList.get(targetIndex.getZeroBased());
exerciseToDelete = lastShownList.get(targetIndex.getZeroBased());
model.deleteExercise(exerciseToDelete);
EventHistory.getInstance().addCommandToUndoStack(this);
return new CommandResult(String.format(MESSAGE_DELETE_EXERCISE_SUCCESS, exerciseToDelete));
}

/**
* Returns the exercise to be deleted from Exercise Book.
*
* @return exercise referred to by targetIndex
*/
public Exercise getExercise() {
return exerciseToDelete;
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/seedu/exercise/logic/commands/RedoCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package seedu.exercise.logic.commands;

import static java.util.Objects.requireNonNull;

import seedu.exercise.logic.commands.exceptions.CommandException;
import seedu.exercise.logic.commands.history.Event;
import seedu.exercise.logic.commands.history.EventHistory;
import seedu.exercise.model.Model;

/**
* Undoes the last executed command.
*/
public class RedoCommand extends Command {

public static final String COMMAND_WORD = "redo";

public static final String MESSAGE_SUCCESS = "Action redone: \n%1$s";
public static final String MESSAGE_EMPTY_REDO_STACK = "There is no command to redo";

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
EventHistory actionHistory = EventHistory.getInstance();

if (actionHistory.isRedoStackEmpty()) {
throw new CommandException(MESSAGE_EMPTY_REDO_STACK);
}

Event eventToRedo = actionHistory.redo();
eventToRedo.redo(model);
return new CommandResult(
String.format(MESSAGE_SUCCESS, eventToRedo));
}

}
37 changes: 37 additions & 0 deletions src/main/java/seedu/exercise/logic/commands/UndoCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package seedu.exercise.logic.commands;

import static java.util.Objects.requireNonNull;

import seedu.exercise.logic.commands.exceptions.CommandException;
import seedu.exercise.logic.commands.history.Event;
import seedu.exercise.logic.commands.history.EventHistory;
import seedu.exercise.model.Model;

/**
* Undoes the last executed command.
*/
public class UndoCommand extends Command {

public static final String COMMAND_WORD = "undo";
public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Undoes the latest command called.\n"
+ "Example: " + COMMAND_WORD;
public static final String MESSAGE_SUCCESS = "Command undone: \n%1$s";
public static final String MESSAGE_EMPTY_UNDO_STACK = "There is no command to undo";

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
EventHistory commandHistory = EventHistory.getInstance();

if (commandHistory.isUndoStackEmpty()) {
throw new CommandException(MESSAGE_EMPTY_UNDO_STACK);
}

Event eventToUndo = commandHistory.undo();
eventToUndo.undo(model);

return new CommandResult(String.format(MESSAGE_SUCCESS, eventToUndo));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package seedu.exercise.logic.commands;

/**
* Represents a command that can be undone.
*/
public interface UndoableCommand {
}
58 changes: 58 additions & 0 deletions src/main/java/seedu/exercise/logic/commands/history/AddEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package seedu.exercise.logic.commands.history;

import seedu.exercise.model.Model;
import seedu.exercise.model.exercise.Exercise;

/**
* Represents a particular add event that can be redone or or undone.
*/
public class AddEvent implements Event {

private static final String EVENT_DESCRIPTION = "Add exercise: %1$s";

/**
* The exercise that has been added during the event.
*/
private final Exercise exercise;

/**
* Creates an AddEvent to store the particular event of an exercise being added to the exercise book.
*
* @param exercise the exercise that has been added in this instance of AddEvent.
*/
AddEvent(Exercise exercise) {
this.exercise = exercise;
}

@Override
public void undo(Model model) {
model.deleteExercise(exercise);
}

@Override
public void redo(Model model) {
model.addExercise(exercise);
}

/**
* Returns the exercise that was added.
*
* @return exercise that is passed into constructor of AddEvent
*/
public Exercise getExercise() {
return exercise;
}

@Override
public String toString() {
return String.format(EVENT_DESCRIPTION, exercise);
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof AddEvent // instanceof handles nulls
&& exercise.equals(((AddEvent) other).getExercise()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package seedu.exercise.logic.commands.history;

import seedu.exercise.model.Model;
import seedu.exercise.model.exercise.Exercise;

/**
* Represents a particular delete event that can be redone or or undone.
*/
public class DeleteEvent implements Event {

private static final String EVENT_DESCRIPTION = "Delete exercise: %1$s";

/**
* The exercise that has been deleted during the event.
*/
private final Exercise exercise;

/**
* Creates a DeleteEvent to store the particular event of an exercise being deleted from the exercise book.
*
* @param exercise the exercise that has been deleted in this instance of DeleteEvent.
*/
DeleteEvent(Exercise exercise) {
this.exercise = exercise;
}

@Override
public void undo(Model model) {
model.addExercise(exercise);
}

@Override
public void redo(Model model) {
model.deleteExercise(exercise);
}

/**
* Returns the exercise that was deleted.
*
* @return exercise that is passed into constructor of DeleteEvent
*/
public Exercise getExercise() {
return exercise;
}

@Override
public String toString() {
return String.format(EVENT_DESCRIPTION, exercise);
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof DeleteEvent // instanceof handles nulls
&& exercise.equals(((DeleteEvent) other).getExercise()));
}

}
23 changes: 23 additions & 0 deletions src/main/java/seedu/exercise/logic/commands/history/Event.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package seedu.exercise.logic.commands.history;

import seedu.exercise.model.Model;

/**
* Represents an Event that can be undone or redone.
*/
public interface Event {

/**
* Executes the reverse of the event.
*
* @param model {@code Model} which the command should operate on.
*/
void undo(Model model);

/**
* Executes the event again.
*
* @param model {@code Model} which the command should operate on.
*/
void redo(Model model);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package seedu.exercise.logic.commands.history;

import seedu.exercise.logic.commands.AddCommand;
import seedu.exercise.logic.commands.DeleteCommand;
import seedu.exercise.logic.commands.UndoableCommand;
import seedu.exercise.model.exercise.Exercise;

/**
* A utility class to generate specific Event objects depending on requirements.
*/
public class EventFactory {

/**
* Generate an Event object that can execute the behaviour of a given Command as well
* as its opposite behaviour.
*
* @param command a command to be represented with using an Event object
* @return an Event that can be undone or redone
*/
static Event commandToEvent(UndoableCommand command) {
if (command instanceof AddCommand) {
Exercise exercise = ((AddCommand) command).getExercise();
return new AddEvent(exercise);

} else if (command instanceof DeleteCommand) {
Exercise exercise = ((DeleteCommand) command).getExercise();
return new DeleteEvent(exercise);

} else {
return null;
}
}

}
Loading

0 comments on commit fa5d182

Please sign in to comment.