]>
Commit | Line | Data |
---|---|---|
bd9396d5 HH |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: No names yet. | |
3 | // Purpose: Contrib. demo | |
4 | // Author: Aleksandras Gluchovas | |
5 | // Modified by: | |
6 | // Created: 26/10/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Aleksandras Gluchovas | |
9 | // Licence: wxWindows license | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifdef __GNUG__ | |
13 | #pragma implementation "pf_sample.h" | |
14 | // #pragma interface | |
15 | #endif | |
16 | ||
17 | // For compilers that support precompilation, includes "wx.h". | |
18 | #include "wx/wxprec.h" | |
19 | ||
20 | #ifdef __BORLANDC__ | |
21 | #pragma hdrstop | |
22 | #endif | |
23 | ||
24 | #ifndef WX_PRECOMP | |
25 | #include "wx/wx.h" | |
26 | #endif | |
27 | ||
28 | #include "pf_sample.h" | |
29 | ||
30 | IMPLEMENT_DYNAMIC_CLASS( classA, wxObject ) | |
31 | IMPLEMENT_DYNAMIC_CLASS( classB, wxObject ) | |
32 | ||
33 | IMPLEMENT_SERIALIZER_CLASS( classA, | |
34 | classASerializer, | |
35 | classASerializer::Serialize, | |
36 | NO_CLASS_INIT ) | |
37 | ||
38 | IMPLEMENT_SERIALIZER_CLASS( classB, | |
39 | classBSerializer, | |
40 | classBSerializer::Serialize, | |
41 | NO_CLASS_INIT ) | |
42 | ||
43 | // somehow original wxASSERT(0) statements get not compiled in... | |
44 | ||
45 | #undef wxASSERT | |
46 | #define wxASSERT(x) if ( !(x) ) throw; | |
47 | ||
48 | extern notStorableClass gNotStorable; | |
49 | ||
50 | typedef notStorableClass* BackRefType; | |
51 | ||
52 | void test_storing( const char* fname, wxObjectStorage& store ) | |
53 | { | |
54 | // create objects | |
55 | ||
56 | classA* pA = new classA(); | |
57 | pA->x = 1; | |
58 | ||
59 | classB* pB = new classB(); | |
60 | ||
61 | pB->y = 2; | |
62 | ||
63 | // put cross-references | |
64 | ||
65 | pB->mpAObj = pA; | |
66 | ||
67 | pA->mpBObj = pB; | |
68 | ||
69 | // put back-references to not-storable obj | |
70 | ||
71 | pA->mpBackRef = &gNotStorable; | |
72 | pB->mpBackRef = &gNotStorable; | |
73 | ||
74 | // create stream object for output | |
75 | ||
76 | wxIOStreamWrapper outFile; | |
77 | ||
78 | bool success = outFile.Create( fname, FALSE ); | |
79 | ||
80 | wxASSERT( success ); | |
81 | ||
82 | store.SetDataStream( outFile ); | |
83 | ||
84 | // store everything starting from "pA" object | |
85 | ||
86 | store.XchgObjPtr( (wxObject**) &pA ); | |
87 | ||
88 | // flushes stream | |
89 | store.Finalize(); | |
90 | } | |
91 | ||
92 | void test_loading( const char* fname, wxObjectStorage& store ) | |
93 | { | |
94 | classA* pA = 0; | |
95 | ||
96 | // create stream-object for input | |
97 | ||
98 | wxIOStreamWrapper inFile; | |
99 | ||
100 | bool success = inFile.Create( fname, TRUE ); | |
101 | ||
102 | wxASSERT( success ); | |
103 | ||
104 | store.SetDataStream( inFile ); | |
105 | ||
106 | // load everything | |
107 | ||
108 | store.XchgObjPtr( (wxObject**) &pA ); | |
109 | ||
110 | // calls initializing procedures for serializer | |
111 | // which provide them | |
112 | ||
113 | store.Finalize(); | |
114 | ||
115 | // short-cut | |
116 | ||
117 | classB* pB = pA->mpBObj; | |
118 | ||
119 | // assertain correctness of class members | |
120 | ||
121 | wxASSERT( pA->x == 1 ); | |
122 | wxASSERT( pB->y == 2 ); | |
123 | ||
124 | // assertain correctness of cross-references | |
125 | ||
126 | wxASSERT( pA->mpBObj == pB ); | |
127 | wxASSERT( pB->mpAObj == pA ); | |
128 | ||
129 | // asssertain correctness of inital references | |
130 | ||
131 | wxASSERT( pA->mpBackRef == &gNotStorable ); | |
132 | wxASSERT( pB->mpBackRef == &gNotStorable ); | |
133 | } | |
134 | ||
135 | void setup_inital_refs( wxObjectStorage& store ) | |
136 | { | |
137 | store.AddInitialRef( (wxObject*) &gNotStorable ); | |
138 | } | |
139 | ||
140 | // global instance of the object, which we do not want to store/load for | |
141 | // some reason, even though other stored/loaded objects have refernces to it | |
142 | ||
143 | notStorableClass gNotStorable; | |
144 | ||
145 | void test_storing_of_list( const char* fname, wxObjectStorage& store ); | |
146 | void test_loading_of_list( const char* fname, wxObjectStorage& store ); | |
147 | ||
148 | /*---------------------------*/ | |
149 | /* Main testing function */ | |
150 | /*---------------------------*/ | |
151 | ||
152 | void test_obj_storage() | |
153 | { | |
154 | // NOTE:: for brevity, the heap clean-ups are omitted in the tests | |
155 | ||
156 | wxObjectStorage store; | |
157 | ||
158 | setup_inital_refs( store ); | |
159 | ||
160 | test_storing( "testdata.dat", store ); | |
161 | test_loading( "testdata.dat", store ); | |
162 | ||
163 | test_storing_of_list( "testdata.dat", store ); | |
164 | test_loading_of_list( "testdata.dat", store ); | |
165 | } | |
166 | ||
167 | void test_storing_of_list( const char* fname, wxObjectStorage& store ) | |
168 | { | |
169 | // create objects | |
170 | ||
171 | classA* pA = new classA(); | |
172 | pA->x = 1; | |
173 | ||
174 | classB* pB = new classB(); | |
175 | ||
176 | pB->y = 2; | |
177 | ||
178 | // put cross-references | |
179 | ||
180 | pB->mpAObj = pA; | |
181 | ||
182 | pA->mpBObj = pB; | |
183 | ||
184 | // create list object | |
185 | ||
186 | wxList* pLst = new wxList; | |
187 | ||
188 | // put objects to the list | |
189 | ||
190 | wxNode* pNode = pLst->Append( pA ); | |
191 | ||
192 | pA->mpBackRef = (BackRefType)pNode; | |
193 | ||
194 | pNode = pLst->Append( pB ); | |
195 | ||
196 | pB->mpBackRef = (BackRefType)pNode; | |
197 | ||
198 | // create stream object for output | |
199 | ||
200 | wxIOStreamWrapper outFile; | |
201 | ||
202 | bool success = outFile.Create( fname, FALSE ); | |
203 | ||
204 | wxASSERT( success ); | |
205 | ||
206 | store.SetDataStream( outFile ); | |
207 | ||
208 | // store everything starting from "pLst" object | |
209 | ||
210 | store.XchgObjPtr( (wxObject**) &pLst ); | |
211 | ||
212 | // flushes stream | |
213 | store.Finalize(); | |
214 | } | |
215 | ||
216 | void test_loading_of_list( const char* fname, wxObjectStorage& store ) | |
217 | { | |
218 | // create stream-object for input | |
219 | ||
220 | wxIOStreamWrapper inFile; | |
221 | ||
222 | bool success = inFile.Create( fname, TRUE ); | |
223 | ||
224 | wxASSERT( success ); | |
225 | ||
226 | store.SetDataStream( inFile ); | |
227 | ||
228 | // load everything | |
229 | ||
230 | wxList* pLst; | |
231 | ||
232 | // (NOTE:: serializers for wxList/wxNode is file objstore.cpp) | |
233 | ||
234 | store.XchgObjPtr( (wxObject**) &pLst ); | |
235 | ||
236 | // assertain correctness of list and it's contents | |
237 | ||
238 | wxASSERT( pLst->Number() == 2 ); | |
239 | ||
240 | int n = 0; | |
241 | wxNode* pNode = pLst->First(); | |
242 | ||
243 | while( pNode ) | |
244 | { | |
245 | if ( n == 0 ) | |
246 | { | |
247 | classA* pA = (classA*)pNode->Data(); | |
248 | ||
249 | // assertain correctness of class members | |
250 | ||
251 | wxASSERT( pA->x == 1 ); | |
252 | ||
253 | // assertain correctness of cross-references | |
254 | ||
255 | wxASSERT( pA->mpBObj == (classB*)pNode->Next()->Data() ); | |
256 | ||
257 | // asssertain correctness of inital references | |
258 | ||
259 | wxASSERT( (wxNode*)pA->mpBackRef == pNode ) | |
260 | } | |
261 | if ( n == 1 ) | |
262 | { | |
263 | classB* pB = (classB*)pNode->Data(); | |
264 | ||
265 | // assertain correctness of class members | |
266 | ||
267 | wxASSERT( pB->y == 2 ); | |
268 | ||
269 | // assertain correctness of cross-references | |
270 | ||
271 | wxASSERT( pB->mpAObj == (classA*)pNode->Previous()->Data() ); | |
272 | ||
273 | // asssertain correctness of inital references | |
274 | ||
275 | wxASSERT( (wxNode*)pB->mpBackRef == pNode ) | |
276 | } | |
277 | ||
278 | pNode = pNode->Next(); | |
279 | ++n; | |
280 | } | |
281 | ||
282 | // calls initializing procedures for serializer | |
283 | // which provide them | |
284 | ||
285 | store.Finalize(); | |
286 | } |