]> git.saurik.com Git - wxWidgets.git/blame - src/common/xtistrm.cpp
constness for accessors of enum data
[wxWidgets.git] / src / common / xtistrm.cpp
CommitLineData
70e88103
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/xtistrm.cpp
2abce515 3// Purpose: streaming runtime metadata information
70e88103 4// Author: Stefan Csomor
2abce515 5// Modified by:
70e88103
SC
6// Created: 27/07/03
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
70e88103
SC
13#pragma implementation "xtistrm.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
16776ad9
SC
24#include "wx/hash.h"
25#include "wx/object.h"
70e88103
SC
26#endif
27
70e88103 28#include "wx/tokenzr.h"
70e88103 29#include "wx/txtstrm.h"
9c8046dd 30#include "wx/event.h"
70e88103
SC
31
32#if wxUSE_EXTENDED_RTTI
ab6e4913 33
8347b97a
SC
34#include "wx/xtistrm.h"
35
ab6e4913 36#include "wx/beforestd.h"
70e88103
SC
37#include <map>
38#include <vector>
39#include <string>
ab6e4913 40#include "wx/afterstd.h"
70e88103
SC
41
42using namespace std ;
43
16776ad9
SC
44struct wxWriter::wxWriterInternal
45{
46 map< const wxObject* , int > m_writtenObjects ;
47 int m_nextId ;
48} ;
49
50wxWriter::wxWriter()
51{
52 m_data = new wxWriterInternal ;
53 m_data->m_nextId = 0 ;
54}
55
56wxWriter::~wxWriter()
57{
58 delete m_data ;
59}
60
61struct wxWriter::wxWriterInternalPropertiesData
62{
cb73e600 63 char nothing ;
16776ad9
SC
64} ;
65
ab6e4913
SC
66void wxWriter::ClearObjectContext()
67{
68 delete m_data ;
69 m_data = new wxWriterInternal() ;
70 m_data->m_nextId = 0 ;
71}
72
4f8ffae1 73void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , const wxString &name , wxxVariantArray &metadata )
16776ad9 74{
ab6e4913 75 DoBeginWriteTopLevelEntry( name ) ;
4f8ffae1 76 WriteObject( object , classInfo , persister , false , metadata) ;
ab6e4913
SC
77 DoEndWriteTopLevelEntry( name ) ;
78}
79
4f8ffae1 80void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , bool isEmbedded, wxxVariantArray &metadata )
ab6e4913 81{
9c8046dd 82 if ( !classInfo->BeforeWriteObject( object , this , persister , metadata) )
c90b8250
SC
83 return ;
84
4f8ffae1 85 if ( persister->BeforeWriteObject( this , object , classInfo , metadata) )
16776ad9 86 {
ab6e4913
SC
87 if ( object == NULL )
88 DoWriteNullObject() ;
89 else if ( IsObjectKnown( object ) )
90 DoWriteRepeatedObject( GetObjectID(object) ) ;
2d51f067
SC
91 else
92 {
93 int oid = m_data->m_nextId++ ;
ab6e4913
SC
94 if ( !isEmbedded )
95 m_data->m_writtenObjects[object] = oid ;
96
2d51f067
SC
97 // in case this object is a wxDynamicObject we also have to insert is superclass
98 // instance with the same id, so that object relations are streamed out correctly
99 const wxDynamicObject* dynobj = dynamic_cast<const wxDynamicObject *>( object ) ;
ab6e4913 100 if ( !isEmbedded && dynobj )
2d51f067
SC
101 m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid ;
102
4f8ffae1 103 DoBeginWriteObject( object , classInfo , oid , metadata ) ;
2d51f067
SC
104 wxWriterInternalPropertiesData data ;
105 WriteAllProperties( object , classInfo , persister , &data ) ;
ab6e4913 106 DoEndWriteObject( object , classInfo , oid ) ;
2d51f067 107 }
ab6e4913 108 persister->AfterWriteObject( this ,object , classInfo ) ;
16776ad9
SC
109 }
110}
111
9c8046dd 112void wxWriter::FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler)
ab6e4913
SC
113{
114 wxList *dynamicEvents = evSource->GetDynamicEventTable() ;
115
116 if ( dynamicEvents )
117 {
118 wxList::compatibility_iterator node = dynamicEvents->GetFirst();
119 while (node)
120 {
121 wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
122
123 // find the match
2abce515 124 if ( entry->m_fn &&
9c8046dd
SC
125 (dti->GetEventType() == entry->m_eventType) &&
126 (entry->m_id == -1 ) &&
127 (entry->m_eventSink != NULL ) )
ab6e4913
SC
128 {
129 sink = entry->m_eventSink ;
130 const wxClassInfo* sinkClassInfo = sink->GetClassInfo() ;
131 const wxHandlerInfo* sinkHandler = sinkClassInfo->GetFirstHandler() ;
132 while ( sinkHandler )
133 {
134 if ( sinkHandler->GetEventFunction() == entry->m_fn )
135 {
136 handler = sinkHandler ;
137 break ;
138 }
139 sinkHandler = sinkHandler->GetNext() ;
140 }
141 break ;
142 }
143 node = node->GetNext();
144 }
145 }
146}
16776ad9
SC
147void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data )
148{
cb73e600
SC
149 wxPropertyInfoMap map ;
150 ci->GetProperties( map ) ;
151 for ( int i = 0 ; i < ci->GetCreateParamCount() ; ++i )
16a45a23 152 {
cb73e600
SC
153 wxString name = ci->GetCreateParamName(i) ;
154 const wxPropertyInfo* prop = map.find(name)->second ;
155 wxASSERT_MSG( prop , wxT("Create Parameter not found in declared RTTI Parameters") ) ;
156 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
157 map.erase( name ) ;
158 }
159
160 for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
161 {
162 const wxPropertyInfo* prop = iter->second ;
163 if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
164 {
165 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
166 }
167 }
168
169 for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
170 {
171 const wxPropertyInfo* prop = iter->second ;
172 if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
16a45a23 173 {
cb73e600 174 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
16a45a23
SC
175 }
176 }
cb73e600
SC
177}
178
2abce515 179void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *WXUNUSED(data) )
cb73e600 180{
9c8046dd
SC
181 if ( pi->GetFlags() & wxPROP_DONT_STREAM )
182 return ;
183
cb73e600
SC
184 // make sure that we are picking the correct object for accessing the property
185 const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (obj ) ;
186 if ( dynobj && (dynamic_cast<const wxDynamicClassInfo*>(ci) == NULL) )
187 obj = dynobj->GetSuperClassInstance() ;
16a45a23 188
cb73e600 189 if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
16776ad9 190 {
cb73e600
SC
191 wxxVariantArray data ;
192 pi->GetAccessor()->GetPropertyCollection(obj, data) ;
193 const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ;
194 for ( size_t i = 0 ; i < data.GetCount() ; ++i )
16776ad9 195 {
ed45345e
SC
196 if ( i == 0 )
197 DoBeginWriteProperty( pi ) ;
198
cb73e600
SC
199 DoBeginWriteElement() ;
200 wxxVariant value = data[i] ;
201 if ( persister->BeforeWriteProperty( this , pi , value ) )
16776ad9 202 {
cb73e600
SC
203 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ;
204 if ( cti )
16776ad9 205 {
cb73e600
SC
206 const wxClassInfo* pci = cti->GetClassInfo() ;
207 wxObject *vobj = pci->VariantToInstance( value ) ;
208 wxxVariantArray md ;
209 WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md ) ;
16776ad9 210 }
cb73e600 211 else
16776ad9 212 {
2abce515 213 DoWriteSimpleType( value ) ;
cb73e600
SC
214 }
215 }
216 DoEndWriteElement() ;
ed45345e
SC
217 if ( i == data.GetCount() - 1 )
218 DoEndWriteProperty( pi ) ;
219 }
220 }
cb73e600
SC
221 else
222 {
223 const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
224 if ( dti )
225 {
226 const wxObject* sink = NULL ;
227 const wxHandlerInfo *handler = NULL ;
ab6e4913 228
9c8046dd
SC
229 const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ;
230 wxASSERT_MSG( evSource , wxT("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ;
a315dda6 231
cb73e600
SC
232 FindConnectEntry( evSource , dti , sink , handler ) ;
233 if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
234 {
235 if ( sink != NULL && handler != NULL )
236 {
ed45345e 237 DoBeginWriteProperty( pi ) ;
cb73e600
SC
238 wxASSERT_MSG( IsObjectKnown( sink ) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
239 DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
ed45345e 240 DoEndWriteProperty( pi ) ;
16776ad9 241 }
cb73e600
SC
242 }
243 }
244 else
245 {
246 wxxVariant value ;
247 pi->GetAccessor()->GetProperty(obj, value) ;
ed45345e
SC
248
249 // avoid streaming out void objects
250 if( value.IsEmpty() )
251 return ;
252
253 if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
254 {
255 const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
256 wxASSERT_MSG( eti , wxT("Type must have enum - long conversion") ) ;
257 eti->ConvertFromLong( value.Get<long>() , value ) ;
258 }
259
260 // avoid streaming out default values
261 if ( pi->GetTypeInfo()->HasStringConverters() && !pi->GetDefaultValue().IsEmpty() )
262 {
263 if ( value.GetAsString() == pi->GetDefaultValue().GetAsString() )
264 return ;
265 }
266
267 // avoid streaming out null objects
268 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
269
270 if ( cti && value.GetAsObject() == NULL )
271 return ;
272
cb73e600
SC
273 if ( persister->BeforeWriteProperty( this , pi , value ) )
274 {
ed45345e 275 DoBeginWriteProperty( pi ) ;
cb73e600 276 if ( cti )
16776ad9 277 {
cb73e600
SC
278 const wxClassInfo* pci = cti->GetClassInfo() ;
279 wxObject *vobj = pci->VariantToInstance( value ) ;
ed45345e
SC
280 if ( vobj && pi->GetTypeInfo()->HasStringConverters() )
281 {
282 wxString stringValue ;
283 cti->ConvertToString( value , stringValue ) ;
284 wxxVariant convertedValue(stringValue) ;
285 DoWriteSimpleType( convertedValue ) ;
286 }
287 else
288 {
289 wxxVariantArray md ;
290 WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
291 }
cb73e600
SC
292 }
293 else
2abce515 294 {
cb73e600 295 DoWriteSimpleType( value ) ;
16776ad9 296 }
ed45345e 297 DoEndWriteProperty( pi ) ;
16776ad9
SC
298 }
299 }
16776ad9 300 }
4f8ffae1 301}
70e88103 302
2abce515 303int wxWriter::GetObjectID(const wxObject *obj)
16776ad9
SC
304{
305 if ( !IsObjectKnown( obj ) )
306 return wxInvalidObjectID ;
307
308 return m_data->m_writtenObjects[obj] ;
309}
310
2abce515 311bool wxWriter::IsObjectKnown( const wxObject *obj )
16776ad9
SC
312{
313 return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ;
314}
315
70e88103
SC
316
317// ----------------------------------------------------------------------------
2abce515 318// reading objects in
70e88103
SC
319// ----------------------------------------------------------------------------
320
70e88103
SC
321struct wxReader::wxReaderInternal
322{
45212047 323 map<int,wxClassInfo*> m_classInfos;
70e88103
SC
324};
325
2abce515 326wxReader::wxReader()
70e88103 327{
45212047 328 m_data = new wxReaderInternal;
70e88103
SC
329}
330
331wxReader::~wxReader()
332{
45212047 333 delete m_data;
70e88103
SC
334}
335
45212047 336wxClassInfo* wxReader::GetObjectClassInfo(int objectID)
70e88103 337{
45212047
SC
338 assert( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() );
339 return m_data->m_classInfos[objectID] ;
70e88103
SC
340}
341
45212047 342void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo )
70e88103 343{
16776ad9
SC
344 assert( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() ) ;
345 m_data->m_classInfos[objectID] = classInfo ;
70e88103
SC
346}
347
2abce515 348bool wxReader::HasObjectClassInfo( int objectID )
70e88103 349{
16776ad9 350 return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ;
70e88103
SC
351}
352
70e88103 353
45212047 354// ----------------------------------------------------------------------------
2abce515 355// reading xml in
45212047 356// ----------------------------------------------------------------------------
70e88103 357
2abce515 358/*
16776ad9
SC
359Reading components has not to be extended for components
360as properties are always sought by typeinfo over all levels
361and create params are always toplevel class only
70e88103
SC
362*/
363
70e88103
SC
364
365// ----------------------------------------------------------------------------
2abce515 366// depersisting to memory
70e88103
SC
367// ----------------------------------------------------------------------------
368
45212047 369struct wxRuntimeDepersister::wxRuntimeDepersisterInternal
70e88103 370{
45212047
SC
371 map<int,wxObject *> m_objects;
372
16776ad9
SC
373 void SetObject(int objectID, wxObject *obj )
374 {
375 assert( m_objects.find(objectID) == m_objects.end() ) ;
376 m_objects[objectID] = obj ;
377 }
378 wxObject* GetObject( int objectID )
379 {
380 if ( objectID == wxNullObjectID )
381 return NULL ;
382
383 assert( m_objects.find(objectID) != m_objects.end() ) ;
384 return m_objects[objectID] ;
385 }
45212047
SC
386} ;
387
388wxRuntimeDepersister::wxRuntimeDepersister()
389{
16776ad9 390 m_data = new wxRuntimeDepersisterInternal() ;
70e88103
SC
391}
392
45212047 393wxRuntimeDepersister::~wxRuntimeDepersister()
70e88103 394{
16776ad9 395 delete m_data ;
70e88103
SC
396}
397
4f8ffae1 398void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
9c8046dd 399 wxxVariantArray &WXUNUSED(metadata))
70e88103
SC
400{
401 wxObject *O;
45212047
SC
402 O = classInfo->CreateObject();
403 m_data->SetObject(objectID, O);
404}
405
406void wxRuntimeDepersister::CreateObject(int objectID,
16776ad9
SC
407 const wxClassInfo *classInfo,
408 int paramCount,
409 wxxVariant *params,
410 int *objectIdValues,
4f8ffae1 411 const wxClassInfo **objectClassInfos ,
9c8046dd 412 wxxVariantArray &WXUNUSED(metadata))
45212047
SC
413{
414 wxObject *o;
415 o = m_data->GetObject(objectID);
16776ad9
SC
416 for ( int i = 0 ; i < paramCount ; ++i )
417 {
418 if ( objectIdValues[i] != wxInvalidObjectID )
419 {
420 wxObject *o;
421 o = m_data->GetObject(objectIdValues[i]);
2d51f067
SC
422 // if this is a dynamic object and we are asked for another class
423 // than wxDynamicObject we cast it down manually.
424 wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ;
425 if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
426 {
427 o = dyno->GetSuperClassInstance() ;
428 }
16776ad9
SC
429 params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
430 }
431 }
45212047
SC
432 classInfo->Create(o, paramCount, params);
433}
434
ed45345e
SC
435void wxRuntimeDepersister::ConstructObject(int objectID,
436 const wxClassInfo *classInfo,
437 int paramCount,
438 wxxVariant *params,
439 int *objectIdValues,
440 const wxClassInfo **objectClassInfos ,
441 wxxVariantArray &WXUNUSED(metadata))
442{
443 wxObject *o;
444 for ( int i = 0 ; i < paramCount ; ++i )
445 {
446 if ( objectIdValues[i] != wxInvalidObjectID )
447 {
448 wxObject *o;
449 o = m_data->GetObject(objectIdValues[i]);
450 // if this is a dynamic object and we are asked for another class
451 // than wxDynamicObject we cast it down manually.
452 wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ;
453 if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
454 {
455 o = dyno->GetSuperClassInstance() ;
456 }
457 params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
458 }
459 }
460 o = classInfo->ConstructObject(paramCount, params);
461 m_data->SetObject(objectID, o);
462}
463
464
2abce515 465void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
45212047
SC
466{
467 wxObject *o;
468 o = m_data->GetObject(objectID);
16776ad9 469 delete o ;
70e88103
SC
470}
471
45212047 472void wxRuntimeDepersister::SetProperty(int objectID,
2d51f067 473 const wxClassInfo *classInfo,
16776ad9
SC
474 const wxPropertyInfo* propertyInfo,
475 const wxxVariant &value)
70e88103 476{
45212047
SC
477 wxObject *o;
478 o = m_data->GetObject(objectID);
2d51f067 479 classInfo->SetProperty( o , propertyInfo->GetName() , value ) ;
45212047
SC
480}
481
482void wxRuntimeDepersister::SetPropertyAsObject(int objectID,
2d51f067 483 const wxClassInfo *classInfo,
16776ad9
SC
484 const wxPropertyInfo* propertyInfo,
485 int valueObjectId)
45212047
SC
486{
487 wxObject *o, *valo;
488 o = m_data->GetObject(objectID);
489 valo = m_data->GetObject(valueObjectId);
2d51f067
SC
490 const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo() ;
491 // if this is a dynamic object and we are asked for another class
492 // than wxDynamicObject we cast it down manually.
493 wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ;
494 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
495 {
496 valo = dynvalo->GetSuperClassInstance() ;
497 }
498
499 classInfo->SetProperty( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ;
45212047
SC
500}
501
502void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
16776ad9
SC
503 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
504 const wxDelegateTypeInfo *delegateInfo ,
505 const wxClassInfo *WXUNUSED(eventSinkClassInfo) ,
506 const wxHandlerInfo* handlerInfo ,
507 int eventSinkObjectID )
45212047 508{
9c8046dd 509 wxEvtHandler *ehsource = dynamic_cast< wxEvtHandler* >( m_data->GetObject( eventSourceObjectID ) ) ;
16776ad9 510 wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ;
70e88103 511
16776ad9
SC
512 if ( ehsource && ehsink )
513 {
2abce515
SC
514 ehsource->Connect( -1 , delegateInfo->GetEventType() ,
515 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
16776ad9
SC
516 ehsink ) ;
517 }
70e88103
SC
518}
519
45212047
SC
520wxObject *wxRuntimeDepersister::GetObject(int objectID)
521{
16776ad9 522 return m_data->GetObject( objectID ) ;
45212047
SC
523}
524
16a45a23
SC
525// adds an element to a property collection
526void wxRuntimeDepersister::AddToPropertyCollection( int objectID ,
4f8ffae1
SC
527 const wxClassInfo *classInfo,
528 const wxPropertyInfo* propertyInfo ,
2abce515 529 const wxxVariant &value)
16a45a23
SC
530{
531 wxObject *o;
532 o = m_data->GetObject(objectID);
533 classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , value ) ;
534}
535
536// sets the corresponding property (value is an object)
537void wxRuntimeDepersister::AddToPropertyCollectionAsObject(int objectID,
4f8ffae1
SC
538 const wxClassInfo *classInfo,
539 const wxPropertyInfo* propertyInfo ,
2abce515 540 int valueObjectId)
16a45a23
SC
541{
542 wxObject *o, *valo;
543 o = m_data->GetObject(objectID);
544 valo = m_data->GetObject(valueObjectId);
545 const wxCollectionTypeInfo * collectionTypeInfo = dynamic_cast< const wxCollectionTypeInfo * >(propertyInfo->GetTypeInfo() ) ;
546 const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(collectionTypeInfo->GetElementType()))->GetClassInfo() ;
547 // if this is a dynamic object and we are asked for another class
548 // than wxDynamicObject we cast it down manually.
549 wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ;
550 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
551 {
552 valo = dynvalo->GetSuperClassInstance() ;
553 }
554
555 classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ;
556}
45212047 557
70e88103 558// ----------------------------------------------------------------------------
2abce515 559// depersisting to code
70e88103
SC
560// ----------------------------------------------------------------------------
561
45212047
SC
562struct wxCodeDepersister::wxCodeDepersisterInternal
563{
67b283a9
JS
564#if wxUSE_UNICODE
565 map<int,wstring> m_objectNames ;
566#else
45212047 567 map<int,string> m_objectNames ;
67b283a9 568#endif
45212047 569
16776ad9
SC
570 void SetObjectName(int objectID, const wxString &name )
571 {
572 assert( m_objectNames.find(objectID) == m_objectNames.end() ) ;
67b283a9 573 m_objectNames[objectID] = (const wxChar *)name;
16776ad9
SC
574 }
575 wxString GetObjectName( int objectID )
576 {
577 if ( objectID == wxNullObjectID )
67b283a9 578 return wxT("NULL") ;
16776ad9
SC
579
580 assert( m_objectNames.find(objectID) != m_objectNames.end() ) ;
581 return wxString( m_objectNames[objectID].c_str() ) ;
582 }
45212047 583} ;
70e88103 584
2abce515 585wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
16776ad9 586: m_fp(out)
70e88103 587{
16776ad9 588 m_data = new wxCodeDepersisterInternal ;
45212047
SC
589}
590
591wxCodeDepersister::~wxCodeDepersister()
592{
16776ad9 593 delete m_data ;
45212047
SC
594}
595
4f8ffae1 596void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
9c8046dd 597 wxxVariantArray &WXUNUSED(metadata))
45212047 598{
67b283a9
JS
599 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
600 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s;\n"),
16776ad9 601 classInfo->GetClassName(),
2abce515 602 objectName.c_str(),
16776ad9
SC
603 classInfo->GetClassName()) );
604 m_data->SetObjectName( objectID , objectName ) ;
45212047
SC
605}
606
2abce515 607void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
45212047 608{
67b283a9 609 m_fp->WriteString( wxString::Format( wxT("\tdelete %s;\n"),
2abce515 610 m_data->GetObjectName( objectID).c_str() ) );
45212047
SC
611}
612
613wxString wxCodeDepersister::ValueAsCode( const wxxVariant &param )
614{
16776ad9
SC
615 wxString value ;
616 const wxTypeInfo* type = param.GetTypeInfo() ;
617 if ( type->GetKind() == wxT_CUSTOM )
618 {
619 const wxCustomTypeInfo* cti = dynamic_cast<const wxCustomTypeInfo*>(type) ;
620 wxASSERT_MSG( cti , wxT("Internal error, illegal wxCustomTypeInfo") ) ;
67b283a9 621 value.Printf( wxT("%s(%s)"), cti->GetTypeName().c_str(),param.GetAsString().c_str() );
16776ad9
SC
622 }
623 else if ( type->GetKind() == wxT_STRING )
624 {
67b283a9 625 value.Printf( wxT("\"%s\""),param.GetAsString().c_str() );
16776ad9
SC
626 }
627 else
628 {
67b283a9 629 value.Printf( wxT("%s"), param.GetAsString().c_str() );
16776ad9
SC
630 }
631 return value ;
70e88103
SC
632}
633
45212047 634void wxCodeDepersister::CreateObject(int objectID,
16776ad9
SC
635 const wxClassInfo *WXUNUSED(classInfo),
636 int paramCount,
637 wxxVariant *params,
638 int *objectIDValues,
4f8ffae1 639 const wxClassInfo **WXUNUSED(objectClassInfos) ,
9c8046dd 640 wxxVariantArray &WXUNUSED(metadata)
16776ad9 641 )
70e88103
SC
642{
643 int i;
67b283a9 644 m_fp->WriteString( wxString::Format( wxT("\t%s->Create("), m_data->GetObjectName(objectID).c_str() ) );
45212047 645 for (i = 0; i < paramCount; i++)
70e88103 646 {
16776ad9 647 if ( objectIDValues[i] != wxInvalidObjectID )
67b283a9 648 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
16776ad9
SC
649 else
650 {
67b283a9 651 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
16776ad9
SC
652 }
653 if (i < paramCount - 1)
67b283a9 654 m_fp->WriteString( wxT(", "));
70e88103 655 }
67b283a9 656 m_fp->WriteString( wxT(");\n") );
70e88103
SC
657}
658
ed45345e
SC
659void wxCodeDepersister::ConstructObject(int objectID,
660 const wxClassInfo *classInfo,
661 int paramCount,
662 wxxVariant *params,
663 int *objectIDValues,
664 const wxClassInfo **WXUNUSED(objectClassInfos) ,
665 wxxVariantArray &WXUNUSED(metadata)
666 )
667{
67b283a9
JS
668 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
669 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s("),
ed45345e
SC
670 classInfo->GetClassName(),
671 objectName.c_str(),
672 classInfo->GetClassName()) );
673 m_data->SetObjectName( objectID , objectName ) ;
674
675 int i;
676 for (i = 0; i < paramCount; i++)
677 {
678 if ( objectIDValues[i] != wxInvalidObjectID )
67b283a9 679 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
ed45345e
SC
680 else
681 {
67b283a9 682 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
ed45345e
SC
683 }
684 if (i < paramCount - 1)
67b283a9 685 m_fp->WriteString( wxT(", ") );
ed45345e 686 }
67b283a9 687 m_fp->WriteString( wxT(");\n") );
ed45345e
SC
688}
689
45212047 690void wxCodeDepersister::SetProperty(int objectID,
16776ad9
SC
691 const wxClassInfo *WXUNUSED(classInfo),
692 const wxPropertyInfo* propertyInfo,
693 const wxxVariant &value)
70e88103 694{
67b283a9 695 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
2abce515
SC
696 m_data->GetObjectName(objectID).c_str(),
697 propertyInfo->GetAccessor()->GetSetterName().c_str(),
698 ValueAsCode(value).c_str()) );
45212047
SC
699}
700
701void wxCodeDepersister::SetPropertyAsObject(int objectID,
16776ad9
SC
702 const wxClassInfo *WXUNUSED(classInfo),
703 const wxPropertyInfo* propertyInfo,
704 int valueObjectId)
705{
706 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
67b283a9 707 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(*%s);\n"),
2abce515
SC
708 m_data->GetObjectName(objectID).c_str(),
709 propertyInfo->GetAccessor()->GetSetterName().c_str(),
710 m_data->GetObjectName( valueObjectId).c_str() ) );
16776ad9 711 else
67b283a9 712 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
2abce515
SC
713 m_data->GetObjectName(objectID).c_str(),
714 propertyInfo->GetAccessor()->GetSetterName().c_str(),
715 m_data->GetObjectName( valueObjectId).c_str() ) );
70e88103
SC
716}
717
16a45a23 718void wxCodeDepersister::AddToPropertyCollection( int objectID ,
9c8046dd 719 const wxClassInfo *WXUNUSED(classInfo),
4f8ffae1 720 const wxPropertyInfo* propertyInfo ,
2abce515 721 const wxxVariant &value)
16a45a23 722{
67b283a9 723 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
2abce515
SC
724 m_data->GetObjectName(objectID).c_str(),
725 propertyInfo->GetAccessor()->GetAdderName().c_str(),
726 ValueAsCode(value).c_str()) );
16a45a23
SC
727}
728
729// sets the corresponding property (value is an object)
9c8046dd
SC
730void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID),
731 const wxClassInfo *WXUNUSED(classInfo),
732 const wxPropertyInfo* WXUNUSED(propertyInfo) ,
2abce515 733 int WXUNUSED(valueObjectId))
16a45a23
SC
734{
735 // TODO
736}
737
45212047 738void wxCodeDepersister::SetConnect(int eventSourceObjectID,
16776ad9
SC
739 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
740 const wxDelegateTypeInfo *delegateInfo ,
741 const wxClassInfo *eventSinkClassInfo ,
742 const wxHandlerInfo* handlerInfo ,
743 int eventSinkObjectID )
744{
745 wxString ehsource = m_data->GetObjectName( eventSourceObjectID ) ;
746 wxString ehsink = m_data->GetObjectName(eventSinkObjectID) ;
747 wxString ehsinkClass = eventSinkClassInfo->GetClassName() ;
748 int eventType = delegateInfo->GetEventType() ;
749 wxString handlerName = handlerInfo->GetName() ;
750
67b283a9 751 m_fp->WriteString( wxString::Format( wxT("\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;") ,
2abce515 752 ehsource.c_str() , ehsource.c_str() , eventType , ehsinkClass.c_str() , handlerName.c_str() , ehsink.c_str() ) );
70e88103
SC
753}
754
ab6e4913
SC
755#include <wx/arrimpl.cpp>
756
757WX_DEFINE_OBJARRAY(wxxVariantArray);
758
70e88103 759#endif