]> git.saurik.com Git - wxWidgets.git/blame - src/common/xtistrm.cpp
added version checking to the renderers
[wxWidgets.git] / src / common / xtistrm.cpp
CommitLineData
70e88103
SC
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
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
70e88103
SC
13#pragma implementation "xtistrm.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
16776ad9
SC
24#include "wx/hash.h"
25#include "wx/object.h"
70e88103
SC
26#endif
27
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
38using namespace std ;
39
16776ad9
SC
40struct wxWriter::wxWriterInternal
41{
42 map< const wxObject* , int > m_writtenObjects ;
43 int m_nextId ;
44} ;
45
46wxWriter::wxWriter()
47{
48 m_data = new wxWriterInternal ;
49 m_data->m_nextId = 0 ;
50}
51
52wxWriter::~wxWriter()
53{
54 delete m_data ;
55}
56
57struct wxWriter::wxWriterInternalPropertiesData
58{
59 map< string , int > m_writtenProperties ;
60} ;
61
62void 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
75void 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 ;
a315dda6
SC
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 }
16776ad9
SC
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}
70e88103 186
16776ad9
SC
187int wxWriter::GetObjectID(const wxObject *obj)
188{
189 if ( !IsObjectKnown( obj ) )
190 return wxInvalidObjectID ;
191
192 return m_data->m_writtenObjects[obj] ;
193}
194
195bool 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
206void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data )
207{
208 node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) );
209}
210
211wxString wxXmlGetContentFromNode( wxXmlNode *node )
212{
213 if ( node->GetChildren() )
214 return node->GetChildren()->GetContent() ;
215 else
216 return wxEmptyString ;
217}
218
219struct wxXmlWriter::wxXmlWriterInternal
220{
221 wxXmlNode *m_root ;
222 wxXmlNode *m_current ;
223 vector< wxXmlNode * > m_objectStack ;
224} ;
225
226wxXmlWriter::wxXmlWriter( wxXmlNode * rootnode )
227{
228 m_data = new wxXmlWriterInternal() ;
229 m_data->m_root = rootnode ;
230 m_data->m_current = rootnode ;
231}
232
233wxXmlWriter::~wxXmlWriter()
234{
235 delete m_data ;
236}
237
238// start of writing the root object
239void 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
252void 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
259void 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
267void 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
280void 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
299void 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
308void 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 }
70e88103
SC
320}
321
322// ----------------------------------------------------------------------------
45212047 323// reading objects in
70e88103
SC
324// ----------------------------------------------------------------------------
325
70e88103
SC
326struct wxReader::wxReaderInternal
327{
45212047 328 map<int,wxClassInfo*> m_classInfos;
70e88103
SC
329};
330
45212047 331wxReader::wxReader()
70e88103 332{
45212047 333 m_data = new wxReaderInternal;
70e88103
SC
334}
335
336wxReader::~wxReader()
337{
45212047 338 delete m_data;
70e88103
SC
339}
340
45212047 341wxClassInfo* wxReader::GetObjectClassInfo(int objectID)
70e88103 342{
45212047
SC
343 assert( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() );
344 return m_data->m_classInfos[objectID] ;
70e88103
SC
345}
346
45212047 347void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo )
70e88103 348{
16776ad9
SC
349 assert( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() ) ;
350 m_data->m_classInfos[objectID] = classInfo ;
70e88103
SC
351}
352
45212047 353bool wxReader::HasObjectClassInfo( int objectID )
70e88103 354{
16776ad9 355 return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ;
70e88103
SC
356}
357
70e88103 358
45212047
SC
359// ----------------------------------------------------------------------------
360// reading xml in
361// ----------------------------------------------------------------------------
70e88103
SC
362
363/*
16776ad9
SC
364Reading components has not to be extended for components
365as properties are always sought by typeinfo over all levels
366and create params are always toplevel class only
70e88103
SC
367*/
368
45212047 369int wxXmlReader::ReadComponent(wxXmlNode *node, wxDepersister *callbacks)
70e88103 370{
45212047
SC
371 wxString className;
372 wxClassInfo *classInfo;
70e88103 373
16776ad9
SC
374 wxxVariant *createParams ;
375 int *createParamOids ;
376 const wxClassInfo** createClassInfos ;
45212047
SC
377 wxXmlNode *children;
378 int objectID;
70e88103 379
45212047
SC
380 children = node->GetChildren();
381 if (!node->GetPropVal("class", &className))
70e88103 382 {
16776ad9
SC
383 // No class name. Eek. FIXME: error handling
384 return wxInvalidObjectID;
70e88103 385 }
16776ad9 386 classInfo = wxClassInfo::FindClass(className);
45212047 387 if (children && children->GetType() == wxXML_TEXT_NODE)
70e88103 388 {
16776ad9
SC
389 assert( wxXmlGetContentFromNode(node) == "null" ) ;
390 // this must be a NULL component reference. We just bail out
391 return wxNullObjectID;
392 }
70e88103 393
16776ad9 394 wxString ObjectIdString ;
45212047 395 if (!node->GetPropVal("id", &ObjectIdString))
70e88103 396 {
16776ad9
SC
397 // No object id. Eek. FIXME: error handling
398 return wxInvalidObjectID;
70e88103
SC
399 }
400
45212047 401 objectID = atoi( ObjectIdString.c_str() ) ;
16776ad9
SC
402 // is this object already has been streamed in, return it here
403 if ( HasObjectClassInfo( objectID ) )
404 return objectID ;
70e88103 405
16776ad9
SC
406 // new object, start with allocation
407 // first make the object know to our internal registry
408 SetObjectClassInfo( objectID , classInfo ) ;
45212047
SC
409
410 callbacks->AllocateObject(objectID, classInfo);
70e88103 411
16776ad9 412 //
70e88103 413 // stream back the Create parameters first
16776ad9
SC
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 }
70e88103
SC
467
468 // got the parameters. Call the Create method
45212047 469 callbacks->CreateObject(objectID, classInfo,
16776ad9
SC
470 classInfo->GetCreateParamCount(),
471 createParams, createParamOids, createClassInfos);
70e88103
SC
472
473 // now stream in the rest of the properties, in the sequence their properties were written in the xml
16776ad9
SC
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 ;
70e88103 522
45212047
SC
523 return objectID;
524}
70e88103 525
45212047 526wxxVariant wxXmlReader::ReadValue(wxXmlNode *node,
16776ad9 527 wxPropertyAccessor *accessor )
45212047 528{
16776ad9 529 return accessor->ReadValue(wxXmlGetContentFromNode( node ) ) ;
45212047
SC
530}
531
532int wxXmlReader::ReadObject(wxDepersister *callbacks)
533{
16776ad9 534 return ReadComponent( m_parent , callbacks ) ;
70e88103
SC
535}
536
537// ----------------------------------------------------------------------------
538// depersisting to memory
539// ----------------------------------------------------------------------------
540
45212047 541struct wxRuntimeDepersister::wxRuntimeDepersisterInternal
70e88103 542{
45212047
SC
543 map<int,wxObject *> m_objects;
544
16776ad9
SC
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 }
45212047
SC
558} ;
559
560wxRuntimeDepersister::wxRuntimeDepersister()
561{
16776ad9 562 m_data = new wxRuntimeDepersisterInternal() ;
70e88103
SC
563}
564
45212047 565wxRuntimeDepersister::~wxRuntimeDepersister()
70e88103 566{
16776ad9 567 delete m_data ;
70e88103
SC
568}
569
45212047 570void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo)
70e88103
SC
571{
572 wxObject *O;
45212047
SC
573 O = classInfo->CreateObject();
574 m_data->SetObject(objectID, O);
575}
576
577void wxRuntimeDepersister::CreateObject(int objectID,
16776ad9
SC
578 const wxClassInfo *classInfo,
579 int paramCount,
580 wxxVariant *params,
581 int *objectIdValues,
582 const wxClassInfo **objectClassInfos)
45212047
SC
583{
584 wxObject *o;
585 o = m_data->GetObject(objectID);
16776ad9
SC
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 }
45212047
SC
595 classInfo->Create(o, paramCount, params);
596}
597
598void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
599{
600 wxObject *o;
601 o = m_data->GetObject(objectID);
16776ad9 602 delete o ;
70e88103
SC
603}
604
45212047 605void wxRuntimeDepersister::SetProperty(int objectID,
16776ad9
SC
606 const wxClassInfo *WXUNUSED(classInfo),
607 const wxPropertyInfo* propertyInfo,
608 const wxxVariant &value)
70e88103 609{
45212047
SC
610 wxObject *o;
611 o = m_data->GetObject(objectID);
16776ad9 612 propertyInfo->GetAccessor()->SetProperty( o , value ) ;
45212047
SC
613}
614
615void wxRuntimeDepersister::SetPropertyAsObject(int objectID,
16776ad9
SC
616 const wxClassInfo *WXUNUSED(classInfo),
617 const wxPropertyInfo* propertyInfo,
618 int valueObjectId)
45212047
SC
619{
620 wxObject *o, *valo;
621 o = m_data->GetObject(objectID);
622 valo = m_data->GetObject(valueObjectId);
16776ad9
SC
623 propertyInfo->GetAccessor()->SetProperty( o ,
624 (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo()->InstanceToVariant(valo) ) ;
45212047
SC
625}
626
627void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
16776ad9
SC
628 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
629 const wxDelegateTypeInfo *delegateInfo ,
630 const wxClassInfo *WXUNUSED(eventSinkClassInfo) ,
631 const wxHandlerInfo* handlerInfo ,
632 int eventSinkObjectID )
45212047 633{
16776ad9
SC
634 wxWindow *ehsource = dynamic_cast< wxWindow* >( m_data->GetObject( eventSourceObjectID ) ) ;
635 wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ;
70e88103 636
16776ad9
SC
637 if ( ehsource && ehsink )
638 {
639 ehsource->Connect( ehsource->GetId() , delegateInfo->GetEventType() ,
640 handlerInfo->GetEventFunction() , NULL /*user data*/ ,
641 ehsink ) ;
642 }
70e88103
SC
643}
644
45212047
SC
645wxObject *wxRuntimeDepersister::GetObject(int objectID)
646{
16776ad9 647 return m_data->GetObject( objectID ) ;
45212047
SC
648}
649
650
70e88103
SC
651// ----------------------------------------------------------------------------
652// depersisting to code
653// ----------------------------------------------------------------------------
654
45212047
SC
655struct wxCodeDepersister::wxCodeDepersisterInternal
656{
657 map<int,string> m_objectNames ;
658
16776ad9
SC
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 }
45212047 672} ;
70e88103 673
45212047 674wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out)
16776ad9 675: m_fp(out)
70e88103 676{
16776ad9 677 m_data = new wxCodeDepersisterInternal ;
45212047
SC
678}
679
680wxCodeDepersister::~wxCodeDepersister()
681{
16776ad9 682 delete m_data ;
45212047
SC
683}
684
685void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo)
686{
16776ad9
SC
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 ) ;
45212047
SC
693}
694
695void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
696{
16776ad9
SC
697 m_fp->WriteString( wxString::Format( "\tdelete %s;\n",
698 m_data->GetObjectName( objectID) ) );
45212047
SC
699}
700
701wxString wxCodeDepersister::ValueAsCode( const wxxVariant &param )
702{
16776ad9
SC
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 ;
70e88103
SC
720}
721
45212047 722void wxCodeDepersister::CreateObject(int objectID,
16776ad9
SC
723 const wxClassInfo *WXUNUSED(classInfo),
724 int paramCount,
725 wxxVariant *params,
726 int *objectIDValues,
727 const wxClassInfo **WXUNUSED(objectClassInfos)
728 )
70e88103
SC
729{
730 int i;
16776ad9 731 m_fp->WriteString( wxString::Format( "\t%s->Create(", m_data->GetObjectName(objectID) ) );
45212047 732 for (i = 0; i < paramCount; i++)
70e88103 733 {
16776ad9
SC
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( ", ");
70e88103 742 }
45212047 743 m_fp->WriteString( ");\n");
70e88103
SC
744}
745
45212047 746void wxCodeDepersister::SetProperty(int objectID,
16776ad9
SC
747 const wxClassInfo *WXUNUSED(classInfo),
748 const wxPropertyInfo* propertyInfo,
749 const wxxVariant &value)
70e88103 750{
45212047 751 m_fp->WriteString( wxString::Format( "\t%s->%s(%s);\n",
16776ad9
SC
752 m_data->GetObjectName(objectID),
753 propertyInfo->GetAccessor()->GetSetterName(),
754 ValueAsCode(value)) );
45212047
SC
755}
756
757void wxCodeDepersister::SetPropertyAsObject(int objectID,
16776ad9
SC
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) ) );
70e88103
SC
772}
773
45212047 774void wxCodeDepersister::SetConnect(int eventSourceObjectID,
16776ad9
SC
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 ) );
70e88103
SC
789}
790
791#endif