]> git.saurik.com Git - wxWidgets.git/blame - src/common/xtistrm.cpp
correction for include name
[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 {
1d73f416
SC
514 if( delegateInfo->GetLastEventType() == -1 )
515 {
516 ehsource->Connect( -1 , delegateInfo->GetEventType() ,
517 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
518 ehsink ) ;
519 }
520 else
521 {
522 for ( wxEventType iter = delegateInfo->GetEventType() ; iter <= delegateInfo->GetLastEventType() ; ++iter )
523 {
524 ehsource->Connect( -1 , iter ,
525 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
526 ehsink ) ;
527 }
528 }
529
16776ad9 530 }
70e88103
SC
531}
532
45212047
SC
533wxObject *wxRuntimeDepersister::GetObject(int objectID)
534{
16776ad9 535 return m_data->GetObject( objectID ) ;
45212047
SC
536}
537
16a45a23
SC
538// adds an element to a property collection
539void wxRuntimeDepersister::AddToPropertyCollection( int objectID ,
4f8ffae1
SC
540 const wxClassInfo *classInfo,
541 const wxPropertyInfo* propertyInfo ,
2abce515 542 const wxxVariant &value)
16a45a23
SC
543{
544 wxObject *o;
545 o = m_data->GetObject(objectID);
546 classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , value ) ;
547}
548
549// sets the corresponding property (value is an object)
550void wxRuntimeDepersister::AddToPropertyCollectionAsObject(int objectID,
4f8ffae1
SC
551 const wxClassInfo *classInfo,
552 const wxPropertyInfo* propertyInfo ,
2abce515 553 int valueObjectId)
16a45a23
SC
554{
555 wxObject *o, *valo;
556 o = m_data->GetObject(objectID);
557 valo = m_data->GetObject(valueObjectId);
558 const wxCollectionTypeInfo * collectionTypeInfo = dynamic_cast< const wxCollectionTypeInfo * >(propertyInfo->GetTypeInfo() ) ;
559 const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(collectionTypeInfo->GetElementType()))->GetClassInfo() ;
560 // if this is a dynamic object and we are asked for another class
561 // than wxDynamicObject we cast it down manually.
562 wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ;
563 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
564 {
565 valo = dynvalo->GetSuperClassInstance() ;
566 }
567
568 classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ;
569}
45212047 570
70e88103 571// ----------------------------------------------------------------------------
2abce515 572// depersisting to code
70e88103
SC
573// ----------------------------------------------------------------------------
574
45212047
SC
575struct wxCodeDepersister::wxCodeDepersisterInternal
576{
67b283a9
JS
577#if wxUSE_UNICODE
578 map<int,wstring> m_objectNames ;
579#else
45212047 580 map<int,string> m_objectNames ;
67b283a9 581#endif
45212047 582
16776ad9
SC
583 void SetObjectName(int objectID, const wxString &name )
584 {
585 assert( m_objectNames.find(objectID) == m_objectNames.end() ) ;
67b283a9 586 m_objectNames[objectID] = (const wxChar *)name;
16776ad9
SC
587 }
588 wxString GetObjectName( int objectID )
589 {
590 if ( objectID == wxNullObjectID )
67b283a9 591 return wxT("NULL") ;
16776ad9
SC
592
593 assert( m_objectNames.find(objectID) != m_objectNames.end() ) ;
594 return wxString( m_objectNames[objectID].c_str() ) ;
595 }
45212047 596} ;
70e88103 597
2abce515 598wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
16776ad9 599: m_fp(out)
70e88103 600{
16776ad9 601 m_data = new wxCodeDepersisterInternal ;
45212047
SC
602}
603
604wxCodeDepersister::~wxCodeDepersister()
605{
16776ad9 606 delete m_data ;
45212047
SC
607}
608
4f8ffae1 609void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
9c8046dd 610 wxxVariantArray &WXUNUSED(metadata))
45212047 611{
67b283a9
JS
612 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
613 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s;\n"),
16776ad9 614 classInfo->GetClassName(),
2abce515 615 objectName.c_str(),
16776ad9
SC
616 classInfo->GetClassName()) );
617 m_data->SetObjectName( objectID , objectName ) ;
45212047
SC
618}
619
2abce515 620void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
45212047 621{
67b283a9 622 m_fp->WriteString( wxString::Format( wxT("\tdelete %s;\n"),
2abce515 623 m_data->GetObjectName( objectID).c_str() ) );
45212047
SC
624}
625
626wxString wxCodeDepersister::ValueAsCode( const wxxVariant &param )
627{
16776ad9
SC
628 wxString value ;
629 const wxTypeInfo* type = param.GetTypeInfo() ;
630 if ( type->GetKind() == wxT_CUSTOM )
631 {
632 const wxCustomTypeInfo* cti = dynamic_cast<const wxCustomTypeInfo*>(type) ;
633 wxASSERT_MSG( cti , wxT("Internal error, illegal wxCustomTypeInfo") ) ;
67b283a9 634 value.Printf( wxT("%s(%s)"), cti->GetTypeName().c_str(),param.GetAsString().c_str() );
16776ad9
SC
635 }
636 else if ( type->GetKind() == wxT_STRING )
637 {
67b283a9 638 value.Printf( wxT("\"%s\""),param.GetAsString().c_str() );
16776ad9
SC
639 }
640 else
641 {
67b283a9 642 value.Printf( wxT("%s"), param.GetAsString().c_str() );
16776ad9
SC
643 }
644 return value ;
70e88103
SC
645}
646
45212047 647void wxCodeDepersister::CreateObject(int objectID,
16776ad9
SC
648 const wxClassInfo *WXUNUSED(classInfo),
649 int paramCount,
650 wxxVariant *params,
651 int *objectIDValues,
4f8ffae1 652 const wxClassInfo **WXUNUSED(objectClassInfos) ,
9c8046dd 653 wxxVariantArray &WXUNUSED(metadata)
16776ad9 654 )
70e88103
SC
655{
656 int i;
67b283a9 657 m_fp->WriteString( wxString::Format( wxT("\t%s->Create("), m_data->GetObjectName(objectID).c_str() ) );
45212047 658 for (i = 0; i < paramCount; i++)
70e88103 659 {
16776ad9 660 if ( objectIDValues[i] != wxInvalidObjectID )
67b283a9 661 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
16776ad9
SC
662 else
663 {
67b283a9 664 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
16776ad9
SC
665 }
666 if (i < paramCount - 1)
67b283a9 667 m_fp->WriteString( wxT(", "));
70e88103 668 }
67b283a9 669 m_fp->WriteString( wxT(");\n") );
70e88103
SC
670}
671
ed45345e
SC
672void wxCodeDepersister::ConstructObject(int objectID,
673 const wxClassInfo *classInfo,
674 int paramCount,
675 wxxVariant *params,
676 int *objectIDValues,
677 const wxClassInfo **WXUNUSED(objectClassInfos) ,
678 wxxVariantArray &WXUNUSED(metadata)
679 )
680{
67b283a9
JS
681 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
682 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s("),
ed45345e
SC
683 classInfo->GetClassName(),
684 objectName.c_str(),
685 classInfo->GetClassName()) );
686 m_data->SetObjectName( objectID , objectName ) ;
687
688 int i;
689 for (i = 0; i < paramCount; i++)
690 {
691 if ( objectIDValues[i] != wxInvalidObjectID )
67b283a9 692 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
ed45345e
SC
693 else
694 {
67b283a9 695 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
ed45345e
SC
696 }
697 if (i < paramCount - 1)
67b283a9 698 m_fp->WriteString( wxT(", ") );
ed45345e 699 }
67b283a9 700 m_fp->WriteString( wxT(");\n") );
ed45345e
SC
701}
702
45212047 703void wxCodeDepersister::SetProperty(int objectID,
16776ad9
SC
704 const wxClassInfo *WXUNUSED(classInfo),
705 const wxPropertyInfo* propertyInfo,
706 const wxxVariant &value)
70e88103 707{
67b283a9 708 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
2abce515
SC
709 m_data->GetObjectName(objectID).c_str(),
710 propertyInfo->GetAccessor()->GetSetterName().c_str(),
711 ValueAsCode(value).c_str()) );
45212047
SC
712}
713
714void wxCodeDepersister::SetPropertyAsObject(int objectID,
16776ad9
SC
715 const wxClassInfo *WXUNUSED(classInfo),
716 const wxPropertyInfo* propertyInfo,
717 int valueObjectId)
718{
719 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
67b283a9 720 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(*%s);\n"),
2abce515
SC
721 m_data->GetObjectName(objectID).c_str(),
722 propertyInfo->GetAccessor()->GetSetterName().c_str(),
723 m_data->GetObjectName( valueObjectId).c_str() ) );
16776ad9 724 else
67b283a9 725 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
2abce515
SC
726 m_data->GetObjectName(objectID).c_str(),
727 propertyInfo->GetAccessor()->GetSetterName().c_str(),
728 m_data->GetObjectName( valueObjectId).c_str() ) );
70e88103
SC
729}
730
16a45a23 731void wxCodeDepersister::AddToPropertyCollection( int objectID ,
9c8046dd 732 const wxClassInfo *WXUNUSED(classInfo),
4f8ffae1 733 const wxPropertyInfo* propertyInfo ,
2abce515 734 const wxxVariant &value)
16a45a23 735{
67b283a9 736 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
2abce515
SC
737 m_data->GetObjectName(objectID).c_str(),
738 propertyInfo->GetAccessor()->GetAdderName().c_str(),
739 ValueAsCode(value).c_str()) );
16a45a23
SC
740}
741
742// sets the corresponding property (value is an object)
9c8046dd
SC
743void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID),
744 const wxClassInfo *WXUNUSED(classInfo),
745 const wxPropertyInfo* WXUNUSED(propertyInfo) ,
2abce515 746 int WXUNUSED(valueObjectId))
16a45a23
SC
747{
748 // TODO
749}
750
45212047 751void wxCodeDepersister::SetConnect(int eventSourceObjectID,
16776ad9
SC
752 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
753 const wxDelegateTypeInfo *delegateInfo ,
754 const wxClassInfo *eventSinkClassInfo ,
755 const wxHandlerInfo* handlerInfo ,
756 int eventSinkObjectID )
757{
758 wxString ehsource = m_data->GetObjectName( eventSourceObjectID ) ;
759 wxString ehsink = m_data->GetObjectName(eventSinkObjectID) ;
760 wxString ehsinkClass = eventSinkClassInfo->GetClassName() ;
761 int eventType = delegateInfo->GetEventType() ;
762 wxString handlerName = handlerInfo->GetName() ;
763
67b283a9 764 m_fp->WriteString( wxString::Format( wxT("\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;") ,
2abce515 765 ehsource.c_str() , ehsource.c_str() , eventType , ehsinkClass.c_str() , handlerName.c_str() , ehsink.c_str() ) );
70e88103
SC
766}
767
ab6e4913
SC
768#include <wx/arrimpl.cpp>
769
770WX_DEFINE_OBJARRAY(wxxVariantArray);
771
70e88103 772#endif