]> git.saurik.com Git - wxWidgets.git/blob - src/common/xtistrm.cpp
added support for gcc precompiled headers
[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/xml/xml.h"
29 #include "wx/tokenzr.h"
30 #include "wx/xtistrm.h"
31 #include "wx/txtstrm.h"
32
33 #if wxUSE_EXTENDED_RTTI
34 #include <map>
35 #include <vector>
36 #include <string>
37
38 using namespace std ;
39
40 struct wxWriter::wxWriterInternal
41 {
42 map< const wxObject* , int > m_writtenObjects ;
43 int m_nextId ;
44 } ;
45
46 wxWriter::wxWriter()
47 {
48 m_data = new wxWriterInternal ;
49 m_data->m_nextId = 0 ;
50 }
51
52 wxWriter::~wxWriter()
53 {
54 delete m_data ;
55 }
56
57 struct wxWriter::wxWriterInternalPropertiesData
58 {
59 map< string , int > m_writtenProperties ;
60 } ;
61
62 void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , const wxString &name )
63 {
64 if ( persister->BeforeWriteObject( object , classInfo , name ) )
65 {
66 int oid = m_data->m_nextId++ ;
67 m_data->m_writtenObjects[object] = oid ;
68 DoBeginWriteObject( object , classInfo , oid , name ) ;
69 wxWriterInternalPropertiesData data ;
70 WriteAllProperties( object , classInfo , persister , &data ) ;
71 DoEndWriteObject( object , classInfo , oid , name ) ;
72 }
73 }
74
75 void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data )
76 {
77 const wxPropertyInfo *pi = ci->GetFirstProperty() ;
78 while( pi )
79 {
80 if ( data->m_writtenProperties.find( pi->GetName() ) == data->m_writtenProperties.end() )
81 {
82 data->m_writtenProperties[ pi->GetName() ] = 1 ;
83 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
84 if ( cti )
85 {
86 const wxClassInfo* pci = cti->GetClassInfo() ;
87 wxxVariant value = pi->GetAccessor()->GetProperty(obj) ;
88 if ( persister->BeforeWritePropertyAsObject( obj , ci , pi , value ) )
89 {
90 wxObject *vobj = pci->VariantToInstance( value ) ;
91 bool embeddedObject = cti->GetKind() == wxT_OBJECT ;
92
93 if ( vobj == NULL || IsObjectKnown( vobj ) )
94 {
95 DoWriteObjectReference( obj , ci , vobj , pci , GetObjectID(vobj) , pi ) ;
96 }
97 else
98 {
99 int oid = m_data->m_nextId++ ;
100 if ( !embeddedObject)
101 m_data->m_writtenObjects[vobj] = oid ;
102
103 DoBeginWriteParamAsObject( obj , ci , vobj , pci , oid , pi ) ;
104 if ( vobj != NULL )
105 {
106 wxWriterInternalPropertiesData data ;
107 WriteAllProperties( vobj , pci , persister , &data ) ;
108 }
109 DoEndWriteParamAsObject( obj , ci , vobj , pci , oid , pi ) ;
110 }
111 }
112 }
113 else
114 {
115 const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
116 if ( dti )
117 {
118 const wxObject* sink = NULL ;
119 const wxHandlerInfo *handler = NULL ;
120
121 const wxWindow * evSource = dynamic_cast<const wxWindow *>(obj) ;
122 wxASSERT_MSG( evSource , wxT("Illegal Object Class (Non-Window) as Event Source") ) ;
123
124 wxList *dynamicEvents = evSource->GetDynamicEventTable() ;
125
126 if ( dynamicEvents )
127 {
128 wxList::compatibility_iterator node = dynamicEvents->GetFirst();
129 while (node)
130 {
131 wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
132
133 // find the match
134 if ( entry->m_fn && (dti->GetEventType() == entry->m_eventType) &&
135 (entry->m_id == -1 ||
136 (entry->m_lastId == -1 && evSource->GetId() == entry->m_id) ||
137 (entry->m_lastId != -1 &&
138 (evSource->GetId() >= entry->m_id && evSource->GetId() <= entry->m_lastId) ) ) &&
139 entry->m_eventSink
140 )
141 {
142 sink = entry->m_eventSink ;
143 const wxClassInfo* sinkClassInfo = sink->GetClassInfo() ;
144 const wxHandlerInfo* sinkHandler = sinkClassInfo->GetFirstHandler() ;
145 while ( sinkHandler )
146 {
147 if ( sinkHandler->GetEventFunction() == entry->m_fn )
148 {
149 handler = sinkHandler ;
150 break ;
151 }
152 sinkHandler = sinkHandler->GetNext() ;
153 }
154 break ;
155 }
156 node = node->GetNext();
157 }
158 }
159 if ( persister->BeforeWriteDelegate( obj , ci , pi , sink , handler ) )
160 {
161 if ( sink != NULL && handler != NULL )
162 {
163 wxASSERT_MSG( IsObjectKnown( sink ) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
164 DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
165 }
166 }
167 }
168 else
169 {
170 wxxVariant value = pi->GetAccessor()->GetProperty(obj) ;
171 if ( persister->BeforeWriteProperty( obj , ci , pi , value ) )
172 {
173 DoWriteProperty( obj , ci , pi , value ) ;
174 }
175 }
176 }
177 }
178 pi = pi->GetNext() ;
179 }
180 const wxClassInfo** parents = ci->GetParents() ;
181 for ( int i = 0 ; parents[i] ; ++ i )
182 {
183 WriteAllProperties( obj , parents[i] , persister , data ) ;
184 }
185 }
186
187 int wxWriter::GetObjectID(const wxObject *obj)
188 {
189 if ( !IsObjectKnown( obj ) )
190 return wxInvalidObjectID ;
191
192 return m_data->m_writtenObjects[obj] ;
193 }
194
195 bool wxWriter::IsObjectKnown( const wxObject *obj )
196 {
197 return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ;
198 }
199
200 //
201 // XML Streaming
202 //
203
204 // convenience functions
205
206 void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
207 {
208 node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
209 }
210
211 wxString wxXmlGetContentFromNode( wxXmlNode *node )
212 {
213 if ( node->GetChildren() )
214 return node->GetChildren()->GetContent() ;
215 else
216 return wxEmptyString ;
217 }
218
219 struct wxXmlWriter::wxXmlWriterInternal
220 {
221 wxXmlNode *m_root ;
222 wxXmlNode *m_current ;
223 vector< wxXmlNode * > m_objectStack ;
224 } ;
225
226 wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode )
227 {
228 m_data = new wxXmlWriterInternal() ;
229 m_data->m_root = rootnode ;
230 m_data->m_current = rootnode ;
231 }
232
233 wxXmlWriter::~wxXmlWriter()
234 {
235 delete m_data ;
236 }
237
238 // start of writing the root object
239 void wxXmlWriter::DoBeginWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *classInfo, int objectID , const wxString &name )
240 {
241 wxXmlNode *onode;
242 onode = new wxXmlNode(wxXML_ELEMENT_NODE, name);
243 onode->AddProperty(wxString("class"), wxString(classInfo->GetClassName()));
244 onode->AddProperty(wxString("id"), wxString::Format( "%d" , objectID ) );
245
246 m_data->m_current->AddChild(onode) ;
247 m_data->m_objectStack.push_back( m_data->m_current ) ;
248 m_data->m_current = onode ;
249 }
250
251 // end of writing the root object
252 void wxXmlWriter::DoEndWriteObject(const wxObject *WXUNUSED(object), const wxClassInfo *WXUNUSED(classInfo), int WXUNUSED(objectID) , const wxString &WXUNUSED(name) )
253 {
254 m_data->m_current = m_data->m_objectStack.back() ;
255 m_data->m_objectStack.pop_back() ;
256 }
257
258 // writes a property in the stream format
259 void wxXmlWriter::DoWriteProperty( const wxObject *WXUNUSED(obj), const wxClassInfo* WXUNUSED(classInfo) , const wxPropertyInfo *pi , wxxVariant &value )
260 {
261 wxXmlNode *pnode;
262 pnode = new wxXmlNode(wxXML_ELEMENT_NODE, pi->GetName() );
263 wxXmlAddContentToNode( pnode ,value.GetAsString() ) ;
264 m_data->m_current->AddChild(pnode);
265 }
266
267 void wxXmlWriter::DoBeginWriteParamAsObject(const wxObject *WXUNUSED(parentObject), const wxClassInfo *WXUNUSED(parentClassInfo), const wxObject *WXUNUSED(valueObject),
268 const wxClassInfo *valueObjectClassInfo, int valueObjectID , const wxPropertyInfo *propInfo )
269 {
270 wxXmlNode *onode;
271 onode = new wxXmlNode(wxXML_ELEMENT_NODE, propInfo->GetName());
272 onode->AddProperty(wxString("class"), wxString(valueObjectClassInfo->GetClassName()));
273 onode->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID ) );
274 m_data->m_current->AddChild(onode) ;
275 m_data->m_objectStack.push_back( m_data->m_current ) ;
276 m_data->m_current = onode ;
277 }
278
279 // insert an object reference to an already written object
280 void wxXmlWriter::DoWriteObjectReference(const wxObject *WXUNUSED(parentObject), const wxClassInfo *WXUNUSED(parentClassInfo), const wxObject *valueObject,
281 const wxClassInfo *valueObjectClassInfo, int valueObjectID , const wxPropertyInfo *propInfo )
282 {
283 wxXmlNode *onode;
284 onode = new wxXmlNode(wxXML_ELEMENT_NODE, propInfo->GetName());
285 onode->AddProperty(wxString("class"), wxString(valueObjectClassInfo->GetClassName()));
286 if ( valueObject == NULL )
287 {
288 wxXmlNode* nullnode = new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, "null");
289 onode->AddChild(nullnode);
290 }
291 else
292 {
293 onode->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID ) );
294 }
295
296 m_data->m_current->AddChild(onode) ;
297 }
298
299 void wxXmlWriter::DoEndWriteParamAsObject(const wxObject *WXUNUSED(parentObject), const wxClassInfo *WXUNUSED(parentClassInfo), const wxObject *WXUNUSED(valueObject),
300 const wxClassInfo *WXUNUSED(valueObjectClassInfo), int WXUNUSED(valueObjectID) , const wxPropertyInfo *WXUNUSED(propInfo) )
301 {
302 m_data->m_current = m_data->m_objectStack.back() ;
303 m_data->m_objectStack.pop_back() ;
304 }
305
306
307 // writes a delegate in the stream format
308 void wxXmlWriter::DoWriteDelegate( const wxObject *WXUNUSED(object), const wxClassInfo* WXUNUSED(classInfo) , const wxPropertyInfo *pi ,
309 const wxObject *eventSink, int sinkObjectID , const wxClassInfo* WXUNUSED(eventSinkClassInfo) , const wxHandlerInfo* handlerInfo )
310 {
311 if ( eventSink != NULL && handlerInfo != NULL )
312 {
313 wxXmlNode *pnode;
314 pnode = new wxXmlNode(wxXML_ELEMENT_NODE, pi->GetName() );
315 wxString s ;
316 s.Printf(wxT("%d.%s"), sinkObjectID , handlerInfo->GetName() ) ;
317 wxXmlAddContentToNode( pnode ,s ) ;
318 m_data->m_current->AddChild(pnode);
319 }
320 }
321
322 // ----------------------------------------------------------------------------
323 // reading objects in
324 // ----------------------------------------------------------------------------
325
326 struct wxReader::wxReaderInternal
327 {
328 map<int,wxClassInfo*> m_classInfos;
329 };
330
331 wxReader::wxReader()
332 {
333 m_data = new wxReaderInternal;
334 }
335
336 wxReader::~wxReader()
337 {
338 delete m_data;
339 }
340
341 wxClassInfo* wxReader::GetObjectClassInfo(int objectID)
342 {
343 assert( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() );
344 return m_data->m_classInfos[objectID] ;
345 }
346
347 void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo )
348 {
349 assert( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() ) ;
350 m_data->m_classInfos[objectID] = classInfo ;
351 }
352
353 bool wxReader::HasObjectClassInfo( int objectID )
354 {
355 return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ;
356 }
357
358
359 // ----------------------------------------------------------------------------
360 // reading xml in
361 // ----------------------------------------------------------------------------
362
363 /*
364 Reading components has not to be extended for components
365 as properties are always sought by typeinfo over all levels
366 and create params are always toplevel class only
367 */
368
369 int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
370 {
371 wxString className;
372 wxClassInfo *classInfo;
373
374 wxxVariant *createParams ;
375 int *createParamOids ;
376 const wxClassInfo** createClassInfos ;
377 wxXmlNode *children;
378 int objectID;
379
380 children = node->GetChildren();
381 if (!node->GetPropVal("class", &className))
382 {
383 // No class name. Eek. FIXME: error handling
384 return wxInvalidObjectID;
385 }
386 classInfo = wxClassInfo::FindClass(className);
387 if (children && children->GetType() == wxXML_TEXT_NODE)
388 {
389 assert( wxXmlGetContentFromNode(node) == "null" ) ;
390 // this must be a NULL component reference. We just bail out
391 return wxNullObjectID;
392 }
393
394 wxString ObjectIdString ;
395 if (!node->GetPropVal("id", &ObjectIdString))
396 {
397 // No object id. Eek. FIXME: error handling
398 return wxInvalidObjectID;
399 }
400
401 objectID = atoi( ObjectIdString.c_str() ) ;
402 // is this object already has been streamed in, return it here
403 if ( HasObjectClassInfo( objectID ) )
404 return objectID ;
405
406 // new object, start with allocation
407 // first make the object know to our internal registry
408 SetObjectClassInfo( objectID , classInfo ) ;
409
410 callbacks->AllocateObject(objectID, classInfo);
411
412 //
413 // stream back the Create parameters first
414 createParams = new wxxVariant[ classInfo->GetCreateParamCount() ] ;
415 createParamOids = new int[classInfo->GetCreateParamCount() ] ;
416 createClassInfos = new const wxClassInfo*[classInfo->GetCreateParamCount() ] ;
417
418 typedef map<string, wxXmlNode *> PropertyNodes ;
419 typedef vector<string> PropertyNames ;
420
421 PropertyNodes propertyNodes ;
422 PropertyNames propertyNames ;
423
424 while( children )
425 {
426 propertyNames.push_back( children->GetName().c_str() ) ;
427 propertyNodes[children->GetName().c_str()] = children ;
428 children = children->GetNext() ;
429 }
430
431 for ( int i = 0 ; i <classInfo->GetCreateParamCount() ; ++i )
432 {
433 const wxChar* paramName = classInfo->GetCreateParamName(i) ;
434 PropertyNodes::iterator propiter = propertyNodes.find( paramName ) ;
435 const wxPropertyInfo* pi = classInfo->FindPropertyInfo( paramName ) ;
436 // if we don't have the value of a create param set in the xml
437 // we use the default value
438 if ( propiter != propertyNodes.end() )
439 {
440 wxXmlNode* prop = propiter->second ;
441 if ( pi->GetTypeInfo()->IsObjectType() )
442 {
443 createParamOids[i] = ReadComponent( prop , callbacks ) ;
444 createClassInfos[i] = dynamic_cast<const wxClassTypeInfo*>(pi->GetTypeInfo())->GetClassInfo() ;
445 }
446 else
447 {
448 createParamOids[i] = wxInvalidObjectID ;
449 createParams[i] = ReadValue( prop , pi->GetAccessor() ) ;
450 createClassInfos[i] = NULL ;
451 }
452
453 for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
454 {
455 if ( propertyNames[j] == paramName )
456 {
457 propertyNames[j] = "" ;
458 break ;
459 }
460 }
461 }
462 else
463 {
464 createParams[i] = pi->GetDefaultValue() ;
465 }
466 }
467
468 // got the parameters. Call the Create method
469 callbacks->CreateObject(objectID, classInfo,
470 classInfo->GetCreateParamCount(),
471 createParams, createParamOids, createClassInfos);
472
473 // now stream in the rest of the properties, in the sequence their properties were written in the xml
474 for ( size_t j = 0 ; j < propertyNames.size() ; ++j )
475 {
476 if ( propertyNames[j].length() )
477 {
478 PropertyNodes::iterator propiter = propertyNodes.find( propertyNames[j] ) ;
479 if ( propiter != propertyNodes.end() )
480 {
481 wxXmlNode* prop = propiter->second ;
482 const wxPropertyInfo* pi = classInfo->FindPropertyInfo( propertyNames[j].c_str() ) ;
483 if ( pi->GetTypeInfo()->IsObjectType() )
484 {
485 int valueId = ReadComponent( prop , callbacks ) ;
486 if ( callbacks )
487 {
488 if ( valueId != wxInvalidObjectID )
489 {
490 callbacks->SetPropertyAsObject( objectID , classInfo , pi , valueId ) ;
491 if ( pi->GetTypeInfo()->GetKind() == wxT_OBJECT && valueId != wxNullObjectID )
492 callbacks->DestroyObject( valueId , GetObjectClassInfo( valueId ) ) ;
493 }
494 }
495 }
496 else if ( pi->GetTypeInfo()->IsDelegateType() )
497 {
498 wxString resstring = wxXmlGetContentFromNode(prop) ;
499 wxInt32 pos = resstring.Find('.') ;
500 assert( pos != wxNOT_FOUND ) ;
501 int sinkOid = atol(resstring.Left(pos)) ;
502 wxString handlerName = resstring.Mid(pos+1) ;
503 wxClassInfo* sinkClassInfo = GetObjectClassInfo( sinkOid ) ;
504
505 if (callbacks)
506 callbacks->SetConnect( objectID , classInfo , dynamic_cast<const wxDelegateTypeInfo*>(pi->GetTypeInfo()) , sinkClassInfo ,
507 sinkClassInfo->FindHandlerInfo(handlerName) , sinkOid ) ;
508
509 }
510 else
511 {
512 if ( callbacks )
513 callbacks->SetProperty( objectID, classInfo ,pi , ReadValue( prop , pi->GetAccessor() ) ) ;
514 }
515 }
516 }
517 }
518
519 delete[] createParams ;
520 delete[] createParamOids ;
521 delete[] createClassInfos ;
522
523 return objectID;
524 }
525
526 wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
527 wxPropertyAccessor *accessor )
528 {
529 return accessor->ReadValue(wxXmlGetContentFromNode( node ) ) ;
530 }
531
532 int wxXmlReader::ReadObject(wxDepersister *callbacks)
533 {
534 return ReadComponent( m_parent , callbacks ) ;
535 }
536
537 // ----------------------------------------------------------------------------
538 // depersisting to memory
539 // ----------------------------------------------------------------------------
540
541 struct wxRuntimeDepersister::wxRuntimeDepersisterInternal
542 {
543 map<int,wxObject *> m_objects;
544
545 void SetObject(int objectID, wxObject *obj )
546 {
547 assert( m_objects.find(objectID) == m_objects.end() ) ;
548 m_objects[objectID] = obj ;
549 }
550 wxObject* GetObject( int objectID )
551 {
552 if ( objectID == wxNullObjectID )
553 return NULL ;
554
555 assert( m_objects.find(objectID) != m_objects.end() ) ;
556 return m_objects[objectID] ;
557 }
558 } ;
559
560 wxRuntimeDepersister::wxRuntimeDepersister()
561 {
562 m_data = new wxRuntimeDepersisterInternal() ;
563 }
564
565 wxRuntimeDepersister::~wxRuntimeDepersister()
566 {
567 delete m_data ;
568 }
569
570 void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo)
571 {
572 wxObject *O;
573 O = classInfo->CreateObject();
574 m_data->SetObject(objectID, O);
575 }
576
577 void wxRuntimeDepersister::CreateObject(int objectID,
578 const wxClassInfo *classInfo,
579 int paramCount,
580 wxxVariant *params,
581 int *objectIdValues,
582 const wxClassInfo **objectClassInfos)
583 {
584 wxObject *o;
585 o = m_data->GetObject(objectID);
586 for ( int i = 0 ; i < paramCount ; ++i )
587 {
588 if ( objectIdValues[i] != wxInvalidObjectID )
589 {
590 wxObject *o;
591 o = m_data->GetObject(objectIdValues[i]);
592 params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
593 }
594 }
595 classInfo->Create(o, paramCount, params);
596 }
597
598 void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
599 {
600 wxObject *o;
601 o = m_data->GetObject(objectID);
602 delete o ;
603 }
604
605 void wxRuntimeDepersister::SetProperty(int objectID,
606 const wxClassInfo *WXUNUSED(classInfo),
607 const wxPropertyInfo* propertyInfo,
608 const wxxVariant &value)
609 {
610 wxObject *o;
611 o = m_data->GetObject(objectID);
612 propertyInfo->GetAccessor()->SetProperty( o , value ) ;
613 }
614
615 void wxRuntimeDepersister::SetPropertyAsObject(int objectID,
616 const wxClassInfo *WXUNUSED(classInfo),
617 const wxPropertyInfo* propertyInfo,
618 int valueObjectId)
619 {
620 wxObject *o, *valo;
621 o = m_data->GetObject(objectID);
622 valo = m_data->GetObject(valueObjectId);
623 propertyInfo->GetAccessor()->SetProperty( o ,
624 (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo()->InstanceToVariant(valo) ) ;
625 }
626
627 void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
628 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
629 const wxDelegateTypeInfo *delegateInfo ,
630 const wxClassInfo *WXUNUSED(eventSinkClassInfo) ,
631 const wxHandlerInfo* handlerInfo ,
632 int eventSinkObjectID )
633 {
634 wxWindow *ehsource = dynamic_cast< wxWindow* >( m_data->GetObject( eventSourceObjectID ) ) ;
635 wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ;
636
637 if ( ehsource && ehsink )
638 {
639 ehsource->Connect( ehsource->GetId() , delegateInfo->GetEventType() ,
640 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
641 ehsink ) ;
642 }
643 }
644
645 wxObject *wxRuntimeDepersister::GetObject(int objectID)
646 {
647 return m_data->GetObject( objectID ) ;
648 }
649
650
651 // ----------------------------------------------------------------------------
652 // depersisting to code
653 // ----------------------------------------------------------------------------
654
655 struct wxCodeDepersister::wxCodeDepersisterInternal
656 {
657 map<int,string> m_objectNames ;
658
659 void SetObjectName(int objectID, const wxString &name )
660 {
661 assert( m_objectNames.find(objectID) == m_objectNames.end() ) ;
662 m_objectNames[objectID] = (const char *)name;
663 }
664 wxString GetObjectName( int objectID )
665 {
666 if ( objectID == wxNullObjectID )
667 return "NULL" ;
668
669 assert( m_objectNames.find(objectID) != m_objectNames.end() ) ;
670 return wxString( m_objectNames[objectID].c_str() ) ;
671 }
672 } ;
673
674 wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
675 : m_fp(out)
676 {
677 m_data = new wxCodeDepersisterInternal ;
678 }
679
680 wxCodeDepersister::~wxCodeDepersister()
681 {
682 delete m_data ;
683 }
684
685 void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo)
686 {
687 wxString objectName = wxString::Format( "LocalObject_%d" , objectID ) ;
688 m_fp->WriteString( wxString::Format( "\t%s *%s = new %s;\n",
689 classInfo->GetClassName(),
690 objectName,
691 classInfo->GetClassName()) );
692 m_data->SetObjectName( objectID , objectName ) ;
693 }
694
695 void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
696 {
697 m_fp->WriteString( wxString::Format( "\tdelete %s;\n",
698 m_data->GetObjectName( objectID) ) );
699 }
700
701 wxString wxCodeDepersister::ValueAsCode( const wxxVariant &param )
702 {
703 wxString value ;
704 const wxTypeInfo* type = param.GetTypeInfo() ;
705 if ( type->GetKind() == wxT_CUSTOM )
706 {
707 const wxCustomTypeInfo* cti = dynamic_cast<const wxCustomTypeInfo*>(type) ;
708 wxASSERT_MSG( cti , wxT("Internal error, illegal wxCustomTypeInfo") ) ;
709 value.Printf( "%s(%s)",cti->GetTypeName(),param.GetAsString() );
710 }
711 else if ( type->GetKind() == wxT_STRING )
712 {
713 value.Printf( "\"%s\"",param.GetAsString() );
714 }
715 else
716 {
717 value.Printf( "%s", param.GetAsString() );
718 }
719 return value ;
720 }
721
722 void wxCodeDepersister::CreateObject(int objectID,
723 const wxClassInfo *WXUNUSED(classInfo),
724 int paramCount,
725 wxxVariant *params,
726 int *objectIDValues,
727 const wxClassInfo **WXUNUSED(objectClassInfos)
728 )
729 {
730 int i;
731 m_fp->WriteString( wxString::Format( "\t%s->Create(", m_data->GetObjectName(objectID) ) );
732 for (i = 0; i < paramCount; i++)
733 {
734 if ( objectIDValues[i] != wxInvalidObjectID )
735 m_fp->WriteString( wxString::Format( "%s", m_data->GetObjectName( objectIDValues[i] ) ) );
736 else
737 {
738 m_fp->WriteString( wxString::Format( "%s", ValueAsCode(params[i]) ) );
739 }
740 if (i < paramCount - 1)
741 m_fp->WriteString( ", ");
742 }
743 m_fp->WriteString( ");\n");
744 }
745
746 void wxCodeDepersister::SetProperty(int objectID,
747 const wxClassInfo *WXUNUSED(classInfo),
748 const wxPropertyInfo* propertyInfo,
749 const wxxVariant &value)
750 {
751 m_fp->WriteString( wxString::Format( "\t%s->%s(%s);\n",
752 m_data->GetObjectName(objectID),
753 propertyInfo->GetAccessor()->GetSetterName(),
754 ValueAsCode(value)) );
755 }
756
757 void wxCodeDepersister::SetPropertyAsObject(int objectID,
758 const wxClassInfo *WXUNUSED(classInfo),
759 const wxPropertyInfo* propertyInfo,
760 int valueObjectId)
761 {
762 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
763 m_fp->WriteString( wxString::Format( "\t%s->%s(*%s);\n",
764 m_data->GetObjectName(objectID),
765 propertyInfo->GetAccessor()->GetSetterName(),
766 m_data->GetObjectName( valueObjectId) ) );
767 else
768 m_fp->WriteString( wxString::Format( "\t%s->%s(%s);\n",
769 m_data->GetObjectName(objectID),
770 propertyInfo->GetAccessor()->GetSetterName(),
771 m_data->GetObjectName( valueObjectId) ) );
772 }
773
774 void wxCodeDepersister::SetConnect(int eventSourceObjectID,
775 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
776 const wxDelegateTypeInfo *delegateInfo ,
777 const wxClassInfo *eventSinkClassInfo ,
778 const wxHandlerInfo* handlerInfo ,
779 int eventSinkObjectID )
780 {
781 wxString ehsource = m_data->GetObjectName( eventSourceObjectID ) ;
782 wxString ehsink = m_data->GetObjectName(eventSinkObjectID) ;
783 wxString ehsinkClass = eventSinkClassInfo->GetClassName() ;
784 int eventType = delegateInfo->GetEventType() ;
785 wxString handlerName = handlerInfo->GetName() ;
786
787 m_fp->WriteString( wxString::Format( "\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;" ,
788 ehsource , ehsource , eventType , ehsinkClass , handlerName , ehsink ) );
789 }
790
791 #endif