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