Skip to content

Commit

Permalink
Merge pull request AY2425S1-CS2103T-W10-2#193 from rxchell/update-gen…
Browse files Browse the repository at this point in the history
…eral-commands

Update DG: General commands
  • Loading branch information
zaidansani authored Nov 2, 2024
2 parents 849a6dc + bdd4eb5 commit 3099bec
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 420 deletions.
169 changes: 26 additions & 143 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,37 +323,28 @@ The activity diagram shows the general sequence of steps when a user interacts w
<br>

## Implementation of general features
General commands include the `exit` and `help` commands.

### Exit feature
#### Implementation
When a user types an `exit` command, the DocTrack application will exit.
The sequence diagram shows how a general command (`ExitCommand` or `HelpCommand`) is executed:
<puml src="diagrams/GeneralCommandsSequenceDiagram.puml" width="600"></puml>

The sequence diagram shows how an `exit` command is executed:
<puml src="diagrams/ExitSequenceDiagram.puml" width="600"></puml>
**Step 1.** The user types an `xyz` command (`exit` or `help`) in the `CommandBox`, which is then passed to the `LogicManager`.

**Step 1.** The user types the `exit` command in the `CommandBox`, which is then passed to the `LogicManager`.
**Step 2.** The `LogicManager` calls the `AddressBookParser::parseCommand` method to parse the `xyz` command.

**Step 2.** The `LogicManager` calls the `AddressBookParser::parseCommand` method to parse the `exit` command.
**Step 3.** The `AddressBookParser` creates an `XYZCommand` object, which is returned to the
`LogicManager`. The `XYZCommand` object can be an `ExitCommand` or a `HelpCommand`.

**Step 3.** The `AddressBookParser` creates an `ExitCommand` object, which is returned to the `LogicManager`.

**Step 4.** The `LogicManager` calls the `ExitCommand::execute` method, which creates a new `CommandResult` object.
**Step 4.** The `LogicManager` calls the `XYZCommand::execute` method, which creates a new `CommandResult`
object.

**Step 5.** The `CommandResult` object is returned to the `LogicManager`.

<br>

#### Design considerations

**Aspect: How to handle unsaved data on exit:**

* **Alternative 1 (current choice):** Automatically save all changes on exit.
* Pros: Simplifies the exit process for the user. Ensures no data is lost.
* Cons: May be slow if there are many changes to save.


* **Alternative 2:** Prompt the user to save changes before exiting.
* Pros: Gives the user more control over the saving process.
* Cons: May be annoying for users who do not want an additional step to save changes.
### Exit feature
#### Implementation
When a user types an `exit` command, the DocTrack application will exit.

<br>

Expand All @@ -362,22 +353,6 @@ The sequence diagram shows how an `exit` command is executed:

When a user types a `help` command, the DocTrack application will display a `HelpWindow`.

The sequence diagram shows how a `help` command is executed:

<puml src="diagrams/HelpSequenceDiagram.puml" width="600"></puml>

**Step 1.** The user types the `help` command in the `CommandBox`, which is then passed to the `LogicManager`.

**Step 2.** The `LogicManager` calls the `AddressBookParser::parseCommand` method to parse the `help` command.

**Step 3.** The `AddressBookParser` creates a `HelpCommand` object, which is returned to the `LogicManager`.

**Step 4.** The `LogicManager` calls the `HelpCommand::execute` method, which creates a new
`CommandResult` object.

**Step 5.** The `CommandResult` object is returned to the `LogicManager`.


#### Design considerations

**Aspect: How to display help information:**
Expand All @@ -392,111 +367,7 @@ The sequence diagram shows how a `help` command is executed:

<br>

---

<br>

## Proposed features

### \[Proposed\] 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:

* `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.

These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively.

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.

<puml src="diagrams/UndoRedoState0.puml" alt="UndoRedoState0" />

**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.

<puml src="diagrams/UndoRedoState1.puml" alt="UndoRedoState1" />

**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`.

<puml src="diagrams/UndoRedoState2.puml" alt="UndoRedoState2" />

<box type="info" seamless>

