source: trunk/Items.pas

Last change on this file was 143, checked in by chronos, 11 months ago

Removed U prefix from all units.

File size: 4.0 KB
Line 
1unit Items;
2
3interface
4
5uses
6 Classes, SysUtils, Generics.Collections, DOM, XML;
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{ TItem }
51
52procedure TItem.LoadFromXmlNode(Node: TDOMNode);
53begin
54 Id := ReadInteger(Node, 'Id', Id);
55end;
56
57procedure TItem.SaveToXmlNode(Node: TDOMNode);
58begin
59 WriteInteger(Node, 'Id', Id);
60end;
61
62procedure TItem.Assign(Source: TItem);
63begin
64 Id := Source.Id;
65end;
66
67class function TItem.GetClassSysName: string;
68begin
69 Result := ClassName;
70end;
71
72{ TItems }
73
74procedure TItems<T>.Assign(Source: TItems<T>);
75var
76 I: Integer;
77begin
78 while Count > Source.Count do Delete(Count - 1);
79 while Count < Source.Count do AddItem;
80 for I := 0 to Count - 1 do
81 Items[I].Assign(Source.Items[I]);
82end;
83
84class function TItems<T>.GetItemClass: TTClass;
85begin
86 Result := TTClass(T.ClassType);
87end;
88
89class function TItems<T>.GetClassSysName: string;
90begin
91 Result := ClassName;
92end;
93
94function TItems<T>.GetNewId: Integer;
95begin
96 Result := NewId;
97 Inc(NewId);
98end;
99
100function TItems<T>.AddItem: T;
101begin
102 Result := CreateItem;
103 Result.Id := GetNewId;
104 Add(Result);
105end;
106
107function TItems<T>.CreateItem: T;
108begin
109 Result := GetItemClass.Create;
110end;
111
112procedure TItems<T>.LoadFromXmlNodeRef(Node: TDOMNode; Target: TItems<T>);
113var
114 Node2: TDOMNode;
115 NewItem: T;
116 RefId: Integer;
117begin
118 Node2 := Node.FirstChild;
119 while Assigned(Node2) and (Node2.NodeName = DOMString(T.GetClassSysName)) do begin
120 RefId := StrToInt(string(Node2.TextContent));
121 NewItem := Target.FindById(RefId);
122 if Assigned(NewItem) then Add(NewItem)
123 else raise Exception.Create(Format(SReferenceNotFound, [string(Node.TextContent),
124 T.GetClassSysName]));
125 Node2 := Node2.NextSibling;
126 end;
127end;
128
129procedure TItems<T>.SaveToXmlNodeRef(Node: TDOMNode);
130var
131 I: Integer;
132begin
133 for I := 0 to Count - 1 do begin;
134 WriteInteger(Node, T.GetClassSysName, Items[I].Id);
135 end;
136end;
137
138procedure TItems<T>.RebuildItemsId;
139var
140 I: Integer;
141begin
142 for I := 0 to Count - 1 do
143 Items[I].Id := I + 1;
144end;
145
146function TItems<T>.FindById(Id: Integer): T;
147var
148 I: Integer;
149begin
150 I := 0;
151 while (I < Count) and (Items[I].Id <> Id) do Inc(I);
152 if I < Count then Result := Items[I]
153 else Result := nil;
154end;
155
156constructor TItems<T>.Create(AOwnsObjects: Boolean = True);
157begin
158 inherited;
159 NewId := 1;
160end;
161
162procedure TItems<T>.LoadFromXmlNode(Node: TDOMNode);
163var
164 Node2: TDOMNode;
165 NewItem: T;
166begin
167 Count := 0;
168 Node2 := Node.FirstChild;
169 while Assigned(Node2) and (Node2.NodeName = UnicodeString(T.GetClassSysName)) do begin
170 NewItem := CreateItem;
171 NewItem.LoadFromXmlNode(Node2);
172 Add(NewItem);
173 Node2 := Node2.NextSibling;
174 end;
175end;
176
177procedure TItems<T>.SaveToXmlNode(Node: TDOMNode);
178var
179 I: Integer;
180 NewNode2: TDOMNode;
181begin
182 for I := 0 to Count - 1 do
183 with TItem(Items[I]) do begin
184 NewNode2 := Node.OwnerDocument.CreateElement(UnicodeString(T.GetClassSysName));
185 Node.AppendChild(NewNode2);
186 SaveToXmlNode(NewNode2);
187 end;
188end;
189
190
191end.
192
Note: See TracBrowser for help on using the repository browser.