-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommand.ts
111 lines (99 loc) · 2.55 KB
/
command.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* The `Command` interface defines the contract for executing, undoing, and drawing commands.
*/
interface Command {
execute: () => void;
undo: () => void;
redo: () => void;
// We usually need a loop in graphical applications and then the draw method is needed.
draw: () => void;
}
/**
* The `Invoker` class is responsible for executing, drawing, and undoing `Command` objects.
*/
class Invoker {
private drawingHistory: Command[];
private undoHistory: Command[];
constructor() {
this.drawingHistory = [];
this.undoHistory = [];
}
/**
* Executes the provided `Command` object, and adds it to the command history.
*/
execute(command: Command): void {
command.execute();
this.drawingHistory.push(command);
}
/**
* Draws all the commands in the command history.
*/
draw() {
for (const command of this.drawingHistory) {
command.draw();
}
}
/**
* Undoes the most recent command executed by the Invoker.
*/
undo() {
if (this.drawingHistory.length > 0) {
const removedCommand = this.drawingHistory.pop();
if (removedCommand) {
removedCommand.undo();
this.undoHistory.push(removedCommand);
}
}
}
redo() {
if (this.undoHistory.length > 0) {
const removedCommand = this.undoHistory.pop();
if (removedCommand) {
removedCommand.redo();
this.drawingHistory.push(removedCommand);
}
}
}
}
/**
* The `DrawCircleCommand` class implements the `Command` interface and represents a command to draw a circle.
*/
class DrawCircleCommand implements Command {
private circle?: Circle;
constructor(private x: number, private y: number) {}
/**
* Executes the command by creating a new `Circle` instance with the provided x and y coordinates.
*/
execute() {
this.circle = new Circle(this.x, this.y);
}
/**
* Undoes the most recent `DrawCircleCommand` by removing the associated `Circle` instance.
*/
undo() {
console.log(`Undone: DrawCircleCommand at (${this.x}, ${this.y})`);
this.circle = undefined;
}
redo() {
console.log(`Redone: DrawCircleCommand at (${this.x}, ${this.y})`);
this.execute();
}
/**
* Draws the circle represented by this command.
*/
draw() {
if (this.circle) {
this.circle.draw();
}
}
}
/**
* Represents a circle with an x and y coordinate.
*/
class Circle {
constructor(private x: number, private y: number) {}
draw() {
console.log(`Circle drawn at (${this.x}, ${this.y})`);
}
}
export { Circle, Command, DrawCircleCommand, Invoker };