**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`.

</box>

**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.

<puml src="diagrams/UndoRedoState3.puml" alt="UndoRedoState3" />


<box type="info" seamless>

**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
than attempting to perform the undo.

</box>

The following sequence diagram shows how an undo operation goes through the `Logic` component:

<puml src="diagrams/UndoSequenceDiagram-Logic.puml" alt="UndoSequenceDiagram-Logic" />

<box type="info" seamless>

**Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.

</box>

Similarly, how an undo operation goes through the `Model` component is shown below:

<puml src="diagrams/UndoSequenceDiagram-Model.puml" alt="UndoSequenceDiagram-Model" />

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.

<box type="info" seamless>

**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.

</box>

**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.

<puml src="diagrams/UndoRedoState4.puml" alt="UndoRedoState4" />

**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.

<puml src="diagrams/UndoRedoState5.puml" alt="UndoRedoState5" />

Steps 1 to 6 will similarly be implemented for the `Appointment` data. The `VersionedAppointmentBook` will
be initialized with the initial appointment book state, and the `currentStatePointer` pointing to that
single appointment book state. The `commit`, `undo`, and `redo` operations for `VersionedAppointmentBook`
will be implemented in the same way as the `VersionedAddressBook`.

The following activity diagram summarizes what happens when a user executes a new command:

<puml src="diagrams/CommitActivityDiagram.puml" width="550" />

#### Design considerations:

**Aspect: How undo & redo executes:**

* **Alternative 1 (current choice):** Saves the entire address book.
* Pros: Easy to implement.
* Cons: May have performance issues in terms of memory usage.

* **Alternative 2:** Individual command knows how to undo/redo by
itself.
* Pros: Will use less memory (e.g. for `delete`, just save the person being deleted).
* Cons: We must ensure that the implementation of each individual command are correct.

<br>

--------------------------------------------------------------------------------------------------------------------
---

<br>

Expand Down Expand Up @@ -526,6 +397,18 @@ For `Appointment`, the fields `Sickness` and `Medicine` are optional. Hence, if
is not specified, it would be represented as `"null"`, in the `appointmentbook.json` file.
</box>

#### Design Considerations
**Aspect: When the data is updated in the `.json` file:**

* **Alternative 1 (current choice):** Automatically save all changes after any command that changes the data.
* Pros: Simplifies the process for the user, without needing to save manually.
* Cons: May be slow if there are many changes to save.


* **Alternative 2:** Prompt the user to save changes before exiting.
* Pros: Gives the user more control over the saving process.
* Cons: May be annoying for users who do not want an additional step to save changes.

<br>

--------------------------------------------------------------------------------------------------------------------
Expand Down
22 changes: 0 additions & 22 deletions docs/diagrams/CommitActivityDiagram.puml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,40 @@ skinparam ArrowFontStyle plain
box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
participant "e:ExitCommand" as ExitCommand LOGIC_COLOR
participant "e:XYZCommand" as XYZCommand LOGIC_COLOR
participant "r:CommandResult" as CommandResult LOGIC_COLOR
end box

[-> LogicManager : execute("exit")
[-> LogicManager : execute("xyz")
activate LogicManager

LogicManager -> AddressBookParser : parseCommand("exit")
LogicManager -> AddressBookParser : parseCommand("xyz")
activate AddressBookParser

create ExitCommand
AddressBookParser -> ExitCommand
activate ExitCommand
create XYZCommand
AddressBookParser -> XYZCommand
activate XYZCommand

ExitCommand --> AddressBookParser
deactivate ExitCommand
note right of XYZCommand: XYZCommand = \nExitCommand, HelpCommand

XYZCommand --> AddressBookParser
deactivate XYZCommand

AddressBookParser --> LogicManager : e
deactivate AddressBookParser

LogicManager -> ExitCommand : execute(e)
activate ExitCommand
LogicManager -> XYZCommand : execute(e)
activate XYZCommand

create CommandResult
ExitCommand -> CommandResult
XYZCommand -> CommandResult
activate CommandResult

CommandResult --> ExitCommand
CommandResult --> XYZCommand
deactivate CommandResult

ExitCommand --> LogicManager : r
deactivate ExitCommand
XYZCommand --> LogicManager : r
deactivate XYZCommand

[<--LogicManager
deactivate LogicManager
Expand Down
43 changes: 0 additions & 43 deletions docs/diagrams/HelpSequenceDiagram.puml

This file was deleted.

21 changes: 0 additions & 21 deletions docs/diagrams/UndoRedoState0.puml

This file was deleted.

23 changes: 0 additions & 23 deletions docs/diagrams/UndoRedoState1.puml

This file was deleted.

21 changes: 0 additions & 21 deletions docs/diagrams/UndoRedoState2.puml

This file was deleted.

Loading

0 comments on commit 3099bec

Please sign in to comment.