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