Skip to content

Commit 3dea8bd

Browse files
authored
Merge pull request #166 from AY2021S1-CS2103T-T12-1/branch-docs-saad
Do UG and DG for Undo/Redo implementation, and fix a few other smaller issues
2 parents 0a5bc98 + 0c53cf9 commit 3dea8bd

27 files changed

+280
-186
lines changed

docs/DeveloperGuide.md

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Structure of Delivery Object
141141

142142
The `Storage` component,
143143
* can save `UserPref` objects in json format and read it back.
144-
* can save the inventory book data and delivery book in json format and read it back.
144+
* can save the inventoryBook/deliveryBook data in json format and read it back.
145145

146146
### Common classes
147147

@@ -164,6 +164,7 @@ method call to return `commandHistory`'s 2nd last command instead of the last co
164164
With `addToHistory(String command)`, `previousCommand()`, `nextCommand()` and `currentCommand()` implemented, a simple `setOnKeyPressed` under `CommandBox` class which checks
165165
for user's input of arrow up (which calls previousCommand()) and arrow down (which calls nextCommand()) would suffice for GUI implementation.
166166

167+
167168
### Finding Items and Delivery
168169
OneShelf is capable of storing many items and deliveries. Therefore, there is an utmost importance to have the ability to be able to find item and delivery based on different fields. There could also be many similar item and this will definitely benefit the user to find it quickly. <br>
169170

@@ -183,41 +184,44 @@ Below is a sequence diagram of the above
183184

184185
![ItemFindCommandSequenceDiagram](images/ItemFindCommandSequenceDiagram.png)
185186

186-
### \[Proposed\] Undo/redo feature
187187

188-
#### Proposed Implementation
188+
### Undo/Redo Command
189+
190+
Each `Model` internally stores its undo and redo history as a (for `DeliveryModel`) `deliveryBookStateList` and `deliveryBookStatePointer`. There are corresponding analogs for `InventoryModel`.
191+
Additionally, the following commands are implemented by `ModelsManager`.
189192

190-
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:
193+
* `ModelsManager#commit()` — Saves the current book states of all the `Model`s it contains in their history.
194+
* `ModelsManager#undo()` — Restores the previous book states from each `Model` from their history.
195+
* `ModelsManager#redo()` — Restores all previously undone book states from every `Model`'s history.
191196

192-
* `VersionedAddressBook#commit()` — Saves the current address book state in its history.
193-
* `VersionedAddressBook#undo()` — Restores the previous address book state from its history.
194-
* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history.
197+
These operations are exposed in the `Models` interface as `Models#commit()`, `Models#undo()` and `Models#redo()` respectively.
195198

196-
These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively.
199+
The `ModelsManager` class calls `Model#commit()`, `Model#undo()`, and `Model#redo` on each of the models it contains, which then handle the respective tasks.
197200

198201
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
199202

200-
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.
203+
Step 1. The user launches the application for the first time. Each `Model` will be initialized with its initial state, and the pointer pointing to their respective book's state.
201204

202205
![UndoRedoState0](images/UndoRedoState0.png)
203206

204-
Step 2. The user executes `delete 5` command to delete the 5th item 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.
207+
Step 2. The user executes `delete-i 5` command to delete the 5th item in the inventory book. The `delete-i` command calls `Models#commit()`, causing the modified state of the inventory and delivery books after the `delete-i 5` command executes to be saved in the `inventoryBookStateList`, `deliveryBookStateList`,
208+
and the `inventoryBookStatePointer`, `deliveryBookStatePointer` are shifted to the newly inserted books state.
205209

206210
![UndoRedoState1](images/UndoRedoState1.png)
207211

208-
Step 3. The user executes `add n/David …​` to add a new item. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`.
212+
Step 3. The user executes `add-d n/David p/12345678 …​` to add a new Delivery. The `add-d` command also calls `Models#commit()`, causing another set of modified book states to be saved into the `inventoryBookStateList` and `deliveryBookStateList`.
209213

210214
![UndoRedoState2](images/UndoRedoState2.png)
211215

212-
<div markdown="span" class="alert alert-info">: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`.
216+
<div markdown="span" class="alert alert-info">:information_source: **Note:** If a command fails its execution, it will not call `Models#commit()`, so the states will not be saved into the `inventoryBookStateList` and `deliveryBookStateList`.
213217

214218
</div>
215219

