forked from mnickw/StacksPractic
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathListModel.cs
More file actions
145 lines (125 loc) · 3.65 KB
/
ListModel.cs
File metadata and controls
145 lines (125 loc) · 3.65 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
namespace TodoApplication
{
public class CommandBuilder<TItem>
{
public ListModel<TItem> ListModel { get; }
public CommandBuilder(ListModel<TItem> listModel)
{
this.ListModel = listModel;
}
public ICommand CreateAddItemCommand(TItem itemToAdd)
{
return new AddItemCommand<TItem>(ListModel.Items, itemToAdd);
}
public ICommand CreateRemoveItemCommand(int indexOfItemToRemove)
{
return new RemoveItemCommand<TItem>(ListModel.Items, indexOfItemToRemove);
}
public ICommand CreateUndoCommand()
{
return new UndoCommand(ListModel.HistoryStack);
}
}
public interface ICommand
{
void Undo();
bool Execute();
}
public class UndoCommand : ICommand
{
public LimitedSizeStack<ICommand> HistoryStack { get; }
public UndoCommand(LimitedSizeStack<ICommand> historyStack)
{
this.HistoryStack = historyStack;
}
public bool Execute()
{
HistoryStack.Pop().Undo();
return false;
}
public void Undo()
{
throw new NotSupportedException();
}
}
public class AddItemCommand<TItem> : ICommand
{
public List<TItem> Items { get; }
public TItem ItemToAdd { get; }
public AddItemCommand(List<TItem> items, TItem itemToAdd)
{
this.Items = items;
this.ItemToAdd = itemToAdd;
}
public bool Execute()
{
Items.Add(ItemToAdd);
return true;
}
public void Undo()
{
Items.RemoveAt(Items.Count - 1);
}
}
public class RemoveItemCommand<TItem> : ICommand
{
public List<TItem> Items { get; }
public int IndexOfItemToRemove { get; }
public TItem Backup { get; private set; }
public RemoveItemCommand(List<TItem> items, int indexOfItemToRemove)
{
this.Items = items;
this.IndexOfItemToRemove = indexOfItemToRemove;
}
public bool Execute()
{
Backup = Items[IndexOfItemToRemove];
Items.RemoveAt(IndexOfItemToRemove);
return true;
}
public void Undo()
{
Items.Insert(IndexOfItemToRemove, Backup);
}
}
public class ListModel<TItem>
{
public List<TItem> Items { get; }
public CommandBuilder<TItem> CommandBuilder { get; }
public int Limit { get; }
public LimitedSizeStack<ICommand> HistoryStack { get; private set; }
public ListModel(int limit)
{
Items = new List<TItem>();
Limit = limit;
HistoryStack = new LimitedSizeStack<ICommand>(Limit);
CommandBuilder = new CommandBuilder<TItem>(this);
}
public void AddItem(TItem item)
{
var command = CommandBuilder.CreateAddItemCommand(item);
ExecuteCommand(command);
}
public void RemoveItem(int index)
{
var command = CommandBuilder.CreateRemoveItemCommand(index);
ExecuteCommand(command);
}
public bool CanUndo()
{
return HistoryStack.Count > 0;
}
public void Undo()
{
var command = CommandBuilder.CreateUndoCommand();
ExecuteCommand(command);
}
public void ExecuteCommand(ICommand command)
{
if (command.Execute())
HistoryStack.Push(command);
}
}
}