diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 204a91bde68..0d9269745be 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -75,7 +75,7 @@ The bulk of the app's work is done by the following four components:
The *Sequence
Diagram* below shows how the components interact with each other for the scenario where the user issues the
-command `delete 1`.
+command `delete NRIC`.
@@ -96,8 +96,7 @@ The sections below give more details of each component.
### UI component
-The **API
-** of this component is specified
+The **API** of this component is specified
in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java)
![Structure of the UI Component](images/UiClassDiagram.png)
@@ -122,8 +121,7 @@ The `UI` component,
### Logic component
-**API
-** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
+**API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
Here's a (partial) class diagram of the `Logic` component:
@@ -161,8 +159,7 @@ How the parsing works:
### Model component
-**API
-** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
+**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
@@ -186,8 +183,7 @@ The `Model` component,
### Storage component
-**API
-** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)
+**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)
@@ -374,52 +370,49 @@ The following sequence diagram shows how the New Appointment works:
![AddPatientSequenceDiagram](images/AddPatientSequenceDiagram.png) //change this
-### \[Proposed\] Undo/redo feature
+### Undo/redo feature
-#### Proposed Implementation
-
-The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo
-history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the
-following operations:
+#### Implementation
-* `VersionedAddressBook#commit()`— Saves the current address book state in its history.
-* `VersionedAddressBook#undo()`— Restores the previous address book state from its history.
-* `VersionedAddressBook#redo()`— Restores a previously undone address book state from its history.
+The proposed undo/redo mechanism is facilitated by two ArrayLists of AddressBooks stored in the Model Manager class,
+which are the redoList and the undoList. Each time an action is performed, the two lists are updated accordingly
+by the following three methods:
-These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()`
-and `Model#redoAddressBook()` respectively.
+* `Model#updateBackup()`— Saves the current address book state in its history.
+* `Model#undo()`— Restores the previous address book state by retrieving it from the undoList.
+* `Model#redo()`— Restores a previously undone address book state by retrieving it from the redoList.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
-Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the
-initial address book state, and the `currentStatePointer` pointing to that single address book state.
+Step 1. The user launches the application for the first time. The undoList and RedoList will both be initialised as
+empty ArrayLists, and the `addressBook` instance, `ab0`, stores the current AddressBook.
![UndoRedoState0](images/UndoRedoState0.png)
-Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command
-calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes
-to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book
-state.
+Step 2. The user executes `delete NRIC` command to delete a person in the address book. The `delete` command
+calls `Model#updateBackup()`, causing the current `addressBook` instance, `ab0`, to be added to the undoList while the
+model now stores the updated address book with the deleted person, `ab1`, as the new `addressBook` instance.
![UndoRedoState1](images/UndoRedoState1.png)
-Step 3. The user executes `add n/David …` to add a new person. The `add` command also
-calls `Model#commitAddressBook()`, causing another modified address book state to be saved into
-the `addressBookStateList`.
+Step 3. The user executes `add-patient n/David …` to add a new patient. The `add` command also
+calls `Model#updateBackup()`, causing another modified address book state to be saved into undoList, `ab1`, and the
+current `addressBook` instance to be updated to the new `ab2`.
![UndoRedoState2](images/UndoRedoState2.png)
-
:information_source: **Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`.
+
:information_source: **Note:** If a command fails its execution, it will not call `Model#updateBackup()`, so the address book state will not be saved into the undoList.
Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing
-the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer`
-once to the left, pointing it to the previous address book state, and restores the address book to that state.
+the `undo` command. The `undo` command will call `Model#undo()`, which will add the current `addressBook` instance,
+`ab2` to redoList, as well as removing the most recently added AddressBook, `ab1`, from the undoList and setting it as
+the new `addressBook` instance.
![UndoRedoState3](images/UndoRedoState3.png)
-
:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather
+
:information_source: **Note:** If the undoList is empty, then there are no previous AddressBook states to restore. The `undo` command checks if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
@@ -432,10 +425,10 @@ The following sequence diagram shows how the undo operation works:
-The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once
-to the right, pointing to the previously undone state, and restores the address book to that state.
+The `redo` command does the opposite — it calls `Model#redo()`, which restores the addressBook to its previous state
+before the `undo` command.
-
:information_source: **Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
+
:information_source: **Note:** If the redoList is empty, then there are no undone AddressBook states to restore. The `redo` command checks if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
@@ -445,13 +438,19 @@ Thus, the `addressBookStateList` remains unchanged.
![UndoRedoState4](images/UndoRedoState4.png)
-Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not
-pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be
-purged. Reason: It no longer makes sense to redo the `add n/David …` command. This is the behavior that most modern
-desktop applications follow.
+Step 6. The user then decides that the person he added in step 3 was not a mistake, and executes the command `redo`.
+The `redo` command will call `Model#redo()`, which will add the current `addressBook` instance,
+`ab1` to undoList, as well as removing the most recently added AddressBook, `ab2`, from the redoList and setting it as
+the new `addressBook` instance. Notice that the current state has been restored to the state at the end of step 3.
![UndoRedoState5](images/UndoRedoState5.png)
+
:information_source: **Note:** If the number of AddressBook states stored
+in the undoList reaches 5, any additional commands that makes changes to the address book will lead to the least
+recently added state in the undoList to be purged as a redundant state and will no longer be accessible via `undo`.
+
+
+
The following activity diagram summarizes what happens when a user executes a new command:
![](images/CommitActivityDiagram.png)
diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml
index 48b6cc4333c..9e87b04772b 100644
--- a/docs/diagrams/ArchitectureSequenceDiagram.puml
+++ b/docs/diagrams/ArchitectureSequenceDiagram.puml
@@ -8,10 +8,10 @@ Participant ":Logic" as logic LOGIC_COLOR
Participant ":Model" as model MODEL_COLOR
Participant ":Storage" as storage STORAGE_COLOR
-user -[USER_COLOR]> ui : "delete 1"
+user -[USER_COLOR]> ui : "delete NRIC"
activate ui UI_COLOR
-ui -[UI_COLOR]> logic : execute("delete 1")
+ui -[UI_COLOR]> logic : execute("delete NRIC")
activate logic LOGIC_COLOR
logic -[LOGIC_COLOR]> model : deletePerson(p)
diff --git a/docs/diagrams/UndoRedoState0.puml b/docs/diagrams/UndoRedoState0.puml
index 43a45903ac9..372107bbc20 100644
--- a/docs/diagrams/UndoRedoState0.puml
+++ b/docs/diagrams/UndoRedoState0.puml
@@ -6,16 +6,13 @@ skinparam ClassBackgroundColor #FFFFAA
title Initial state
-package States {
- class State1 as "
ab0:AddressBook"
- class State2 as "
ab1:AddressBook"
- class State3 as "
ab2:AddressBook"
+package UndoList {
}
-State1 -[hidden]right-> State2
-State2 -[hidden]right-> State3
-hide State2
-hide State3
-class Pointer as "Current State" #FFFFFF
-Pointer -up-> State1
+package RedoList {
+}
+
+package CurrentState {
+ class State0 as "
ab0:AddressBook"
+}
@end
diff --git a/docs/diagrams/UndoRedoState1.puml b/docs/diagrams/UndoRedoState1.puml
index 5a41e9e1651..247d2678621 100644
--- a/docs/diagrams/UndoRedoState1.puml
+++ b/docs/diagrams/UndoRedoState1.puml
@@ -6,18 +6,14 @@ skinparam ClassBackgroundColor #FFFFAA
title After command "delete 5"
-package States <
> {
- class State1 as "ab0:AddressBook"
- class State2 as "ab1:AddressBook"
- class State3 as "ab2:AddressBook"
+package UndoList {
+ class State0 as "ab0:AddressBook"
}
-State1 -[hidden]right-> State2
-State2 -[hidden]right-> State3
-
-hide State3
-
-class Pointer as "Current State" #FFFFFF
+package RedoList {
+}
-Pointer -up-> State2
+package CurrentState {
+ class State1 as "ab1:AddressBook"
+}
@end
diff --git a/docs/diagrams/UndoRedoState2.puml b/docs/diagrams/UndoRedoState2.puml
index ad32fce1b0b..910f01891fe 100644
--- a/docs/diagrams/UndoRedoState2.puml
+++ b/docs/diagrams/UndoRedoState2.puml
@@ -6,16 +6,15 @@ skinparam ClassBackgroundColor #FFFFAA
title After command "add n/David"
-package States <> {
- class State1 as "ab0:AddressBook"
- class State2 as "ab1:AddressBook"
- class State3 as "ab2:AddressBook"
+package UndoList {
+ class State1 as "ab1:AddressBook"
+ class State0 as "ab0:AddressBook"
}
-State1 -[hidden]right-> State2
-State2 -[hidden]right-> State3
-
-class Pointer as "Current State" #FFFFFF
+package RedoList {
+}
-Pointer -up-> State3
+package CurrentState {
+ class State2 as "ab2:AddressBook"
+}
@end
diff --git a/docs/diagrams/UndoRedoState3.puml b/docs/diagrams/UndoRedoState3.puml
index 9187a690036..9bf01d8611d 100644
--- a/docs/diagrams/UndoRedoState3.puml
+++ b/docs/diagrams/UndoRedoState3.puml
@@ -6,16 +6,15 @@ skinparam ClassBackgroundColor #FFFFAA
title After command "undo"
-package States <> {
- class State1 as "ab0:AddressBook"
- class State2 as "ab1:AddressBook"
- class State3 as "ab2:AddressBook"
+package RedoList {
+ class State2 as "ab2:AddressBook"
}
-State1 -[hidden]right-> State2
-State2 -[hidden]right-> State3
-
-class Pointer as "Current State" #FFFFFF
+package UndoList {
+ class State0 as "ab0:AddressBook"
+}
-Pointer -up-> State2
+package CurrentState {
+ class State1 as "ab1:AddressBook"
+}
@end
diff --git a/docs/diagrams/UndoRedoState4.puml b/docs/diagrams/UndoRedoState4.puml
index 2bc631ffcd0..636cfa22b35 100644
--- a/docs/diagrams/UndoRedoState4.puml
+++ b/docs/diagrams/UndoRedoState4.puml
@@ -6,16 +6,15 @@ skinparam ClassBackgroundColor #FFFFAA
title After command "list"
-package States <> {
- class State1 as "ab0:AddressBook"
- class State2 as "ab1:AddressBook"
- class State3 as "ab2:AddressBook"
+package RedoList {
+ class State2 as "ab2:AddressBook"
}
-State1 -[hidden]right-> State2
-State2 -[hidden]right-> State3
-
-class Pointer as "Current State" #FFFFFF
+package UndoList {
+ class State0 as "ab0:AddressBook"
+}
-Pointer -up-> State2
+package CurrentState {
+ class State1 as "ab1:AddressBook"
+}
@end
diff --git a/docs/diagrams/UndoRedoState5.puml b/docs/diagrams/UndoRedoState5.puml
index e77b04104aa..5f32dd86374 100644
--- a/docs/diagrams/UndoRedoState5.puml
+++ b/docs/diagrams/UndoRedoState5.puml
@@ -6,17 +6,15 @@ skinparam ClassBackgroundColor #FFFFAA
title After command "clear"
-package States <> {
- class State1 as "ab0:AddressBook"
- class State2 as "ab1:AddressBook"
- class State3 as "ab3:AddressBook"
+package UndoList {
+ class State1 as "ab1:AddressBook"
+ class State0 as "ab0:AddressBook"
}
-State1 -[hidden]right-> State2
-State2 -[hidden]right-> State3
-
-class Pointer as "Current State" #FFFFFF
+package RedoList {
+}
-Pointer -up-> State3
-note right on link: State ab2 deleted.
+package CurrentState {
+ class State2 as "ab2:AddressBook"
+}
@end
diff --git a/docs/diagrams/UndoSequenceDiagram.puml b/docs/diagrams/UndoSequenceDiagram.puml
index 87ff3e9237e..84b2bd46b7b 100644
--- a/docs/diagrams/UndoSequenceDiagram.puml
+++ b/docs/diagrams/UndoSequenceDiagram.puml
@@ -10,7 +10,10 @@ end box
box Model MODEL_COLOR_T1
participant ":Model" as Model MODEL_COLOR
-participant ":VersionedAddressBook" as VersionedAddressBook MODEL_COLOR
+participant ":AddressBook" as NewAddressBook MODEL_COLOR
+participant "addressBook:AddressBook" as AddressBook MODEL_COLOR
+participant "redoList:ArrayList" as RedoList MODEL_COLOR
+participant "undoList:ArrayList" as UndoList MODEL_COLOR
end box
[-> LogicManager : execute(undo)
activate LogicManager
@@ -31,15 +34,32 @@ deactivate AddressBookParser
LogicManager -> UndoCommand : execute()
activate UndoCommand
-UndoCommand -> Model : undoAddressBook()
+UndoCommand -> Model : undo()
activate Model
-Model -> VersionedAddressBook : undo()
-activate VersionedAddressBook
+create NewAddressBook
+Model -> NewAddressBook : new AddressBook(addressBook)
+activate NewAddressBook
-VersionedAddressBook -> VersionedAddressBook :resetData(ReadOnlyAddressBook)
-VersionedAddressBook --> Model :
-deactivate VersionedAddressBook
+NewAddressBook --> Model : newAddressBook
+deactivate NewAddressBook
+
+Model -> RedoList : add()
+activate RedoList
+
+RedoList -> RedoList : add(newAddressBook)
+RedoList --> Model
+deactivate RedoList
+
+Model -> UndoList : remove(index)
+activate UndoList
+UndoList --> Model : d
+deactivate
+
+Model -> AddressBook : resetData(d)
+activate AddressBook
+AddressBook --> Model
+deactivate AddressBook
Model --> UndoCommand
deactivate Model
diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png
index 37ad06a2803..ee56e5ee8d3 100644
Binary files a/docs/images/ArchitectureSequenceDiagram.png and b/docs/images/ArchitectureSequenceDiagram.png differ
diff --git a/docs/images/UndoRedoState0.png b/docs/images/UndoRedoState0.png
index c5f91b58533..89b3822cd25 100644
Binary files a/docs/images/UndoRedoState0.png and b/docs/images/UndoRedoState0.png differ
diff --git a/docs/images/UndoRedoState1.png b/docs/images/UndoRedoState1.png
index 2d3ad09c047..3e4d39e8ed9 100644
Binary files a/docs/images/UndoRedoState1.png and b/docs/images/UndoRedoState1.png differ
diff --git a/docs/images/UndoRedoState2.png b/docs/images/UndoRedoState2.png
index 20853694e03..3d8315116fa 100644
Binary files a/docs/images/UndoRedoState2.png and b/docs/images/UndoRedoState2.png differ
diff --git a/docs/images/UndoRedoState3.png b/docs/images/UndoRedoState3.png
index 1a9551b31be..5738fdc23a3 100644
Binary files a/docs/images/UndoRedoState3.png and b/docs/images/UndoRedoState3.png differ
diff --git a/docs/images/UndoRedoState4.png b/docs/images/UndoRedoState4.png
index 46dfae78c94..d544943620a 100644
Binary files a/docs/images/UndoRedoState4.png and b/docs/images/UndoRedoState4.png differ
diff --git a/docs/images/UndoRedoState5.png b/docs/images/UndoRedoState5.png
index f45889b5fdf..630f8663adb 100644
Binary files a/docs/images/UndoRedoState5.png and b/docs/images/UndoRedoState5.png differ
diff --git a/docs/images/UndoSequenceDiagram.png b/docs/images/UndoSequenceDiagram.png
index c7a7e637266..e35b7ae97b5 100644
Binary files a/docs/images/UndoSequenceDiagram.png and b/docs/images/UndoSequenceDiagram.png differ