216-
Step 4. The user now decides that adding the item 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.
220+
Step 4. The user now decides that adding the delivery was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Models#undo()`, which will shift the `deliveryBookStatePointer` and `inventoryBookStatePointer` once to the left, pointing it to the previous states, and restores the inventoryBook/deliveryBook to those states.
217221

218222
![UndoRedoState3](images/UndoRedoState3.png)
219223

220-
<div markdown="span" class="alert alert-info">: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
224+
<div markdown="span" class="alert alert-info">:information_source: **Note:** If the current state pointers are at index 0, pointing to the initial state, then there are no previous books states to restore. The `undo` command uses `InventoryModel#canUndo()` and `DeliveryModel#canUndo()` to check if this is the case. If so, it will return an error to the user rather
221225
than attempting to perform the undo.
222226

223227
</div>
@@ -230,17 +234,17 @@ The following sequence diagram shows how the undo operation works:
230234

231235
</div>
232236

233-
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.
237+
The `redo` command does the opposite — it calls `Models#redo()`, which shifts the `inventoryBookStatePointer` and `deliveryBookStatePointer` once to the right, pointing to the previously undone state, and restores the inventoryBook and deliveryBook to that state.
234238

235-
<div markdown="span" class="alert alert-info">: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.
239+
<div markdown="span" class="alert alert-info">:information_source: **Note:** If the current pointers are pointing to the latest state, then there are no undone InventoryBook/DeliveryBook states to restore. The `redo` command uses `InventoryModel#canRedo()` and `DeliveryModel#canRedo()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
236240

237241
</div>
238242

239-
Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged.
243+
Step 5. The user then decides to execute the command `list-i`. Commands that do not modify the inventoryBook and deliveryBook, such as `list-d` and `find-i`, will usually not call `Models#commit()`, `Models#undo()` or `Models#redo()`. Thus, the `inventoryBookStateList` and `deliveryBookStateList` remain unchanged.
240244

241245
![UndoRedoState4](images/UndoRedoState4.png)
242246

243-
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.
247+
Step 6. The user executes `clear-d`, which calls `Models#commit()`. Since the state pointers are not pointing at the end of the respective state lists, all states after the current state will be purged. Reason: It no longer makes sense to redo the `add-d n/David p/12345678 …​` command. This is the behavior that most modern desktop applications follow.
244248

245249
![UndoRedoState5](images/UndoRedoState5.png)
246250

@@ -252,7 +256,7 @@ The following activity diagram summarizes what happens when a user executes a ne
252256

253257
##### Aspect: How undo & redo executes
254258

255-
* **Alternative 1 (current choice):** Saves the entire address book.
259+
* **Alternative 1 (current choice):** Saves the entire state.
256260
* Pros: Easy to implement.
257261
* Cons: May have performance issues in terms of memory usage.
258262

@@ -420,18 +424,17 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
420424
1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed.
421425
2. Should be able to hold up to 1000 items without a noticeable sluggishness in performance for typical usage.
422426
3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
423-
4. Project should not cost any money
424-
5. Should work on 32-bit and 64-bit environments
425-
6. Should not take up more than 50 MB of disk space
426-
7. Should not take up more than 250 MB of RAM
427-
8. Commands should receive a response within 1 second
428-
9. The system is not required to change the physical inventory
429-
10. The system should operate within a local network
430-
11. The data should be secured using a password
431-
12. Users should be able to get fluent with the syntax by their 10th usage
432-
13. The system should not provide functionality that breaks and local laws within a country it is distributed to
433-
14. The system should still be able to function without connection to a network
434-
15. The system should only be used by one user
427+
4. Should work on 32-bit and 64-bit environments.
428+
5. Should not take up more than 50 MB of disk space.
429+
6. Should not take up more than 250 MB of RAM.
430+
7. Add, Delete, List, Undo, Redo, Edit, and Remove Commands should receive a response within 1 second regardless of data size.
431+
8. All other commands should receive a response withing 5 seconds regardless of data size.
432+
9. The data should be secured using a password.
433+
10. Users should be able to get fluent with the syntax by their 10th usage.
434+
11. The system should still be able to function without connection to a network.
435+
12. The system should only be used by one user.
436+
13. Storing 100 states of the models for the Undo and Redo Commands should not take more than 100 KB.
437+
14. Storing 100 states of history of commands the user has entered should not take more than 10 KB.
435438

436439
### Glossary
437440

docs/UserGuide.md

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,22 @@ track of multiple items, OneShelf is for you!
6767

6868

