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