source: tags/1.4.0/UItems.pas

Last change on this file was 132, checked in by chronos, 13 months ago
  • Fixed: Improved stored game state.
File size: 4.0 KB
Line 
1unit UItems;
2
3interface
4
5uses
6 Classes, SysUtils, Generics.Collections, DOM, UXMLUtils;
7
8type
9 { TItem }
10
11 TItem = class
12 Id: Integer;
13 procedure LoadFromXmlNode(Node: TDOMNode); virtual;
14 procedure SaveToXmlNode(Node: TDOMNode); virtual;
15 procedure Assign(Source: TItem); virtual;
16 class function GetClassSysName: string; virtual;
17 end;
18
19 TItemClass = class of TItem;
20
21 { TItems }
22
23 TItems<T: TItem> = class(TObjectList<T>)
24 public
25 type
26 TTClass = class of T;
27 var
28 NewId: Integer;
29 class function GetItemClass: TTClass; virtual;
30 class function GetClassSysName: string; virtual;
31 function GetNewId: Integer;
32 function AddItem: T; virtual;
33 procedure Assign(Source: TItems<T>); virtual;
34 function CreateItem: T; virtual;
35 procedure LoadFromXmlNodeRef(Node: TDOMNode; Target: TItems<T>);
36 procedure SaveToXmlNodeRef(Node: TDOMNode);
37 procedure LoadFromXmlNode(Node: TDOMNode); virtual;
38 procedure SaveToXmlNode(Node: TDOMNode); virtual;
39 procedure RebuildItemsId;
40 function FindById(Id: Integer): T;
41 constructor Create(AOwnsObjects: Boolean = True); virtual;
42 end;
43
44resourcestring
45 SReferenceNotFound = 'Reference %s to class %s not found.';
46
47
48implementation
49
50
51{ TItem }
52
53procedure TItem.LoadFromXmlNode(Node: TDOMNode);
54begin
55 Id := ReadInteger(Node, 'Id', Id);
56end;
57
58procedure TItem.SaveToXmlNode(Node: TDOMNode);
59begin
60 WriteInteger(Node, 'Id', Id);
61end;
62
63procedure TItem.Assign(Source: TItem);
64begin
65 Id := Source.Id;
66end;
67
68class function TItem.GetClassSysName: string;
69begin
70 Result := ClassName;
71end;
72
73{ TItems }
74
75procedure TItems<T>.Assign(Source: TItems<T>);
76var
77 I: Integer;
78begin
79 while Count > Source.Count do Delete(Count - 1);
80 while Count < Source.Count do AddItem;
81 for I := 0 to Count - 1 do
82 Items[I].Assign(Source.Items[I]);
83end;
84
85class function TItems<T>.GetItemClass: TTClass;
86begin
87 Result := TTClass(T.ClassType);
88end;
89
90class function TItems<T>.GetClassSysName: string;
91begin
92 Result := ClassName;
93end;
94
95function TItems<T>.GetNewId: Integer;
96begin
97 Result := NewId;
98 Inc(NewId);
99end;
100
101function TItems<T>.AddItem: T;
102begin
103 Result := CreateItem;
104 Result.Id := GetNewId;
105 Add(Result);
106end;
107
108function TItems<T>.CreateItem: T;
109begin
110 Result := GetItemClass.Create;
111end;
112
113procedure TItems<T>.LoadFromXmlNodeRef(Node: TDOMNode; Target: TItems<T>);
114var
115 Node2: TDOMNode;
116 NewItem: T;
117 RefId: Integer;
118begin
119 Node2 := Node.FirstChild;
120 while Assigned(Node2) and (Node2.NodeName = DOMString(T.GetClassSysName)) do begin
121 RefId := StrToInt(string(Node2.TextContent));
122 NewItem := Target.FindById(RefId);
123 if Assigned(NewItem) then Add(NewItem)
124 else raise Exception.Create(Format(SReferenceNotFound, [string(Node.TextContent),
125 T.GetClassSysName]));
126 Node2 := Node2.NextSibling;
127 end;
128end;
129
130procedure TItems<T>.SaveToXmlNodeRef(Node: TDOMNode);
131var
132 I: Integer;
133begin
134 for I := 0 to Count - 1 do begin;
135 WriteInteger(Node, T.GetClassSysName, Items[I].Id);
136 end;
137end;
138
139procedure TItems<T>.RebuildItemsId;
140var
141 I: Integer;
142begin
143 for I := 0 to Count - 1 do
144 Items[I].Id := I + 1;
145end;
146
147function TItems<T>.FindById(Id: Integer): T;
148var
149 I: Integer;
150begin
151 I := 0;
152 while (I < Count) and (Items[I].Id <> Id) do Inc(I);
153 if I < Count then Result := Items[I]
154 else Result := nil;
155end;
156
157constructor TItems<T>.Create(AOwnsObjects: Boolean = True);
158begin
159 inherited;
160 NewId := 1;
161end;
162
163procedure TItems<T>.LoadFromXmlNode(Node: TDOMNode);
164var
165 Node2: TDOMNode;
166 NewItem: T;
167begin
168 Count := 0;
169 Node2 := Node.FirstChild;
170 while Assigned(Node2) and (Node2.NodeName = UnicodeString(T.GetClassSysName)) do begin
171 NewItem := CreateItem;
172 NewItem.LoadFromXmlNode(Node2);
173 Add(NewItem);
174 Node2 := Node2.NextSibling;
175 end;
176end;
177
178procedure TItems<T>.SaveToXmlNode(Node: TDOMNode);
179var
180 I: Integer;
181 NewNode2: TDOMNode;
182begin
183 for I := 0 to Count - 1 do
184 with TItem(Items[I]) do begin
185 NewNode2 := Node.OwnerDocument.CreateElement(UnicodeString(T.GetClassSysName));
186 Node.AppendChild(NewNode2);
187 SaveToXmlNode(NewNode2);
188 end;
189end;
190
191
192end.
193
Note: See TracBrowser for help on using the repository browser.