6969
### Viewing help : `help`
70-
Format: `help summary`
71-
Shows a summary of all the possible commands in OneShelf.
7270

7371
Format: `help start`
7472
Shows a guide for user to kick-start their journey in OneShelf.
7573

76-
<<Insert Screenshot in the future to show user what is expected, once GUI of help finalized>>
74+
Alternatives:
75+
* Press `F1` at any point in the usage of the app
76+
* GUI navigation menu at the top left
77+
78+
Format: `help summary`
79+
Shows a summary of all the possible commands in OneShelf.
80+
81+
Alternatives:
82+
* Press `F2` at any point in the usage of the app
83+
* GUI navigation menu at the top left
7784

85+
![Help Summary Screenshot](images/HelpSummaryWindow.png)
7886

7987

8088
### Adding an item: `add-i`
@@ -196,6 +204,27 @@ Exits the program.
196204
Format: `exit`
197205

198206

207+
### Undo last command : `undo`
208+
209+
Undoes the previous command by reverting the current data displayed to the state it was in before the last command was executed.
210+
211+
Format: `undo`
212+
213+
* If there is a previous state available, the current state is reverted to that state
214+
* If the current state is the earliest possible one, it shows a message informing the user that there is nothing more to undo
215+
216+
217+
### Redo last command : `redo`
218+
219+
Redoes the last undone command by reverting the current data displayed to the state it was in before the last undo command was executed.
220+
221+
Format: `redo`
222+
223+
* If there is an undone state available, the current state is reverted to that state
224+
* If the current state is the latest possible one, it shows a message informing the user that there is nothing more to redo
225+
* After any command that changes the state of data (such as add, clear, delete, edit), the new state becomes the latest state
226+
(i.e. the previous undo commands are "forgotten" and `redo` will have no effect)
227+
199228

200229
### Saving the data
201230

@@ -205,11 +234,6 @@ OneShelf data are saved in the hard disk automatically after any command that ch
205234

206235
OneShelf commands are traversable much like Window's command prompt with the arrow up key traversing into previous commands and arrow down key traversing into next commands.
207236

208-
### Undo `[Coming Soon]`
209-
210-
Undo previous command
211-
212-
213237

214238
### Sorting items`[Coming Soon]`
215239

@@ -254,7 +278,14 @@ Notify the user if a certain stock is below threshold
254278

255279
## Command summary
256280

281+
#### General commands summary
257282

283+
| Action | Format, Examples |
284+
|-----------|-----------------------------------------------------------------------------------------------------|
285+
|**Get help to start off** | `help start` or press `F1` or use GUI help menu at the top left |
286+
|**Get help summary** | `help summary` or press `F2` or use GUI help menu at the top left | | |
287+
|**Undo last command** | `undo` |
288+
|**Redo last undone command** | `redo` |
258289

259290
#### Inventory summary
260291

