]>
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 | #ifndef __OBJSTORE_G__ | |
13 | #define __OBJSTORE_G__ | |
14 | ||
15 | #include "wx/object.h" | |
16 | #include "wx/string.h" | |
17 | #include "wx/list.h" | |
18 | #include "wx/hash.h" | |
19 | ||
20 | #include "wx/window.h" | |
21 | #include "wx/button.h" | |
22 | #include "wx/textctrl.h" | |
23 | #include "wx/treectrl.h" | |
24 | #include "wx/dynarray.h" | |
25 | ||
26 | // abstract classes declared | |
27 | ||
28 | class wxDataStreamBase; | |
29 | class wxSerializerBase; | |
30 | class wxObjectStorage; | |
31 | ||
32 | // classes which implement the above interfaces | |
33 | ||
34 | class wxPointSerializer; | |
35 | class wxSizeSerializer; | |
36 | class wxRectSerializer; | |
37 | class wxPenSerializer; | |
38 | class wxBrushSerializer; | |
39 | ||
40 | class wxObjectListSerializer; | |
41 | ||
42 | class wxEvtHandlerSerializer; | |
43 | class wxWindowSerializer; | |
44 | class wxButtonSerializer; | |
45 | class wxScrollBarSerializer; | |
46 | class wxChoiceSerializer; | |
47 | class wxTextCtrlSerializer; | |
48 | class wxTreeCtrlSerializer; | |
49 | ||
50 | ||
51 | class wxIOStreamWrapper; | |
52 | ||
53 | // prototypes for serialzatoin/initialization functions | |
54 | ||
55 | typedef void (*wxObjectSerializationFn) (wxObject*, wxObjectStorage& ); | |
56 | typedef void (*wxObjectInitializationFn)(wxObject*); | |
57 | ||
58 | #define NO_CLASS_VER NULL | |
59 | #define NO_CLASS_INIT NULL | |
60 | ||
61 | /* | |
62 | * class conceptually simiar to wxClassInfo, execpt that it's static | |
63 | * instances hold information about class-serializers rather then | |
64 | * about the classes themselves. | |
65 | */ | |
66 | ||
67 | class wxSerializerInfo | |
68 | { | |
69 | public: | |
70 | char* className; | |
71 | ||
72 | wxClassInfo* classInfo; // link to corresponding class-info object, | |
73 | // established upon invocation of InitializeSerializers() | |
74 | ||
75 | wxObjectSerializationFn serFn; | |
76 | wxObjectInitializationFn initFn; | |
77 | ||
78 | char* classVersion; | |
79 | ||
80 | static bool alreadyInitialized; | |
81 | static wxSerializerInfo* first; | |
82 | static wxHashTable serInfoHash; // classInfo <=> serializerInfo | |
83 | ||
84 | wxSerializerInfo* next; | |
85 | wxSerializerInfo* nextByVersion; | |
86 | ||
87 | wxSerializerInfo( char* theClassName, | |
88 | wxObjectSerializationFn serializationFun, | |
89 | wxObjectInitializationFn initializationFun, | |
90 | char* classVersionName | |
91 | ); | |
92 | ||
93 | // looks up for serializers of the base classes (base1 and base2) | |
94 | // of the given object invokes them if present | |
95 | ||
96 | void SerializeInherited ( wxObject* pObj, wxObjectStorage& store ); | |
97 | void InitializeInherited( wxObject* pObj ); | |
98 | ||
99 | bool HasVersion() { return classVersion != NO_CLASS_VER; } | |
100 | ||
101 | bool HasInitializer() { return initFn != NO_CLASS_INIT; } | |
102 | ||
103 | // static methods | |
104 | ||
105 | static void InitializeSerializers(void); | |
106 | ||
107 | static wxSerializerInfo* FindSerializer( char* className ); | |
108 | }; | |
109 | ||
110 | /* | |
111 | * formal base class for all serializers, implemented as | |
112 | * classes with static serialization/initialization methods | |
113 | */ | |
114 | ||
115 | class wxSerializerBase {}; | |
116 | ||
117 | // macros for declaring and implementing serializers both as | |
118 | // classes and as a pair of (serialize/init) functions | |
119 | ||
120 | #define DECLARE_SERIALIZER_CLASS(serializerName) \ | |
121 | public:\ | |
122 | static wxSerializerInfo info;; | |
123 | ||
124 | #define IMPLEMENT_SERIALIZER_CLASS( name, serializerName, serFn, initFn) \ | |
125 | wxSerializerInfo \ | |
126 | serializerName::info( #name, serFn, initFn, NO_CLASS_VER ); | |
127 | ||
128 | #define IMPLEMENT_SERIALIZER_FUNCTIONS( name, serFn, initFn) \ | |
129 | wxSerializerInfo \ | |
130 | static __gSerFnInfoFor##name( #name, serFn, initFn, NO_CLASS_VER ); | |
131 | ||
132 | // for serializers, which are dedicated for specific versions of persistant classes | |
133 | // (further referred as "versioned" serializers) | |
134 | ||
135 | #define IMPLEMENT_SERIALIZER_CLASS_FOR_VERSION( name, serializerName, serFn, initFn, versionName) \ | |
136 | wxSerializerInfo \ | |
137 | serializerName::info( #name, serFn, initFn, #versionName ); | |
138 | ||
139 | #define IMPLEMENT_SERIALIZER_FUNCTIONS_FOR_VERSION( name, serializerName, serFn, initFn, versionName) \ | |
140 | wxSerializerInfo \ | |
141 | static __gSerFnInfoFor##name( #name, serFn, initFn, #versionName ); | |
142 | ||
143 | /* | |
144 | * defines abstract inferface for data-stream objects, | |
145 | * can be implemented as a wrapper class for already | |
146 | * existing stream classes | |
147 | */ | |
148 | ||
149 | class wxDataStreamBase : public wxObject | |
150 | { | |
151 | DECLARE_ABSTRACT_CLASS( wxDataStreamBase ) | |
152 | protected: | |
153 | bool mIsForInput; | |
154 | ||
155 | public: | |
156 | virtual bool StoreChar ( char ch ) = 0; | |
157 | virtual bool StoreInt ( int i ) = 0; | |
158 | virtual bool StoreLong ( long l ) = 0; | |
159 | virtual bool StoreDouble( double d ) = 0; | |
160 | virtual bool StoreBytes ( void* bytes, int count ) = 0; | |
161 | ||
162 | virtual bool LoadChar ( char *pCh ) = 0; | |
163 | virtual bool LoadInt ( int *pI ) = 0; | |
164 | virtual bool LoadLong ( long *pL ) = 0; | |
165 | virtual bool LoadDouble( double *pD ) = 0; | |
166 | virtual bool LoadBytes ( void *pBytes, int count ) = 0; | |
167 | ||
168 | virtual bool Flush() = 0; | |
169 | ||
170 | virtual long GetStreamPos() = 0; | |
171 | ||
172 | bool IsForInput() { return mIsForInput; } | |
173 | }; | |
174 | ||
175 | /* | |
176 | * class provides stream-based persistance service for | |
177 | * classes derivated from wxObject, which are declared | |
178 | * as dynamic classes. Relies on the presence of appropriate | |
179 | * serializers for objects, which are being stored/loaded. | |
180 | */ | |
181 | ||
182 | class wxObjectStorage : public wxObject | |
183 | { | |
184 | DECLARE_DYNAMIC_CLASS( wxObjectStorage ) | |
185 | protected: | |
186 | wxDataStreamBase* mpStm; | |
187 | bool mIsLoading; | |
188 | ||
189 | wxHashTable mRefHash; | |
190 | ||
191 | wxList mInitialRefs; | |
192 | wxHashTable mInitialRefsHash; | |
193 | long mInitialRefsCnt; | |
194 | ||
195 | wxList mNewObjs; | |
196 | wxList mSerializersForNewObjs; | |
197 | ||
198 | bool mFinalizePending; | |
199 | ||
200 | protected: | |
201 | wxSerializerBase* FindSerializer( wxObject* pForObj ); | |
202 | ||
203 | void ClearHashesAndLists(); | |
204 | ||
205 | virtual bool VersionsMatch( char* v1, char* v2 ); | |
206 | ||
207 | virtual wxSerializerInfo* FindSrzInfoForClass( wxClassInfo* pInfo ); | |
208 | ||
209 | void DoExchangeObject( wxObject* pInstance, wxSerializerInfo& srzInfo ); | |
210 | ||
211 | bool ExchangeObjectInfo( wxClassInfo** ppCInfo, wxSerializerInfo** ppSrz ); | |
212 | ||
213 | wxSerializerInfo* GetLatestSrzForObj( wxObject* pWxObj ); | |
214 | ||
215 | public: | |
216 | // can be changed (with countion!) | |
217 | ||
218 | static char mVerSepartorCh; // default: '#' | |
219 | static char mMinorMajorSepartorCh; // default: '-' | |
220 | ||
221 | public: | |
222 | ||
223 | wxObjectStorage(); | |
224 | ||
225 | wxObjectStorage( wxDataStreamBase& stm ); | |
226 | ||
227 | virtual ~wxObjectStorage(); | |
228 | ||
229 | // adds initial reference, objects referred by such reference | |
230 | // are not serialized when storing. When loading, pointers which | |
231 | // refere to these "inital objects" are set up to refere to | |
232 | // objects provided in by AddInitailRef() method. | |
233 | // | |
234 | // NOTE:: initial references should be added always in the | |
235 | // same order, since the seq-# of the reference is used | |
236 | // as an alias to the real object while storing/loading | |
237 | ||
238 | void AddInitialRef( wxObject* pObjRef ); | |
239 | ||
240 | void ClearInitalRefs(); | |
241 | ||
242 | // init/reinit of object-storage | |
243 | ||
244 | void SetDataStream( wxDataStreamBase& stm ); | |
245 | ||
246 | // performs linkng of in-memory references after loading, or | |
247 | // links in-stream references after storing has proceeded | |
248 | ||
249 | void Finalize(); | |
250 | ||
251 | // storage methods for basic types | |
252 | ||
253 | void XchgChar ( char& chObj ); | |
254 | void XchgInt ( int& intObj ); | |
255 | void XchgLong ( long& longObj ); | |
256 | void XchgBool ( bool& boolObj ); | |
257 | void XchgDouble ( double& doubleObj ); | |
258 | void XchgCStr ( char* pCStrObj ); | |
259 | void XchgUInt ( unsigned int& uI ); | |
260 | void XchgSizeType( size_t& szObj ); | |
261 | ||
262 | void XchgObjList ( wxList& objList ); | |
263 | void XchgObjArray ( wxBaseArray& objArr ); | |
264 | void XchgLongArray( wxBaseArray& longArr ); | |
265 | ||
266 | // storage methods for objects and pointers to objects | |
267 | ||
268 | void XchgObj ( wxObject* pWxObj ); | |
269 | void XchgObjPtr( wxObject** ppWxObj ); | |
270 | ||
271 | bool IsLoading() { return mIsLoading; } | |
272 | ||
273 | // storage methods for common wxWindows classes, | |
274 | // which may or may not be dymaic, therefor use the | |
275 | // below methods instead of XchgObj(..) | |
276 | ||
277 | void XchgWxStr ( wxString& str ); | |
278 | void XchgWxSize ( wxSize& size ); | |
279 | void XchgWxPoint( wxPoint& point ); | |
280 | void XchgWxRect ( wxRect& rect ); | |
281 | }; | |
282 | ||
283 | /* | |
284 | * The below classes provide "curde" serialization for most | |
285 | * common wxWindows objects, i.e. they discard the information | |
286 | * which may be contained in the subclassed versions of these classes | |
287 | * However, more "fine-grainded" serializers could be written | |
288 | * to match these subclasses exactly. | |
289 | */ | |
290 | ||
291 | class wxColourSerializer : public wxSerializerBase | |
292 | { | |
293 | DECLARE_SERIALIZER_CLASS( wxColourSerializer ); | |
294 | ||
295 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
296 | }; | |
297 | ||
298 | // NOTE:: currently "stipple" and "dashes" properties of the pen | |
299 | // are not serialized | |
300 | ||
301 | class wxPenSerializer : public wxSerializerBase | |
302 | { | |
303 | DECLARE_SERIALIZER_CLASS( wxPenSerializer ); | |
304 | public: | |
305 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
306 | }; | |
307 | ||
308 | // NOTE:: currently "stipple" property of the brush is not serialized | |
309 | ||
310 | class wxBrushSerializer : public wxSerializerBase | |
311 | { | |
312 | DECLARE_SERIALIZER_CLASS( wxBrushSerializer ); | |
313 | ||
314 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
315 | }; | |
316 | ||
317 | // serializer for wxList, assuming that the list | |
318 | // holds derivatives of wxObject. | |
319 | ||
320 | class wxObjectListSerializer : public wxSerializerBase | |
321 | { | |
322 | DECLARE_SERIALIZER_CLASS( wxObjectListSerializer ); | |
323 | ||
324 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
325 | }; | |
326 | ||
327 | // generic serializer for classes derived from wxEvtHandler handler, | |
328 | // assuming that they do not add any new properties to wxEvtHandler | |
329 | // or these properties are transient | |
330 | ||
331 | class wxEvtHandlerSerializer : public wxSerializerBase | |
332 | { | |
333 | DECLARE_SERIALIZER_CLASS( wxEvtHandlerSerializer ); | |
334 | public: | |
335 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
336 | ||
337 | static void Initialize( wxObject* pObj ); | |
338 | }; | |
339 | ||
340 | // serializer for generic wxWindow. Serializes position, size, id, | |
341 | // reference to parent, list of children, style flags and name string. | |
342 | // Could be used for serializing wxWindow and generic wxPanel objects. | |
343 | // Separate serializers have to be written for control classes. | |
344 | ||
345 | class wxWindowSerializer : public wxEvtHandlerSerializer | |
346 | { | |
347 | DECLARE_SERIALIZER_CLASS( wxWindowSerializer ); | |
348 | public: | |
349 | ||
350 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
351 | ||
352 | // helpers, to ease the creation of serializers for derivatives of wxWindow | |
353 | ||
354 | typedef (*wndCreationFn)(wxWindow*, wxWindow*, const wxWindowID, | |
355 | const wxPoint&, const wxSize&, long, const wxString& ); | |
356 | ||
357 | ||
358 | static void DoSerialize( wxObject* pObj, wxObjectStorage& store, | |
359 | wndCreationFn creationFn, bool refreshNow = TRUE | |
360 | ); | |
361 | ||
362 | ||
363 | static void CreateWindowFn( wxWindow* wnd, wxWindow* parent, const wxWindowID id, | |
364 | const wxPoint& pos, const wxSize& size, long style , | |
365 | const wxString& name ); | |
366 | ||
367 | }; | |
368 | ||
369 | class wxTextCtrlSerializer : public wxWindowSerializer | |
370 | { | |
371 | DECLARE_SERIALIZER_CLASS( wxTextCtrlSerializer ); | |
372 | public: | |
373 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
374 | ||
375 | static void CreateTextCtrlWindowFn( wxTextCtrl* wnd, wxWindow* parent, const wxWindowID id, | |
376 | const wxPoint& pos, const wxSize& size, long style , | |
377 | const wxString& name ); | |
378 | }; | |
379 | ||
380 | class wxButtonSerializer : public wxWindowSerializer | |
381 | { | |
382 | DECLARE_SERIALIZER_CLASS( wxButtonSerializer ); | |
383 | public: | |
384 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
385 | ||
386 | static void CreateButtonWindowFn( wxButton* btn, wxWindow* parent, const wxWindowID id, | |
387 | const wxPoint& pos, const wxSize& size, long style , | |
388 | const wxString& name ); | |
389 | }; | |
390 | ||
391 | class wxStaticTextSerializer : public wxWindowSerializer | |
392 | { | |
393 | DECLARE_SERIALIZER_CLASS( wxStaticTextSerializer ); | |
394 | public: | |
395 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
396 | ||
397 | static void CreateSTextWindowFn( wxStaticText* pSTxt, wxWindow* parent, const wxWindowID id, | |
398 | const wxPoint& pos, const wxSize& size, long style , | |
399 | const wxString& name ); | |
400 | }; | |
401 | ||
402 | ||
403 | class wxScrollBarSerializer : public wxWindowSerializer | |
404 | { | |
405 | DECLARE_SERIALIZER_CLASS( wxScrollBarSerializer ); | |
406 | public: | |
407 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
408 | ||
409 | static void CreateScollBarWindowFn( wxScrollBar* sbar, wxWindow* parent, const wxWindowID id, | |
410 | const wxPoint& pos, const wxSize& size, long style , | |
411 | const wxString& name ); | |
412 | }; | |
413 | ||
414 | class wxTreeCtrlSerializer : public wxWindowSerializer | |
415 | { | |
416 | DECLARE_SERIALIZER_CLASS( wxTreeCtrlSerializer ); | |
417 | ||
418 | protected: | |
419 | static void SerializeBranch( wxTreeItemId parentId, wxTreeCtrl* pTree, | |
420 | wxObjectStorage& store, wxTreeItemId nextVisId, | |
421 | int depth ); | |
422 | ||
423 | public: | |
424 | static void Serialize( wxObject* pObj, wxObjectStorage& store ); | |
425 | ||
426 | static void CreateTreeCtrlWindowFn( wxTreeCtrl* tree, wxWindow* parent, const wxWindowID id, | |
427 | const wxPoint& pos, const wxSize& size, long style , | |
428 | const wxString& name ); | |
429 | }; | |
430 | ||
431 | // default implementations of interfaces, used by wxObjectStorage class | |
432 | // | |
433 | // FOR NOW:: methods do not yet perform byte-swaps for outputting/reading words in | |
434 | // machine-independent format. Better solution would be to write wrapper | |
435 | // around the "promissed" protable-data-stream class of wxWindows | |
436 | ||
437 | class wxIOStreamWrapper : public wxDataStreamBase | |
438 | { | |
439 | DECLARE_DYNAMIC_CLASS( wxIOStreamWrapper ) | |
440 | protected: | |
441 | iostream* mpStm; | |
442 | bool mOwnsStmObject; | |
443 | long mStreamPos; // precalcualted stream postion, | |
444 | // assuming that the actual stream object is not | |
445 | // capable of telling postion of current get/put pointer | |
446 | // (e.g. socket-stream) | |
447 | void Close(); | |
448 | ||
449 | public: | |
450 | ||
451 | // default constructor | |
452 | wxIOStreamWrapper(); | |
453 | ||
454 | // attach this wrapper to already exiting iostream object | |
455 | ||
456 | wxIOStreamWrapper( iostream& stm, bool forInput = TRUE ); | |
457 | ||
458 | // creates "fstream" object with the given file name in binary mode, | |
459 | // returns FALSE, if stream creation failed | |
460 | // | |
461 | // The created fstream object is "owned" by this wrapper, | |
462 | // thus it is destored during destruction of this object | |
463 | ||
464 | bool Create( const char* fileName, bool forInput = TRUE ); | |
465 | ||
466 | inline bool CreateForInput( const char* fileName ) | |
467 | ||
468 | { return Create( fileName, TRUE ); } | |
469 | ||
470 | inline bool CreateForOutput( const char* fileName ) | |
471 | ||
472 | { return Create( fileName, FALSE ); } | |
473 | ||
474 | // the same as in the second constructor, previousely used | |
475 | // stream object is flushed and destroyed (if owned). | |
476 | // The attached stream is not "owned" by this wrapper object | |
477 | ||
478 | void Attach( iostream& stm, bool forInput = TRUE ); | |
479 | ||
480 | virtual ~wxIOStreamWrapper(); | |
481 | ||
482 | virtual bool StoreChar ( char ch ); | |
483 | virtual bool StoreInt ( int i ); | |
484 | virtual bool StoreLong ( long l ); | |
485 | virtual bool StoreDouble( double d ); | |
486 | virtual bool StoreBytes ( void* bytes, int count ); | |
487 | ||
488 | virtual bool LoadChar ( char* pCh ); | |
489 | virtual bool LoadInt ( int* pI ); | |
490 | virtual bool LoadLong ( long* pL ); | |
491 | virtual bool LoadDouble( double* pD ); | |
492 | virtual bool LoadBytes ( void* pBytes, int count ); | |
493 | ||
494 | virtual bool Flush(); | |
495 | ||
496 | virtual long GetStreamPos(); | |
497 | ||
498 | bool Good(); | |
499 | }; | |
500 | ||
501 | #endif |