1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "objstore.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
33 // BUG?:: somehow assertion statements with oritinal wxASSERT do not get compiled in
36 //#define wxASSERT(x) if ( !(x) ) throw;
38 /***** Implementation for class wxSerializerInfo *****/
40 bool wxSerializerInfo::alreadyInitialized
= FALSE
;
41 wxSerializerInfo
*wxSerializerInfo::first
= NULL
;
42 wxHashTable
wxSerializerInfo::serInfoHash
;
44 wxSerializerInfo::wxSerializerInfo( char* theClassName
,
45 wxObjectSerializationFn serializationFun
,
46 wxObjectInitializationFn initializationFun
,
47 char* classVersionName
51 nextByVersion( NULL
),
52 className ( theClassName
),
53 serFn ( serializationFun
),
54 initFn ( initializationFun
),
55 classVersion ( classVersionName
)
62 int serializer_ver_cmp_fun( const void* arg1
, const void* arg2
)
64 // "no-version" is considered being the highest version
66 if ( ((wxSerializerInfo
*)arg1
)->classVersion
== NO_CLASS_VER
)
68 // DBG:: two serializers for the same version of the class should not be present!
69 wxASSERT( ((wxSerializerInfo
*)arg1
)->classVersion
!= NO_CLASS_VER
);
71 return -1; // (inverted already)
74 if ( ((wxSerializerInfo
*)arg2
)->classVersion
== NO_CLASS_VER
)
76 // DBG:: two serializers for the same version of the class should not be present!
77 wxASSERT( ((wxSerializerInfo
*)arg1
)->classVersion
!= NO_CLASS_VER
);
79 return 1; // (inverted already)
82 // versions are compared lexicographically ignoring the char-case
84 wxString
v1( ((wxSerializerInfo
*)arg1
)->classVersion
);
85 wxString
v2( ((wxSerializerInfo
*)arg2
)->classVersion
);
87 bool result
= v1
.CompareTo( v2
, wxString::ignoreCase
);
89 // DBG:: two serializers for the same version of the class should not be present!
90 wxASSERT( result
== FALSE
);
92 // invert the sense of "greater than" for storting in decreasing order
94 return ( result
> 0 ) ? -1 : 1;
97 void wxSerializerInfo::InitializeSerializers(void)
99 if ( alreadyInitialized
) return;
101 alreadyInitialized
= TRUE
;
103 wxSerializerInfo
* pCur
= first
;
105 // first resolve references to class information structures
109 pCur
->classInfo
= wxClassInfo::FindClass( pCur
->className
);
111 wxASSERT( pCur
->classInfo
); // DBG:: class info should already be present somewhere!
113 // check if serializer for the class is already present,
115 wxSerializerInfo
* pFound
= (wxSerializerInfo
*)serInfoHash
.Get( (long)pCur
->classInfo
);
119 // if present, then it must be serializer for the certain version of that class,
120 // put it at the end of the chain of versioned serializers for that class
122 // go to the end of chain
124 while( pFound
->nextByVersion
) pFound
= pFound
->nextByVersion
;
128 pFound
->nextByVersion
= pCur
;
130 pCur
->next
= (wxSerializerInfo
*)(-1); // label it as member of local chain
131 // of "versioned" serializers
133 pCur
->nextByVersion
= NULL
;
137 // otherwise, serializer for the class found for the first time -
140 serInfoHash
.Put( (long)pCur
->classInfo
, (wxObject
*)pCur
);
142 // and include it to the list of serializers for the highest-versions
147 // sort chains of "versioned" serializers in the order of decreasing version
149 // (since, when loading, the newest version of an object
150 // is expected first, rather then the older one)
152 wxSerializerInfo
* pPrev
= NULL
;
159 if ( pCur
->nextByVersion
)
163 wxSerializerInfo
* pStart
= pCur
;
164 wxSerializerInfo
* pNext
= pCur
->next
;
166 // let wxList do the sorting, we're too lazy :)
172 sorted
.Append( (wxObject
*) pCur
);
174 pCur
= pCur
->nextByVersion
;
177 sorted
.Sort( serializer_ver_cmp_fun
);
179 wxNode
* pNode
= sorted
.First();
183 wxSerializerInfo
* pInfo
= (wxSerializerInfo
*)pNode
->Data();
185 if ( pNode
== sorted
.First() )
187 // make node with the highest version, a member of the global
188 // list of serializers
190 if ( pPrev
) pPrev
->next
= pInfo
;
196 pInfo
->next
= (wxSerializerInfo
*)(-1); // otherwise label it as a member of local
197 // chain of "versioned" serializers
201 pInfo
->nextByVersion
= (wxSerializerInfo
*)( pNode
->Next()->Data() );
204 pInfo
->nextByVersion
= 0;
206 pNode
= pNode
->Next();
209 } // end of if ( nextByVersion )
214 } // end of while(...)
217 wxSerializerInfo
* wxSerializerInfo::FindSerializer( char* className
)
219 wxSerializerInfo::InitializeSerializers();
221 wxSerializerInfo
* pInfo
= (wxSerializerInfo
*)
223 serInfoHash
.Get( (long)wxClassInfo::FindClass( className
) );
228 static void invoke_for_inherited( wxObject
* pObj
, wxClassInfo
* pCInfo
, wxObjectStorage
* pStore
, bool invokeSerFn
)
230 wxSerializerInfo
* pSrzInfo
= (wxSerializerInfo
*)
232 wxSerializerInfo::serInfoHash
.Get( (long)wxClassInfo::FindClass( pCInfo
->GetClassName() ) );
236 // if found, serialize/initialize and don't go "any higher"
240 (*pSrzInfo
->serFn
) ( pObj
, *pStore
);
242 (*pSrzInfo
->initFn
)( pObj
);
247 // go up the hierarchy, if no serializer present for the current class
249 if ( pCInfo
->GetBaseClass1() )
251 invoke_for_inherited( pObj
, pCInfo
->GetBaseClass1(), pStore
, invokeSerFn
);
253 if ( pCInfo
->GetBaseClass2() )
255 invoke_for_inherited( pObj
, pCInfo
->GetBaseClass2(), pStore
, invokeSerFn
);
259 void wxSerializerInfo::SerializeInherited( wxObject
* pObj
, wxObjectStorage
& store
)
261 // search recursivelly up the hierarchy for serializers of base
262 // classes, and invoke serialization function for the given object
264 if ( classInfo
->GetBaseClass1() )
266 invoke_for_inherited( pObj
, classInfo
->GetBaseClass1(), &store
, TRUE
);
268 if ( classInfo
->GetBaseClass2() )
270 invoke_for_inherited( pObj
, classInfo
->GetBaseClass2(), &store
, TRUE
);
273 void wxSerializerInfo::InitializeInherited( wxObject
* pObj
)
275 // search recursivelly up the hierarchy for serializers of base
276 // classes, and invoke initialization function for the given object
278 if ( classInfo
->GetBaseClass1() )
280 invoke_for_inherited( pObj
, classInfo
->GetBaseClass1(), NULL
, FALSE
);
282 if ( classInfo
->GetBaseClass2() )
284 invoke_for_inherited( pObj
, classInfo
->GetBaseClass2(), NULL
, FALSE
);
287 /***** Implementation for class wxDataStreamBase *****/
289 IMPLEMENT_ABSTRACT_CLASS( wxDataStreamBase
, wxObject
)
291 /***** Implementation for class wxObjectStorage *****/
293 // codes, used as tokens written/read from the stream
295 enum STORED_OBJ_TYPES
297 SOT_NULL_POINTER
= 'N',
298 SOT_POINTER_TO_OBJ
= 'P',
299 SOT_INITIAL_REF
= 'I',
303 // veraion-encoding in object-name string fromat defaults:
305 char wxObjectStorage::mVerSepartorCh
= '#';
306 char wxObjectStorage::mMinorMajorSepartorCh
= '-';
308 IMPLEMENT_DYNAMIC_CLASS( wxObjectStorage
, wxObject
)
310 wxObjectStorage::wxObjectStorage()
313 mInitialRefsCnt ( 0 ),
314 mFinalizePending( FALSE
)
317 wxObjectStorage::wxObjectStorage( wxDataStreamBase
& stm
)
319 mIsLoading ( stm
.IsForInput() ),
320 mInitialRefsCnt ( 0 ),
321 mFinalizePending( FALSE
)
323 wxSerializerInfo::InitializeSerializers();
325 mFinalizePending
= TRUE
; // stream object was given - store/load is
329 wxObjectStorage::~wxObjectStorage()
331 if ( mFinalizePending
)
333 Finalize(); // <- do it now, if "user" forgot about it
336 /*** protected members ***/
338 void wxObjectStorage::ClearHashesAndLists()
341 mSerializersForNewObjs
.Clear();
345 /*** public members ***/
347 void wxObjectStorage::SetDataStream( wxDataStreamBase
& stm
)
349 if ( mFinalizePending
)
353 wxSerializerInfo::InitializeSerializers();
355 ClearHashesAndLists();
359 mIsLoading
= stm
.IsForInput();
361 mFinalizePending
= TRUE
;
364 void wxObjectStorage::Finalize()
366 wxASSERT( mpStm
); // DBG:: finalize should called be after loading/storing has proceeded
368 mFinalizePending
= FALSE
;
372 // initializaiton is performed after all objects successfully
373 // loaded, and references among them are established
375 wxNode
* pObjNode
= mNewObjs
.First();
376 wxNode
* pSrzNode
= mSerializersForNewObjs
.First();
380 wxSerializerInfo
* pSrzInfo
= (wxSerializerInfo
*)(pSrzNode
->Data());
382 if ( pSrzInfo
->HasInitializer() )
384 (*pSrzInfo
->initFn
)( pObjNode
->Data() );
386 pObjNode
= pObjNode
->Next();
387 pSrzNode
= pSrzNode
->Next();
391 // otherwise, nothing's need to be done after storing of objects is proceeded
395 // storage methods for basic types
397 void wxObjectStorage::XchgChar( char& chObj
)
399 if ( mIsLoading
) mpStm
->LoadChar( &chObj
);
400 else mpStm
->StoreChar( chObj
);
403 void wxObjectStorage::XchgInt( int& intObj
)
405 if ( mIsLoading
) mpStm
->LoadInt( &intObj
);
406 else mpStm
->StoreInt( intObj
);
409 void wxObjectStorage::XchgSizeType( size_t& szObj
)
415 mpStm
->LoadInt( &i
);
419 mpStm
->StoreInt( i
);
422 void wxObjectStorage::XchgLong( long& longObj
)
424 if ( mIsLoading
) mpStm
->LoadLong( &longObj
);
425 else mpStm
->StoreLong( longObj
);
428 void wxObjectStorage::XchgBool( bool& boolObj
)
430 // bools are stored as ints
434 int bVal
= (int)boolObj
;
435 mpStm
->LoadInt( &bVal
);
439 mpStm
->StoreInt( (int)boolObj
);
442 void wxObjectStorage::XchgUInt ( unsigned int& uI
)
447 mpStm
->LoadInt( &uiVal
);
448 uI
= (unsigned int)uiVal
;
451 mpStm
->StoreInt( (int)uI
);
454 void wxObjectStorage::XchgObjList( wxList
& objList
)
462 if ( count
== 0 ) return;
468 count
= objList
.GetCount();
473 // work-around for assessing operator[] which is protected in wxArrayBase
477 for( int i
= 0; i
!= count
; ++i
)
479 wxObject
* pObj
= NULL
;
483 objList
.Append( pObj
);
487 wxNode
* pNode
= objList
.First();
491 wxObject
* pObj
= pNode
->Data();
495 pNode
= pNode
->Next();
500 void wxObjectStorage::XchgObjArray ( wxBaseArray
& objArr
)
508 if ( count
== 0 ) return;
511 objArr
.Alloc( count
);
515 count
= objArr
.GetCount();
520 // work-around for assessing operator[] which is protected in wxArrayBase
522 wxArrayLong
& longArr
= *( (wxArrayLong
*) (&objArr
) );
526 for( int i
= 0; i
!= count
; ++i
)
528 wxObject
* pObj
= NULL
;
532 longArr
.Add( (long) pObj
);
535 for( int i
= 0; i
!= count
; ++i
)
537 wxObject
* pObj
= (wxObject
*)longArr
[i
];
543 void wxObjectStorage::XchgLongArray( wxBaseArray
& longArr
)
551 if ( count
== 0 ) return;
554 longArr
.Alloc( count
);
558 count
= longArr
.GetCount();
563 // work-around for assessing operator[] which is protected in wxArrayBase
565 wxArrayLong
& realLongArr
= *( (wxArrayLong
*) (&longArr
) );
569 for( int i
= 0; i
!= count
; ++i
)
574 realLongArr
.Add( l
);
577 for( int i
= 0; i
!= count
; ++i
)
579 XchgLong( realLongArr
[i
] );
582 void wxObjectStorage::XchgDouble( double& doubleObj
)
584 if ( mIsLoading
) mpStm
->LoadDouble( &doubleObj
);
585 else mpStm
->StoreDouble( doubleObj
);
588 void wxObjectStorage::XchgCStr( char* pCStrObj
)
593 mpStm
->LoadInt( &len
);
594 mpStm
->LoadBytes( pCStrObj
, len
);
598 int len
= strlen( pCStrObj
) + 1; // include terminating zero
599 mpStm
->StoreInt( len
);
600 mpStm
->StoreBytes( pCStrObj
, len
);
604 wxSerializerInfo
* wxObjectStorage::FindSrzInfoForClass( wxClassInfo
* pInfo
)
606 wxSerializerInfo
* pSrz
= (wxSerializerInfo
*)
608 wxSerializerInfo::serInfoHash
.Get( (long)pInfo
);
612 // look up recursivelly for serializers for of the base classes
614 if ( pInfo
->GetBaseClass1() )
616 return FindSrzInfoForClass( pInfo
->GetBaseClass1() );
618 if ( pInfo
->GetBaseClass2() )
620 return FindSrzInfoForClass( pInfo
->GetBaseClass2() );
623 wxASSERT(0); // DBG:: no serializers present for the given class,
624 // serialization cannot proceed
632 bool wxObjectStorage::VersionsMatch( char* v1
, char* v2
)
636 if ( *v1
== mMinorMajorSepartorCh
||
637 *v2
== mMinorMajorSepartorCh
)
639 // minor versions are ignored
643 if ( toupper(*v1
) != toupper(*v2
) )
650 return ( *v1
== '\0' && *v2
== '\0' );
653 bool wxObjectStorage::ExchangeObjectInfo( wxClassInfo
** ppCInfo
, wxSerializerInfo
** ppSrz
)
655 char objInfoStr
[512]; // FOR NOW:: fixed?
657 if ( mIsLoading
== FALSE
)
659 strcpy( objInfoStr
, (*ppCInfo
)->GetClassName() );
661 if ( (*ppSrz
)->HasVersion() )
664 separator
[2] = mVerSepartorCh
;
667 strcat( objInfoStr
, separator
);
669 strcat( objInfoStr
, (*ppSrz
)->classVersion
);
672 XchgCStr( objInfoStr
);
677 // otherwise if loading...
679 XchgCStr( objInfoStr
); // read string
684 // formal description of objInfoStr format is following (if '#' and '-' are set
685 // as version and minor/major separators):
687 // object objInfoStr = { class_name_str , [version] }
689 // version = { '#', simple_version_str | major_and_minor_version_str }
691 // simple_version_str = any_literal
693 // major_and_minro_version_str = { major_version_str, '-', minro_version_str }
695 // major_version_str = any_literal
697 // inor_version_str = any_literal
699 // any_literal = "any string not containing '#' and '-' characters"
702 char* cur
= objInfoStr
;
704 while( *cur
&& *cur
!= mVerSepartorCh
) ++cur
;
708 if ( last
== mVerSepartorCh
)
712 (*ppCInfo
) = wxClassInfo::FindClass( objInfoStr
);
714 if ( !(*ppCInfo
) ) return FALSE
;
716 // get the bigining of the chain of serializers for (*ppCInfo)
718 wxSerializerInfo
* pSrz
= FindSrzInfoForClass( (*ppCInfo
) );
720 if ( last
== mVerSepartorCh
) *cur
= last
; // restore from temprary "termination"
722 // find serializer which matches the version, or the serializer
723 // with no version, if version is not attached to the objInfoStr
727 // there's no version trailing, the "not-versioned"
728 // serializer can be present only at the begining of
731 if ( pSrz
->HasVersion() == FALSE
)
741 ++cur
; // skip className<->version separator
743 // version present, search for matching serializer down the chain
745 if ( pSrz
->HasVersion() == FALSE
) pSrz
= pSrz
->nextByVersion
;
749 if ( VersionsMatch( pSrz
->classVersion
, cur
) )
756 pSrz
= pSrz
->nextByVersion
;
759 return FALSE
; // no serializers matching given version found
762 wxSerializerInfo
* wxObjectStorage::GetLatestSrzForObj( wxObject
* pWxObj
)
764 wxClassInfo
* pCInfo
= pWxObj
->GetClassInfo();
766 wxASSERT( pCInfo
); // DBG:: object's class should be dynamic
768 // find first serializer for (*pCInfo) in the chain
770 wxSerializerInfo
* pSrz
= FindSrzInfoForClass( pCInfo
);
772 wxASSERT( pSrz
); // DBG:: there should be at least one serializer of
773 // the object's class, at least for it's base classes
775 // skip not-versioned serializer at the beginng of the chain if present
777 if ( !pSrz
->HasVersion() && pSrz
->nextByVersion
)
779 pSrz
= pSrz
->nextByVersion
; // the reminding ones are "vesioned",
780 // starting from the highest version
785 void wxObjectStorage::DoExchangeObject( wxObject
* pInstance
, wxSerializerInfo
& srzInfo
)
789 // put info about already (partially) loaded object (stream-offset <=> object-ptr )
791 mRefHash
.Put( (long)mpStm
->GetStreamPos(), (wxObject
*)pInstance
);
793 // put info about already (partially) stored object (object-ptr <=> stream-offset)
795 mRefHash
.Put( (long)(pInstance
), (wxObject
*)mpStm
->GetStreamPos() );
799 mNewObjs
.Append( pInstance
);
800 mSerializersForNewObjs
.Append( (wxObject
*)&srzInfo
);
803 // now, perform actual serialization of the object
805 (srzInfo
.serFn
)( pInstance
, *this );
808 // storage methods for objects and object-references
810 void wxObjectStorage::XchgObj( wxObject
* pWxObj
)
812 wxClassInfo
* pCInfo
= pWxObj
->GetClassInfo();
814 wxASSERT( pCInfo
); // DBG:: if this fails, the object which is passed to
815 // XchgObj(..) has not it's class information
816 // i.e. is not a wxWindows dynamic class
818 wxSerializerInfo
* pSrz
= ( mIsLoading
== FALSE
) ? GetLatestSrzForObj( pWxObj
)
821 bool success
= ExchangeObjectInfo( &pCInfo
, &pSrz
);
823 wxASSERT( success
); // DBG:: all info about object should be present i.e. class
824 // info, serializer which matches the object's version
825 // (see source of ExchangeObjectInfo() for more info)
827 DoExchangeObject( pWxObj
, *pSrz
);
830 void wxObjectStorage::XchgObjPtr( wxObject
** ppWxObj
)
835 mpStm
->LoadChar( &token
);
837 if ( token
== (char)SOT_NULL_POINTER
)
841 if ( token
== (char)SOT_POINTER_TO_OBJ
)
843 long ofs
; // stream-offset
845 mpStm
->LoadLong( &ofs
);
847 wxObject
* pObj
= (wxObject
*) mRefHash
.Get( ofs
);
849 wxASSERT( pObj
); // DBG:: object (at the given stream-offset)
850 // must be already loaded
855 if ( token
== (char)SOT_INITIAL_REF
)
859 mpStm
->LoadLong( &refNo
);
861 wxASSERT( mInitialRefsCnt
>= refNo
); // DBG:: inital refernce should be already added
864 (*ppWxObj
) = mInitialRefs
.Nth( refNo
-1 )->Data();
868 wxASSERT( token
== (char)SOT_OBJ_DATA
);// DBG:: other types of tokens are
869 // bogous! If this happens you're
870 // probably trying to load the data
871 // which was stored by defferent.
872 // perhaps out-dated serializers
874 // Use versioning mechanizm to
875 // privide backwards compatiblity
876 // option, among different versions
877 // stored data-format
880 int stmPos
= mpStm
->GetStreamPos();
882 wxClassInfo
* pCInfo
= 0;
883 wxSerializerInfo
* pSrz
= 0;
885 bool success
= ExchangeObjectInfo( &pCInfo
, &pSrz
);
887 wxASSERT( success
); // DBG:: all info about object should be present
888 // i.e. class info, serializer which matches the object's
889 // version (see source of ExchangeObjectInfo() for more info)
891 (*ppWxObj
) = pCInfo
->CreateObject();
893 DoExchangeObject( (*ppWxObj
), *pSrz
);
898 // otherwise if storing the pointer to an object
900 // first, check if it's an initial reference
902 long refNo
= (long)mInitialRefsHash
.Get( (long)(*ppWxObj
) );
906 mpStm
->StoreChar( (char)SOT_INITIAL_REF
);
907 mpStm
->StoreLong( refNo
);
912 long streamPos
= (long) mRefHash
.Get( (long)(*ppWxObj
) );
914 // check if object is already stored
915 if ( streamPos
!= 0 )
917 // store only reference to the object (in the form of stream-offset)
919 mpStm
->StoreChar( (char)SOT_POINTER_TO_OBJ
);
920 mpStm
->StoreLong( streamPos
);
924 // otherwise store the entire referenced object
926 if ( (*ppWxObj
) == NULL
)
928 mpStm
->StoreChar( (char)SOT_NULL_POINTER
); // token
932 mpStm
->StoreChar( (char)SOT_OBJ_DATA
); // token
934 // store object's info and data
940 // storage methods for common wxWindows objects
942 void wxObjectStorage::XchgWxStr( wxString
& str
)
947 mpStm
->LoadLong( &len
);
950 str
.Append( (char)1, len
);
952 mpStm
->LoadBytes( (char*)str
.c_str(), len
);
955 XchgCStr( (char*)str
.c_str() );
958 void wxObjectStorage::XchgWxSize( wxSize
& size
)
964 void wxObjectStorage::XchgWxPoint( wxPoint
& point
)
970 void wxObjectStorage::XchgWxRect( wxRect
& rect
)
974 XchgLong( rect
.width
);
975 XchgLong( rect
.height
);
978 void wxObjectStorage::AddInitialRef( wxObject
* pObjRef
)
980 // duplicates are not accepted
982 if ( mInitialRefsHash
.Get( (long)pObjRef
) != NULL
)
988 // NOTE:: reference number is 1-based (zero is "reserved" by wxHashTable)
990 mInitialRefs
.Append( pObjRef
);
991 mInitialRefsHash
.Put( (long)pObjRef
, (wxObject
*)mInitialRefsCnt
);
994 void wxObjectStorage::ClearInitalRefs()
998 mInitialRefsHash
.Clear();
999 mInitialRefsHash
.Clear();
1002 /***** Implementation for class wxColourSerializer *****/
1004 IMPLEMENT_SERIALIZER_CLASS( wxColour
,
1006 wxColourSerializer::Serialize
,
1009 void wxColourSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1011 wxColour
* pCol
= (wxColour
*)pObj
;
1013 // slightly optimized
1015 if ( store
.IsLoading() )
1018 store
.XchgLong( rgb
);
1020 *pCol
= wxColour( rgb
& 0xFF,
1021 ( rgb
>> 8 ) & 0xFF,
1022 ( rgb
>> 16 ) & 0xFF );
1029 unsigned char r
= pCol
->Red(),g
= pCol
->Green(), b
= pCol
->Blue();
1031 rgb
= ( long(r
) & 0x0000FF ) |
1032 ( ( long(g
) << 8 ) & 0x00FF00 ) |
1033 ( ( long(b
) << 16 ) & 0xFF0000 );
1035 store
.XchgLong( rgb
);
1039 /***** Implementation for class wxPenSerializer *****/
1041 IMPLEMENT_SERIALIZER_CLASS( wxPen
,
1043 wxPenSerializer::Serialize
,
1046 void wxPenSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1048 wxPen
* pPen
= (wxPen
*)pObj
;
1056 if ( store
.IsLoading() == FALSE
)
1058 cap
= pPen
->GetCap();
1059 col
= pPen
->GetColour();
1060 join
= pPen
->GetJoin();
1061 style
= pPen
->GetStyle();
1062 width
= pPen
->GetWidth();
1065 store
.XchgInt( cap
);
1066 store
.XchgObj( (wxObject
*) &col
);
1067 store
.XchgInt( join
);
1068 store
.XchgInt( style
);
1069 store
.XchgInt( width
);
1071 if ( store
.IsLoading() )
1073 pPen
->SetCap ( cap
);
1074 pPen
->SetColour( col
);
1075 pPen
->SetJoin ( join
);
1076 pPen
->SetStyle ( style
);
1077 pPen
->SetWidth ( width
);
1081 /***** Implementation for class wxBrushSerializer *****/
1083 IMPLEMENT_SERIALIZER_CLASS( wxBrush
,
1085 wxBrushSerializer::Serialize
,
1088 void wxBrushSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1090 wxBrush
* pBrush
= (wxBrush
*)pObj
;
1095 if ( store
.IsLoading() == FALSE
)
1097 col
= pBrush
->GetColour();
1098 style
= pBrush
->GetStyle();
1101 store
.XchgObj( (wxObject
*) &col
);
1102 store
.XchgInt( style
);
1104 if ( store
.IsLoading() )
1106 pBrush
->SetColour( col
);
1107 pBrush
->SetStyle ( style
);
1111 /***** Implementation for class wxEvtHandlerSerializer *****/
1113 IMPLEMENT_SERIALIZER_CLASS( wxEvtHandler
,
1114 wxEvtHandlerSerializer
,
1115 wxEvtHandlerSerializer::Serialize
,
1116 wxEvtHandlerSerializer::Initialize
)
1118 void wxEvtHandlerSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1120 wxEvtHandler
* pHnd
= ( wxEvtHandler
*) pObj
;
1122 wxEvtHandler
* pPrevHnd
;
1123 wxEvtHandler
* pNextHnd
;
1125 if ( store
.IsLoading() == FALSE
)
1127 // extract properties when storing
1129 pPrevHnd
= pHnd
->GetPreviousHandler();
1130 pNextHnd
= pHnd
->GetNextHandler();
1133 // serialize properties
1135 store
.XchgObjPtr( (wxObject
**) &pPrevHnd
);
1136 store
.XchgObjPtr( (wxObject
**) &pNextHnd
);
1138 if ( store
.IsLoading() )
1140 // set properties when loading
1142 pHnd
->SetPreviousHandler( pPrevHnd
);
1143 pHnd
->SetNextHandler ( pNextHnd
);
1147 void wxEvtHandlerSerializer::Initialize( wxObject
* pObj
)
1149 wxEvtHandler
* pHnd
= ( wxEvtHandler
*) pObj
;
1152 if ( pHnd
->GetPreviousHandler() == NULL
)
1154 // then check if we're in the chain which is
1155 // attached to wxWindow object
1157 wxEvtHandler
* pCur
= pHnd
->GetNextHandler();
1161 if ( pCur
->IsKindOf( CLASSINFO(wxWindow
) ) )
1163 // since we are the the right-most event handler
1164 // in the chain, then we must be the first
1165 // receiver of events sent to the window obj. -
1166 // therefore "make it happen":
1168 ((wxWindow
*)pCur
)->SetEventHandler( pHnd
);
1170 // but if wxWindow is persistant, then why
1171 // we're setting "manually" the property
1172 // which is serialized anyway?
1174 // The *PROBLEM* is that, it's not always good idea
1175 // to serialize a window (e.g. main frame), instead
1176 // they could be referred by "inital-refernces". To
1177 // handle the later case, we additionally make sure
1178 // that serialized evt. handlers are "glued" to the
1179 // window correctly,even if the window is transient
1185 // keep on searching for wxWindows down the chain
1187 pCur
= pCur
->GetNextHandler();
1192 /***** Implementation for class wxWindowSerializer *****/
1194 IMPLEMENT_SERIALIZER_CLASS( wxWindow
,
1196 wxWindowSerializer::Serialize
,
1199 void wxWindowSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1201 DoSerialize( pObj
, store
, (wndCreationFn
)wxWindowSerializer::CreateWindowFn
);
1204 void wxWindowSerializer::DoSerialize( wxObject
* pObj
, wxObjectStorage
& store
,
1205 wndCreationFn creationFn
, bool refreshNow
)
1207 // wxWindow is a kind of wxEvtHandler - peform serialization of
1208 // the base class first
1210 info
.SerializeInherited( pObj
, store
);
1212 wxWindow
* pWnd
= (wxWindow
*)pObj
;
1222 wxEvtHandler
* pEvtHandler
;
1226 if ( store
.IsLoading() == FALSE
)
1228 // extract properties from window object
1230 name
= pWnd
->GetName();
1232 style
= pWnd
->GetWindowStyleFlag();
1234 // workaround for long/int inconsitency of wxWin2.0a
1236 pWnd
->GetPosition( &x
, &y
);
1237 pWnd
->GetSize ( &w
, &h
);
1238 bkCol
= pWnd
->GetBackgroundColour();
1240 pos
.x
= x
; pos
.y
= y
;
1241 size
.x
= w
; size
.y
= h
;
1243 pEvtHandler
= pWnd
->GetEventHandler();
1244 pParent
= pWnd
->GetParent();
1246 #ifdef __HACK_MY_MSDEV40__
1247 pCldLst
= pWnd
->GetChildren();
1249 pCldLst
= &pWnd
->GetChildren();
1254 // serialize properties
1256 store
.XchgWxStr ( name
);
1257 store
.XchgLong ( id
);
1258 store
.XchgLong ( style
);
1259 store
.XchgLong ( pos
.x
);
1260 store
.XchgLong ( pos
.y
);
1261 store
.XchgLong ( size
.x
);
1262 store
.XchgLong ( size
.y
);
1263 store
.XchgObj ( (wxObject
* ) &bkCol
);
1264 store
.XchgObjPtr( (wxObject
**) &pParent
);
1265 store
.XchgObjPtr( (wxObject
**) &pEvtHandler
);
1267 if ( store
.IsLoading() )
1270 // serialize to on-stack list object, since children will
1271 // automatically add themselves to parent's list
1273 pCldLst
= &tmpCldLst
;
1275 // first create window (when loading), then serialize it's children
1277 (*creationFn
)( pWnd
, pParent
, id
, pos
, size
, style
, name
);
1279 //pWnd->SetBackgroundColour( bkCol );
1281 //pWnd->SetBackgroundColour( bkCol );
1283 if ( refreshNow
&& 0 ) pWnd
->Refresh();
1286 store
.XchgObjList( *pCldLst
);
1289 void wxWindowSerializer::CreateWindowFn( wxWindow
* wnd
, wxWindow
* parent
, const wxWindowID id
,
1290 const wxPoint
& pos
, const wxSize
& size
, long style
,
1291 const wxString
& name
)
1293 wnd
->Create( parent
, id
, pos
, size
, style
, name
);
1296 /***** Implementation for class wxTextCtrlSerializer *****/
1298 IMPLEMENT_SERIALIZER_CLASS( wxTextCtrl
,
1299 wxTextCtrlSerializer
,
1300 wxTextCtrlSerializer::Serialize
,
1303 void wxTextCtrlSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1305 wxTextCtrl
* pCtrl
= (wxTextCtrl
*)pObj
;
1307 wxWindowSerializer::DoSerialize( pObj
, store
,
1308 (wndCreationFn
)wxTextCtrlSerializer::CreateTextCtrlWindowFn
);
1312 if ( store
.IsLoading() == FALSE
)
1314 text
= pCtrl
->GetValue();
1316 store
.XchgWxStr( text
);
1318 if ( store
.IsLoading() )
1320 pCtrl
->SetValue( text
);
1323 void wxTextCtrlSerializer::CreateTextCtrlWindowFn( wxTextCtrl
* wnd
, wxWindow
* parent
, const wxWindowID id
,
1324 const wxPoint
& pos
, const wxSize
& size
, long style
,
1325 const wxString
& name
)
1327 wnd
->Create( parent
, id
, "", pos
, size
, style
);
1329 // FIXME:: quick-hack
1330 wnd
->SetBackgroundColour( wxColour(255,255,255) );
1333 /***** Implementation for class wxButtonSerializer *****/
1335 IMPLEMENT_SERIALIZER_CLASS( wxButton
,
1337 wxButtonSerializer::Serialize
,
1340 void wxButtonSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1342 wxButton
* pBtn
= (wxButton
*)pObj
;
1344 wxWindowSerializer::DoSerialize( pObj
, store
,
1345 (wndCreationFn
)wxButtonSerializer::CreateButtonWindowFn
);
1349 if ( store
.IsLoading() == FALSE
)
1351 label
= pBtn
->GetLabel();
1353 store
.XchgWxStr( label
);
1355 if ( store
.IsLoading() )
1357 pBtn
->SetLabel( label
);
1360 void wxButtonSerializer::CreateButtonWindowFn( wxButton
* btn
, wxWindow
* parent
, const wxWindowID id
,
1361 const wxPoint
& pos
, const wxSize
& size
, long style
,
1362 const wxString
& name
)
1364 btn
->Create( parent
, id
, "", pos
, size
, style
);
1367 /***** Implementation for class wxStaticTextSerializer *****/
1369 IMPLEMENT_SERIALIZER_CLASS( wxStaticText
,
1370 wxStaticTextSerializer
,
1371 wxStaticTextSerializer::Serialize
,
1374 void wxStaticTextSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1376 wxStaticText
* pSTxt
= (wxStaticText
*)pObj
;
1378 wxWindowSerializer::DoSerialize( pObj
, store
,
1379 (wndCreationFn
)wxStaticTextSerializer::CreateSTextWindowFn
);
1383 if ( store
.IsLoading() == FALSE
)
1385 label
= pSTxt
->GetLabel();
1387 store
.XchgWxStr( label
);
1389 if ( store
.IsLoading() )
1391 pSTxt
->SetLabel( label
);
1394 void wxStaticTextSerializer::CreateSTextWindowFn( wxStaticText
* pSTxt
, wxWindow
* parent
, const wxWindowID id
,
1395 const wxPoint
& pos
, const wxSize
& size
, long style
,
1396 const wxString
& name
)
1398 pSTxt
->Create( parent
, id
, "", pos
, size
, style
);
1401 /***** Implementation for class wxScrollBarSerializer *****/
1403 IMPLEMENT_SERIALIZER_CLASS( wxScrollBar
,
1404 wxScrollBarSerializer
,
1405 wxScrollBarSerializer::Serialize
,
1408 void wxScrollBarSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1410 wxWindowSerializer::DoSerialize( pObj
, store
,
1411 (wndCreationFn
)wxScrollBarSerializer::CreateScollBarWindowFn
);
1414 void wxScrollBarSerializer::CreateScollBarWindowFn( wxScrollBar
* sbar
, wxWindow
* parent
, const wxWindowID id
,
1415 const wxPoint
& pos
, const wxSize
& size
, long style
,
1416 const wxString
& name
)
1418 sbar
->Create( parent
, id
, pos
, size
, style
);
1421 // FIXME:: serialization of tree control causes bunch of assertions on wxGtk
1425 /***** Implementation for class wxTreeCtrlSerializer *****/
1427 IMPLEMENT_SERIALIZER_CLASS( wxTreeCtrl
,
1428 wxTreeCtrlSerializer
,
1429 wxTreeCtrlSerializer::Serialize
,
1432 static bool get_child_count( wxTreeItemId itemId
, wxTreeCtrl
* pTree
)
1436 if ( !pTree
->ItemHasChildren( itemId
) ) return 0;
1438 wxTreeItemId curId
= pTree
->GetFirstChild( itemId
, cookie
);
1446 curId
= pTree
->GetNextChild( itemId
, cookie
);
1453 void wxTreeCtrlSerializer::SerializeBranch( wxTreeItemId parentId
, wxTreeCtrl
* pTree
,
1454 wxObjectStorage
& store
, wxTreeItemId nextVisId
,
1463 if ( store
.IsLoading() )
1465 store
.XchgWxStr( text
);
1466 store
.XchgInt ( childCnt
);
1467 store
.XchgInt ( img
);
1468 store
.XchgBool ( isExpanded
);
1469 store
.XchgBool ( isVisible
);
1471 wxTreeItemId subBranchId
=
1473 ? pTree
->AddRoot( text
, img
)
1474 : pTree
->AppendItem( parentId
, text
, img
);
1476 // check if the item was labeled as first-visible
1480 nextVisId
= subBranchId
;
1482 while ( childCnt
-- )
1484 SerializeBranch( subBranchId
, pTree
, store
, nextVisId
, depth
+1 );
1486 if ( isExpanded
) pTree
->Expand( subBranchId
);
1487 else pTree
->Collapse( subBranchId
);
1492 // otherwise storing children of the branch
1494 text
= pTree
->GetItemText( parentId
);
1495 childCnt
= get_child_count( parentId
, pTree
);
1496 img
= pTree
->GetItemImage( parentId
);
1497 isExpanded
= pTree
->IsExpanded( parentId
);
1499 if ( parentId
== nextVisId
)
1505 store
.XchgWxStr( text
);
1506 store
.XchgInt ( childCnt
);
1507 store
.XchgInt ( img
);
1508 store
.XchgBool ( isExpanded
);
1509 store
.XchgBool ( isVisible
);
1513 wxTreeItemId curId
= pTree
->GetFirstChild( parentId
, cookie
);
1515 while ( childCnt
-- )
1517 SerializeBranch( curId
, pTree
, store
, nextVisId
, -1 );
1519 curId
= pTree
->GetNextChild( parentId
, cookie
);
1524 void wxTreeCtrlSerializer::Serialize( wxObject
* pObj
, wxObjectStorage
& store
)
1526 // FOR NOW::image id's and image list are not serialized!
1527 // it should be provided as a initial reference (IR)
1528 // if it presents. Currently only normal image list
1529 // for normal items-states is set up
1531 wxTreeCtrl
* pTree
= (wxTreeCtrl
*)pObj
;
1533 wxWindowSerializer::DoSerialize( pObj
, store
,
1534 (wndCreationFn
)wxTreeCtrlSerializer::CreateTreeCtrlWindowFn
);
1536 wxTreeItemId nextVisId
= (long)0;
1541 if ( store
.IsLoading() )
1543 store
.XchgInt( indent
);
1545 store
.XchgObjPtr( (wxObject
**) &(pILst
) );
1549 pTree
->SetImageList( pILst
);
1551 store
.XchgInt( childCnt
);
1553 while ( childCnt
-- )
1555 SerializeBranch( pTree
->GetRootItem() , pTree
, store
, nextVisId
, 0 );
1557 // FIXME:: somehow this is no longer inmplemented in latest wxWin-2.0
1558 // pTree->ScrollTo( nextVisId );
1560 pTree
->SetIndent( indent
);
1564 indent
= pTree
->GetIndent();
1566 // FIXME:: somehow this is no longer inmplemented in latest wxWin-2.0
1567 // nextVisId = pTree->GetFirstVisibleItem();
1569 nextVisId
= pTree
->GetRootItem();
1571 pILst
= pTree
->GetImageList();
1573 store
.XchgInt( indent
);
1575 store
.XchgObjPtr( (wxObject
**) &(pILst
) );
1577 // otherwise storing children of the branch
1579 childCnt
= get_child_count( pTree
->GetRootItem(), pTree
);
1581 store
.XchgInt( childCnt
);
1584 wxTreeItemId parent
= pTree
->GetRootItem();
1585 wxTreeItemId curId
= pTree
->GetFirstChild( parent
, cookie
);
1587 while ( childCnt
-- )
1589 SerializeBranch( curId
, pTree
, store
, nextVisId
, -1 );
1591 curId
= pTree
->GetNextChild( parent
, cookie
);
1596 void wxTreeCtrlSerializer::CreateTreeCtrlWindowFn( wxTreeCtrl
* tree
, wxWindow
* parent
, const wxWindowID id
,
1597 const wxPoint
& pos
, const wxSize
& size
, long style
,
1598 const wxString
& name
)
1600 tree
->Create( parent
, id
, pos
, size
, style
);
1605 /***** Implementation for class wxIOStreamWrapper *****/
1607 IMPLEMENT_DYNAMIC_CLASS( wxIOStreamWrapper
, wxDataStreamBase
)
1609 void wxIOStreamWrapper::Close()
1611 // close previous stream if any
1616 if ( mOwnsStmObject
)
1620 mOwnsStmObject
= FALSE
;
1628 wxIOStreamWrapper::wxIOStreamWrapper()
1630 mOwnsStmObject( FALSE
),
1633 mIsForInput
= TRUE
; // just a defaul
1636 bool wxIOStreamWrapper::Create( const char* fileName
, bool forInput
)
1640 // FIXME:: if using default value of the last arg, linking breaks complaining
1641 // about duplicated symbols
1644 mpStm
= new fstream( fileName
,
1645 ( ( forInput
== FALSE
) ? ios::out
: ios::in
) | ios::binary
,
1649 mpStm
= new fstream( fileName
,
1650 ( ( forInput
== FALSE
) ? ios::out
: ios::in
) | ios::binary
1654 //((fstream*)mpStm)->close();
1656 //delete ((fstream*)mpStm);
1658 mOwnsStmObject
= TRUE
;
1666 mIsForInput
= forInput
;
1671 wxIOStreamWrapper::wxIOStreamWrapper( iostream
& stm
, bool forInput
)
1672 : mOwnsStmObject( FALSE
)
1676 // FIXME:: what about actual stream postion of attached stream?
1679 mIsForInput
= forInput
;
1682 void wxIOStreamWrapper::Attach( iostream
& stm
, bool forInput
)
1686 mOwnsStmObject
= FALSE
;
1690 // FIXME:: what about actual stream postion of attached stream?
1693 mIsForInput
= forInput
;
1696 wxIOStreamWrapper::~wxIOStreamWrapper()
1701 bool wxIOStreamWrapper::StoreChar( char ch
)
1703 mpStm
->write( &ch
, sizeof(char) );
1705 mStreamPos
+= sizeof(char);
1710 bool wxIOStreamWrapper::StoreInt( int i
)
1712 mpStm
->write( (char*)&i
, sizeof(int) );
1714 mStreamPos
+= sizeof(int);
1719 bool wxIOStreamWrapper::StoreLong( long l
)
1721 mpStm
->write( (char*)&l
, sizeof(long) );
1723 mStreamPos
+= sizeof(long);
1728 bool wxIOStreamWrapper::StoreDouble( double d
)
1730 mpStm
->write( (char*)&d
, sizeof(double) );
1732 mStreamPos
+= sizeof(double);
1737 bool wxIOStreamWrapper::StoreBytes( void* bytes
, int count
)
1739 mpStm
->write( (char*)bytes
, count
);
1741 mStreamPos
+= count
;
1746 bool wxIOStreamWrapper::LoadChar( char* pCh
)
1748 mpStm
->read( pCh
, sizeof(char) );
1750 mStreamPos
+= sizeof(char);
1755 bool wxIOStreamWrapper::LoadInt( int* pI
)
1757 mpStm
->read( (char*)pI
, sizeof(int) );
1759 mStreamPos
+= sizeof(int);
1764 bool wxIOStreamWrapper::LoadLong( long* pL
)
1766 mpStm
->read( (char*)pL
, sizeof(long) );
1768 mStreamPos
+= sizeof(long);
1773 bool wxIOStreamWrapper::LoadDouble( double* pD
)
1775 mpStm
->read( (char*)pD
, sizeof(double) );
1777 mStreamPos
+= sizeof(double);
1782 bool wxIOStreamWrapper::LoadBytes ( void* pBytes
, int count
)
1784 mpStm
->read( (char*)pBytes
, count
);
1786 mStreamPos
+= count
;
1791 bool wxIOStreamWrapper::Flush()
1798 long wxIOStreamWrapper::GetStreamPos()
1803 bool wxIOStreamWrapper::Good()
1805 // FIXME FIXME:: somehow, when using ios::good/ios::bad, linking breaks complaining
1806 // about "ios::bad" already defined in this object file...