@@ -266,8 +297,7 @@ Notify the user if a certain stock is below threshold
266297
|**Edit Inventory** | `edit-i INDEX [n/NAME] [q/QUANTITY] [s/SUPPLIER] [max/MAX_QUANTITY] [t/TAG]…​`<br> e.g.,`edit 1 n/Chicken q/50` |
267298
|**Find in Inventory** | `find-i PREFIX KEYWORD [MORE_KEYWORDS]`<br> e.g., `find-i n/Chicken Steak` |
268299
|**List Inventory** | `list-i
269-
|**Remove from Inventory** | `remove-i INDEX q/QUANTITY` |
270-
|**Help** | `help` |
300+
|**Remove from Inventory** | `remove-i INDEX q/QUANTITY` | |
271301

272302

273303

docs/diagrams/CommitActivityDiagram.puml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ start
55
'Since the beta syntax does not support placing the condition outside the
66
'diamond we place it as the true branch instead.
77

8-
if () then ([command commits AddressBook])
9-
:Purge redunant states;
10-
:Save AddressBook to
11-
addressBookStateList;
8+
if () then ([command commits Models])
9+
:Purge redundant states;
10+
:Save inventoryBook to inventoryBookStateList
11+
and deliveryBook to DeliveryBookStateList;
1212
else ([else])
1313
endif
1414
stop

docs/diagrams/UndoRedoState0.puml

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,24 @@ skinparam ClassBorderColor #000000
66
title Initial state
77

88
package States {
9-
class State1 as "__ab0:AddressBook__"
10-
class State2 as "__ab1:AddressBook__"
11-
class State3 as "__ab2:AddressBook__"
9+
class InventoryState1 as "__ib0:InventoryBook__"
10+
class DeliveryState1 as "__db0:DeliveryBook__"
11+
class InventoryState2 as "__ib1:InventoryBook__"
12+
class DeliveryState2 as "__db1:DeliveryBook__"
13+
class InventoryState3 as "__ib2:InventoryBook__"
14+
class DeliveryState3 as "__db2:DeliveryBook__"
15+
class Pointer as "Current State" #FFFFF
1216
}
13-
State1 -[hidden]right-> State2
14-
State2 -[hidden]right-> State3
15-
hide State2
16-
hide State3
17+
InventoryState1 -[hidden]right-> InventoryState2
18+
InventoryState2 -[hidden]right-> InventoryState3
19+
hide InventoryState2
20+
hide InventoryState3
1721

18-
class Pointer as "Current State" #FFFFF
19-
Pointer -up-> State1
22+
DeliveryState1 -[hidden]right-> DeliveryState2
23+
DeliveryState2 -[hidden]right-> DeliveryState3
24+
hide DeliveryState2
25+
hide DeliveryState3
26+
27+
Pointer -up-> InventoryState1
28+
Pointer -down-> DeliveryState1
2029
@end

docs/diagrams/UndoRedoState1.puml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,25 @@
33
skinparam ClassFontColor #000000
44
skinparam ClassBorderColor #000000
55

6-
title After command "delete 5"
6+
title After command "delete-i 5"
77

8-
package States <<rectangle>> {
9-
class State1 as "__ab0:AddressBook__"
10-
class State2 as "__ab1:AddressBook__"
11-
class State3 as "__ab2:AddressBook__"
8+
package States {
9+
class InventoryState1 as "__ib0:InventoryBook__"
10+
class DeliveryState1 as "__db0:DeliveryBook__"
11+
class InventoryState2 as "__ib1:InventoryBook__"
12+
class DeliveryState2 as "__db1:DeliveryBook__"
13+
class InventoryState3 as "__ib2:InventoryBook__"
14+
class DeliveryState3 as "__db2:DeliveryBook__"
15+
class Pointer as "Current State" #FFFFF
1216
}
17+
InventoryState1 -[hidden]right-> InventoryState2
18+
InventoryState2 -[hidden]right-> InventoryState3
19+
hide InventoryState3
1320

14-
State1 -[hidden]right-> State2
15-
State2 -[hidden]right-> State3
21+
DeliveryState1 -[hidden]right-> DeliveryState2
22+
DeliveryState2 -[hidden]right-> DeliveryState3
23+
hide DeliveryState3
1624

17-
hide State3
18-
19-
class Pointer as "Current State" #FFFFF
20-
21-
Pointer -up-> State2
25+
Pointer -up-> InventoryState2
26+
Pointer -down-> DeliveryState2
2227
@end

docs/diagrams/UndoRedoState2.puml

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,24 @@
33
skinparam ClassFontColor #000000
44
skinparam ClassBorderColor #000000
55

6-
title After command "add n/David"
6+
title After command "add-d n/David p/12345678 …​"
77

8-
package States <<rectangle>> {
9-
class State1 as "__ab0:AddressBook__"
10-
class State2 as "__ab1:AddressBook__"
11-
class State3 as "__ab2:AddressBook__"
8+
package States {
9+
class InventoryState1 as "__ib0:InventoryBook__"
10+
class DeliveryState1 as "__db0:DeliveryBook__"
11+
class InventoryState2 as "__ib1:InventoryBook__"
12+
class DeliveryState2 as "__db1:DeliveryBook__"
13+
class InventoryState3 as "__ib2:InventoryBook__"
14+
class DeliveryState3 as "__db2:DeliveryBook__"
15+
class Pointer as "Current State" #FFFFF
1216
}
17+
InventoryState1 -[hidden]right-> InventoryState2
18+
InventoryState2 -[hidden]right-> InventoryState3
1319

14-
State1 -[hidden]right-> State2
15-
State2 -[hidden]right-> State3
20+
DeliveryState1 -[hidden]right-> DeliveryState2
21+
DeliveryState2 -[hidden]right-> DeliveryState3
1622

17-
class Pointer as "Current State" #FFFFF
23+
Pointer -up-> InventoryState3
24+
Pointer -down-> DeliveryState3
1825

19-
Pointer -up-> State3
2026
@end

0 commit comments

Comments
 (0)