1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/xtistrm.cpp
3 // Purpose: streaming runtime metadata information
4 // Author: Stefan Csomor
8 // Copyright: (c) 2003 Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "xtistrm.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/object.h"
28 #include "wx/xml/xml.h"
29 #include "wx/tokenzr.h"
30 #include "wx/xtistrm.h"
31 #include "wx/txtstrm.h"
33 #if wxUSE_EXTENDED_RTTI
40 struct wxWriter::wxWriterInternal
42 map
< const wxObject
* , int > m_writtenObjects
;
48 m_data
= new wxWriterInternal
;
49 m_data
->m_nextId
= 0 ;
57 struct wxWriter::wxWriterInternalPropertiesData
59 map
< string
, int > m_writtenProperties
;
62 void wxWriter::WriteObject(const wxObject
*object
, const wxClassInfo
*classInfo
, wxPersister
*persister
, const wxString
&name
)
64 if ( persister
->BeforeWriteObject( object
, classInfo
, name
) )
66 if ( object
== NULL
|| IsObjectKnown( object
) )
68 DoWriteObjectReference( NULL
, NULL
, object
, classInfo
, GetObjectID(object
) , NULL
) ;
72 int oid
= m_data
->m_nextId
++ ;
73 m_data
->m_writtenObjects
[object
] = oid
;
74 // in case this object is a wxDynamicObject we also have to insert is superclass
75 // instance with the same id, so that object relations are streamed out correctly
76 const wxDynamicObject
* dynobj
= dynamic_cast<const wxDynamicObject
*>( object
) ;
78 m_data
->m_writtenObjects
[dynobj
->GetSuperClassInstance()] = oid
;
80 DoBeginWriteObject( object
, classInfo
, oid
, name
) ;
81 wxWriterInternalPropertiesData data
;
82 WriteAllProperties( object
, classInfo
, persister
, &data
) ;
83 DoEndWriteObject( object
, classInfo
, oid
, name
) ;
88 void wxWriter::WriteAllProperties( const wxObject
* obj
, const wxClassInfo
* ci
, wxPersister
*persister
, wxWriterInternalPropertiesData
* data
)
90 const wxPropertyInfo
*pi
= ci
->GetFirstProperty() ;
93 if ( data
->m_writtenProperties
.find( pi
->GetName() ) == data
->m_writtenProperties
.end() )
95 data
->m_writtenProperties
[ pi
->GetName() ] = 1 ;
96 const wxClassTypeInfo
* cti
= dynamic_cast< const wxClassTypeInfo
* > ( pi
->GetTypeInfo() ) ;
99 const wxClassInfo
* pci
= cti
->GetClassInfo() ;
100 wxxVariant value
= pi
->GetAccessor()->GetProperty(obj
) ;
101 if ( persister
->BeforeWritePropertyAsObject( obj
, ci
, pi
, value
) )
103 wxObject
*vobj
= pci
->VariantToInstance( value
) ;
104 bool embeddedObject
= cti
->GetKind() == wxT_OBJECT
;
106 if ( vobj
== NULL
|| IsObjectKnown( vobj
) )
108 DoWriteObjectReference( obj
, ci
, vobj
, pci
, GetObjectID(vobj
) , pi
) ;
112 int oid
= m_data
->m_nextId
++ ;
113 if ( !embeddedObject
)
115 // insert this object and its id
116 m_data
->m_writtenObjects
[vobj
] = oid
;
117 // in case this object is a wxDynamicObject we also have to insert is superclass
118 // instance with the same id, so that object relations are streamed out correctly
119 const wxDynamicObject
* dynobj
= dynamic_cast<const wxDynamicObject
*>( vobj
) ;
121 m_data
->m_writtenObjects
[dynobj
->GetSuperClassInstance()] = oid
;
124 DoBeginWriteParamAsObject( obj
, ci
, vobj
, pci
, oid
, pi
) ;
127 wxWriterInternalPropertiesData data
;
128 WriteAllProperties( vobj
, pci
, persister
, &data
) ;
130 DoEndWriteParamAsObject( obj
, ci
, vobj
, pci
, oid
, pi
) ;
136 const wxDelegateTypeInfo
* dti
= dynamic_cast< const wxDelegateTypeInfo
* > ( pi
->GetTypeInfo() ) ;
139 const wxObject
* sink
= NULL
;
140 const wxHandlerInfo
*handler
= NULL
;
142 const wxWindow
* evSource
= dynamic_cast<const wxWindow
*>(obj
) ;
143 wxASSERT_MSG( evSource
, wxT("Illegal Object Class (Non-Window) as Event Source") ) ;
145 wxList
*dynamicEvents
= evSource
->GetDynamicEventTable() ;
149 wxList::compatibility_iterator node
= dynamicEvents
->GetFirst();
152 wxDynamicEventTableEntry
*entry
= (wxDynamicEventTableEntry
*)node
->GetData();
155 if ( entry
->m_fn
&& (dti
->GetEventType() == entry
->m_eventType
) &&
156 (entry
->m_id
== -1 ||
157 (entry
->m_lastId
== -1 && evSource
->GetId() == entry
->m_id
) ||
158 (entry
->m_lastId
!= -1 &&
159 (evSource
->GetId() >= entry
->m_id
&& evSource
->GetId() <= entry
->m_lastId
) ) ) &&
163 sink
= entry
->m_eventSink
;
164 const wxClassInfo
* sinkClassInfo
= sink
->GetClassInfo() ;
165 const wxHandlerInfo
* sinkHandler
= sinkClassInfo
->GetFirstHandler() ;
166 while ( sinkHandler
)
168 if ( sinkHandler
->GetEventFunction() == entry
->m_fn
)
170 handler
= sinkHandler
;
173 sinkHandler
= sinkHandler
->GetNext() ;
177 node
= node
->GetNext();
180 if ( persister
->BeforeWriteDelegate( obj
, ci
, pi
, sink
, handler
) )
182 if ( sink
!= NULL
&& handler
!= NULL
)
184 wxASSERT_MSG( IsObjectKnown( sink
) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
185 DoWriteDelegate( obj
, ci
, pi
, sink
, GetObjectID( sink
) , sink
->GetClassInfo() , handler
) ;
191 wxxVariant value
= pi
->GetAccessor()->GetProperty(obj
) ;
192 if ( persister
->BeforeWriteProperty( obj
, ci
, pi
, value
) )
194 DoWriteProperty( obj
, ci
, pi
, value
) ;
201 // in case this object is wxDynamic object we have to hand over the streaming
202 // of the properties of the superclasses to the real super class instance
203 const wxDynamicObject
* dynobj
= dynamic_cast< const wxDynamicObject
* > (obj
) ;
205 obj
= dynobj
->GetSuperClassInstance() ;
206 const wxClassInfo
** parents
= ci
->GetParents() ;
207 for ( int i
= 0 ; parents
[i
] ; ++ i
)
209 WriteAllProperties( obj
, parents
[i
] , persister
, data
) ;
213 int wxWriter::GetObjectID(const wxObject
*obj
)
215 if ( !IsObjectKnown( obj
) )
216 return wxInvalidObjectID
;
218 return m_data
->m_writtenObjects
[obj
] ;
221 bool wxWriter::IsObjectKnown( const wxObject
*obj
)
223 return m_data
->m_writtenObjects
.find( obj
) != m_data
->m_writtenObjects
.end() ;
230 // convenience functions
232 void wxXmlAddContentToNode( wxXmlNode
* node
, const wxString
& data
)
234 node
->AddChild(new wxXmlNode(wxXML_TEXT_NODE
, "value", data
) );
237 wxString
wxXmlGetContentFromNode( wxXmlNode
*node
)
239 if ( node
->GetChildren() )
240 return node
->GetChildren()->GetContent() ;
242 return wxEmptyString
;
245 struct wxXmlWriter::wxXmlWriterInternal
248 wxXmlNode
*m_current
;
249 vector
< wxXmlNode
* > m_objectStack
;
252 wxXmlWriter::wxXmlWriter( wxXmlNode
* rootnode
)
254 m_data
= new wxXmlWriterInternal() ;
255 m_data
->m_root
= rootnode
;
256 m_data
->m_current
= rootnode
;
259 wxXmlWriter::~wxXmlWriter()
264 // start of writing the root object
265 void wxXmlWriter::DoBeginWriteObject(const wxObject
*WXUNUSED(object
), const wxClassInfo
*classInfo
, int objectID
, const wxString
&name
)
268 onode
= new wxXmlNode(wxXML_ELEMENT_NODE
, name
);
269 onode
->AddProperty(wxString("class"), wxString(classInfo
->GetClassName()));
270 onode
->AddProperty(wxString("id"), wxString::Format( "%d" , objectID
) );
272 m_data
->m_current
->AddChild(onode
) ;
273 m_data
->m_objectStack
.push_back( m_data
->m_current
) ;
274 m_data
->m_current
= onode
;
277 // end of writing the root object
278 void wxXmlWriter::DoEndWriteObject(const wxObject
*WXUNUSED(object
), const wxClassInfo
*WXUNUSED(classInfo
), int WXUNUSED(objectID
) , const wxString
&WXUNUSED(name
) )
280 m_data
->m_current
= m_data
->m_objectStack
.back() ;
281 m_data
->m_objectStack
.pop_back() ;
284 // writes a property in the stream format
285 void wxXmlWriter::DoWriteProperty( const wxObject
*WXUNUSED(obj
), const wxClassInfo
* WXUNUSED(classInfo
) , const wxPropertyInfo
*pi
, wxxVariant
&value
)
288 pnode
= new wxXmlNode(wxXML_ELEMENT_NODE
, pi
->GetName() );
289 wxXmlAddContentToNode( pnode
,value
.GetAsString() ) ;
290 m_data
->m_current
->AddChild(pnode
);
293 void wxXmlWriter::DoBeginWriteParamAsObject(const wxObject
*WXUNUSED(parentObject
), const wxClassInfo
*WXUNUSED(parentClassInfo
), const wxObject
*WXUNUSED(valueObject
),
294 const wxClassInfo
*valueObjectClassInfo
, int valueObjectID
, const wxPropertyInfo
*propInfo
)
297 onode
= new wxXmlNode(wxXML_ELEMENT_NODE
, propInfo
->GetName());
298 onode
->AddProperty(wxString("class"), wxString(valueObjectClassInfo
->GetClassName()));
299 onode
->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID
) );
300 m_data
->m_current
->AddChild(onode
) ;
301 m_data
->m_objectStack
.push_back( m_data
->m_current
) ;
302 m_data
->m_current
= onode
;
305 // insert an object reference to an already written object
306 void wxXmlWriter::DoWriteObjectReference(const wxObject
*WXUNUSED(parentObject
), const wxClassInfo
*WXUNUSED(parentClassInfo
), const wxObject
*valueObject
,
307 const wxClassInfo
*valueObjectClassInfo
, int valueObjectID
, const wxPropertyInfo
*propInfo
)
310 onode
= new wxXmlNode(wxXML_ELEMENT_NODE
, propInfo
->GetName());
311 onode
->AddProperty(wxString("class"), wxString(valueObjectClassInfo
->GetClassName()));
312 if ( valueObject
== NULL
)
314 wxXmlNode
* nullnode
= new wxXmlNode(wxXML_TEXT_NODE
, wxEmptyString
, "null");
315 onode
->AddChild(nullnode
);
319 onode
->AddProperty(wxString("id"), wxString::Format( "%d" , valueObjectID
) );
322 m_data
->m_current
->AddChild(onode
) ;
325 void wxXmlWriter::DoEndWriteParamAsObject(const wxObject
*WXUNUSED(parentObject
), const wxClassInfo
*WXUNUSED(parentClassInfo
), const wxObject
*WXUNUSED(valueObject
),
326 const wxClassInfo
*WXUNUSED(valueObjectClassInfo
), int WXUNUSED(valueObjectID
) , const wxPropertyInfo
*WXUNUSED(propInfo
) )
328 m_data
->m_current
= m_data
->m_objectStack
.back() ;
329 m_data
->m_objectStack
.pop_back() ;
333 // writes a delegate in the stream format
334 void wxXmlWriter::DoWriteDelegate( const wxObject
*WXUNUSED(object
), const wxClassInfo
* WXUNUSED(classInfo
) , const wxPropertyInfo
*pi
,
335 const wxObject
*eventSink
, int sinkObjectID
, const wxClassInfo
* WXUNUSED(eventSinkClassInfo
) , const wxHandlerInfo
* handlerInfo
)
337 if ( eventSink
!= NULL
&& handlerInfo
!= NULL
)
340 pnode
= new wxXmlNode(wxXML_ELEMENT_NODE
, pi
->GetName() );
342 s
.Printf(wxT("%d.%s"), sinkObjectID
, handlerInfo
->GetName() ) ;
343 wxXmlAddContentToNode( pnode
,s
) ;
344 m_data
->m_current
->AddChild(pnode
);
348 // ----------------------------------------------------------------------------
349 // reading objects in
350 // ----------------------------------------------------------------------------
352 struct wxReader::wxReaderInternal
354 map
<int,wxClassInfo
*> m_classInfos
;
359 m_data
= new wxReaderInternal
;
362 wxReader::~wxReader()
367 wxClassInfo
* wxReader::GetObjectClassInfo(int objectID
)
369 assert( m_data
->m_classInfos
.find(objectID
) != m_data
->m_classInfos
.end() );
370 return m_data
->m_classInfos
[objectID
] ;
373 void wxReader::SetObjectClassInfo(int objectID
, wxClassInfo
*classInfo
)
375 assert( m_data
->m_classInfos
.find(objectID
) == m_data
->m_classInfos
.end() ) ;
376 m_data
->m_classInfos
[objectID
] = classInfo
;
379 bool wxReader::HasObjectClassInfo( int objectID
)
381 return m_data
->m_classInfos
.find(objectID
) != m_data
->m_classInfos
.end() ;
385 // ----------------------------------------------------------------------------
387 // ----------------------------------------------------------------------------
390 Reading components has not to be extended for components
391 as properties are always sought by typeinfo over all levels
392 and create params are always toplevel class only
395 int wxXmlReader::ReadComponent(wxXmlNode
*node
, wxDepersister
*callbacks
)
398 wxClassInfo
*classInfo
;
400 wxxVariant
*createParams
;
401 int *createParamOids
;
402 const wxClassInfo
** createClassInfos
;
406 children
= node
->GetChildren();
407 if (!node
->GetPropVal("class", &className
))
409 // No class name. Eek. FIXME: error handling
410 return wxInvalidObjectID
;
412 classInfo
= wxClassInfo::FindClass(className
);
413 if (children
&& children
->GetType() == wxXML_TEXT_NODE
)
415 assert( wxXmlGetContentFromNode(node
) == "null" ) ;
416 // this must be a NULL component reference. We just bail out
417 return wxNullObjectID
;
420 wxString ObjectIdString
;
421 if (!node
->GetPropVal("id", &ObjectIdString
))
423 // No object id. Eek. FIXME: error handling
424 return wxInvalidObjectID
;
427 objectID
= atoi( ObjectIdString
.c_str() ) ;
428 // is this object already has been streamed in, return it here
429 if ( HasObjectClassInfo( objectID
) )
432 // new object, start with allocation
433 // first make the object know to our internal registry
434 SetObjectClassInfo( objectID
, classInfo
) ;
436 callbacks
->AllocateObject(objectID
, classInfo
);
439 // stream back the Create parameters first
440 createParams
= new wxxVariant
[ classInfo
->GetCreateParamCount() ] ;
441 createParamOids
= new int[classInfo
->GetCreateParamCount() ] ;
442 createClassInfos
= new const wxClassInfo
*[classInfo
->GetCreateParamCount() ] ;
444 typedef map
<string
, wxXmlNode
*> PropertyNodes
;
445 typedef vector
<string
> PropertyNames
;
447 PropertyNodes propertyNodes
;
448 PropertyNames propertyNames
;
452 propertyNames
.push_back( children
->GetName().c_str() ) ;
453 propertyNodes
[children
->GetName().c_str()] = children
;
454 children
= children
->GetNext() ;
457 for ( int i
= 0 ; i
<classInfo
->GetCreateParamCount() ; ++i
)
459 const wxChar
* paramName
= classInfo
->GetCreateParamName(i
) ;
460 PropertyNodes::iterator propiter
= propertyNodes
.find( paramName
) ;
461 const wxPropertyInfo
* pi
= classInfo
->FindPropertyInfo( paramName
) ;
462 // if we don't have the value of a create param set in the xml
463 // we use the default value
464 if ( propiter
!= propertyNodes
.end() )
466 wxXmlNode
* prop
= propiter
->second
;
467 if ( pi
->GetTypeInfo()->IsObjectType() )
469 createParamOids
[i
] = ReadComponent( prop
, callbacks
) ;
470 createClassInfos
[i
] = dynamic_cast<const wxClassTypeInfo
*>(pi
->GetTypeInfo())->GetClassInfo() ;
474 createParamOids
[i
] = wxInvalidObjectID
;
475 createParams
[i
] = ReadValue( prop
, pi
->GetAccessor() ) ;
476 createClassInfos
[i
] = NULL
;
479 for ( size_t j
= 0 ; j
< propertyNames
.size() ; ++j
)
481 if ( propertyNames
[j
] == paramName
)
483 propertyNames
[j
] = "" ;
490 createParams
[i
] = pi
->GetDefaultValue() ;
494 // got the parameters. Call the Create method
495 callbacks
->CreateObject(objectID
, classInfo
,
496 classInfo
->GetCreateParamCount(),
497 createParams
, createParamOids
, createClassInfos
);
499 // now stream in the rest of the properties, in the sequence their properties were written in the xml
500 for ( size_t j
= 0 ; j
< propertyNames
.size() ; ++j
)
502 if ( propertyNames
[j
].length() )
504 PropertyNodes::iterator propiter
= propertyNodes
.find( propertyNames
[j
] ) ;
505 if ( propiter
!= propertyNodes
.end() )
507 wxXmlNode
* prop
= propiter
->second
;
508 const wxPropertyInfo
* pi
= classInfo
->FindPropertyInfo( propertyNames
[j
].c_str() ) ;
509 if ( pi
->GetTypeInfo()->IsObjectType() )
511 int valueId
= ReadComponent( prop
, callbacks
) ;
514 if ( valueId
!= wxInvalidObjectID
)
516 callbacks
->SetPropertyAsObject( objectID
, classInfo
, pi
, valueId
) ;
517 if ( pi
->GetTypeInfo()->GetKind() == wxT_OBJECT
&& valueId
!= wxNullObjectID
)
518 callbacks
->DestroyObject( valueId
, GetObjectClassInfo( valueId
) ) ;
522 else if ( pi
->GetTypeInfo()->IsDelegateType() )
524 wxString resstring
= wxXmlGetContentFromNode(prop
) ;
525 wxInt32 pos
= resstring
.Find('.') ;
526 assert( pos
!= wxNOT_FOUND
) ;
527 int sinkOid
= atol(resstring
.Left(pos
)) ;
528 wxString handlerName
= resstring
.Mid(pos
+1) ;
529 wxClassInfo
* sinkClassInfo
= GetObjectClassInfo( sinkOid
) ;
532 callbacks
->SetConnect( objectID
, classInfo
, dynamic_cast<const wxDelegateTypeInfo
*>(pi
->GetTypeInfo()) , sinkClassInfo
,
533 sinkClassInfo
->FindHandlerInfo(handlerName
) , sinkOid
) ;
539 callbacks
->SetProperty( objectID
, classInfo
,pi
, ReadValue( prop
, pi
->GetAccessor() ) ) ;
545 delete[] createParams
;
546 delete[] createParamOids
;
547 delete[] createClassInfos
;
552 wxxVariant
wxXmlReader::ReadValue(wxXmlNode
*node
,
553 wxPropertyAccessor
*accessor
)
555 return accessor
->ReadValue(wxXmlGetContentFromNode( node
) ) ;
558 int wxXmlReader::ReadObject(wxDepersister
*callbacks
)
560 return ReadComponent( m_parent
, callbacks
) ;
563 // ----------------------------------------------------------------------------
564 // depersisting to memory
565 // ----------------------------------------------------------------------------
567 struct wxRuntimeDepersister::wxRuntimeDepersisterInternal
569 map
<int,wxObject
*> m_objects
;
571 void SetObject(int objectID
, wxObject
*obj
)
573 assert( m_objects
.find(objectID
) == m_objects
.end() ) ;
574 m_objects
[objectID
] = obj
;
576 wxObject
* GetObject( int objectID
)
578 if ( objectID
== wxNullObjectID
)
581 assert( m_objects
.find(objectID
) != m_objects
.end() ) ;
582 return m_objects
[objectID
] ;
586 wxRuntimeDepersister::wxRuntimeDepersister()
588 m_data
= new wxRuntimeDepersisterInternal() ;
591 wxRuntimeDepersister::~wxRuntimeDepersister()
596 void wxRuntimeDepersister::AllocateObject(int objectID
, wxClassInfo
*classInfo
)
599 O
= classInfo
->CreateObject();
600 m_data
->SetObject(objectID
, O
);
603 void wxRuntimeDepersister::CreateObject(int objectID
,
604 const wxClassInfo
*classInfo
,
608 const wxClassInfo
**objectClassInfos
)
611 o
= m_data
->GetObject(objectID
);
612 for ( int i
= 0 ; i
< paramCount
; ++i
)
614 if ( objectIdValues
[i
] != wxInvalidObjectID
)
617 o
= m_data
->GetObject(objectIdValues
[i
]);
618 // if this is a dynamic object and we are asked for another class
619 // than wxDynamicObject we cast it down manually.
620 wxDynamicObject
*dyno
= dynamic_cast< wxDynamicObject
* > (o
) ;
621 if ( dyno
!=NULL
&& (objectClassInfos
[i
] != dyno
->GetClassInfo()) )
623 o
= dyno
->GetSuperClassInstance() ;
625 params
[i
] = objectClassInfos
[i
]->InstanceToVariant(o
) ;
628 classInfo
->Create(o
, paramCount
, params
);
631 void wxRuntimeDepersister::DestroyObject(int objectID
, wxClassInfo
*WXUNUSED(classInfo
))
634 o
= m_data
->GetObject(objectID
);
638 void wxRuntimeDepersister::SetProperty(int objectID
,
639 const wxClassInfo
*classInfo
,
640 const wxPropertyInfo
* propertyInfo
,
641 const wxxVariant
&value
)
644 o
= m_data
->GetObject(objectID
);
645 classInfo
->SetProperty( o
, propertyInfo
->GetName() , value
) ;
646 // propertyInfo->GetAccessor()->SetProperty( o , value ) ;
649 void wxRuntimeDepersister::SetPropertyAsObject(int objectID
,
650 const wxClassInfo
*classInfo
,
651 const wxPropertyInfo
* propertyInfo
,
655 o
= m_data
->GetObject(objectID
);
656 valo
= m_data
->GetObject(valueObjectId
);
657 const wxClassInfo
* valClassInfo
= (dynamic_cast<const wxClassTypeInfo
*>(propertyInfo
->GetTypeInfo()))->GetClassInfo() ;
658 // if this is a dynamic object and we are asked for another class
659 // than wxDynamicObject we cast it down manually.
660 wxDynamicObject
*dynvalo
= dynamic_cast< wxDynamicObject
* > (valo
) ;
661 if ( dynvalo
!=NULL
&& (valClassInfo
!= dynvalo
->GetClassInfo()) )
663 valo
= dynvalo
->GetSuperClassInstance() ;
666 classInfo
->SetProperty( o
, propertyInfo
->GetName() , valClassInfo
->InstanceToVariant(valo
) ) ;
667 // propertyInfo->GetAccessor()->SetProperty( o ,
668 // (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo()->InstanceToVariant(valo) ) ;
671 void wxRuntimeDepersister::SetConnect(int eventSourceObjectID
,
672 const wxClassInfo
*WXUNUSED(eventSourceClassInfo
),
673 const wxDelegateTypeInfo
*delegateInfo
,
674 const wxClassInfo
*WXUNUSED(eventSinkClassInfo
) ,
675 const wxHandlerInfo
* handlerInfo
,
676 int eventSinkObjectID
)
678 wxWindow
*ehsource
= dynamic_cast< wxWindow
* >( m_data
->GetObject( eventSourceObjectID
) ) ;
679 wxEvtHandler
*ehsink
= dynamic_cast< wxEvtHandler
*>(m_data
->GetObject(eventSinkObjectID
) ) ;
681 if ( ehsource
&& ehsink
)
683 ehsource
->Connect( ehsource
->GetId() , delegateInfo
->GetEventType() ,
684 handlerInfo
->GetEventFunction() , NULL
/*user data*/ ,
689 wxObject
*wxRuntimeDepersister::GetObject(int objectID
)
691 return m_data
->GetObject( objectID
) ;
695 // ----------------------------------------------------------------------------
696 // depersisting to code
697 // ----------------------------------------------------------------------------
699 struct wxCodeDepersister::wxCodeDepersisterInternal
701 map
<int,string
> m_objectNames
;
703 void SetObjectName(int objectID
, const wxString
&name
)
705 assert( m_objectNames
.find(objectID
) == m_objectNames
.end() ) ;
706 m_objectNames
[objectID
] = (const char *)name
;
708 wxString
GetObjectName( int objectID
)
710 if ( objectID
== wxNullObjectID
)
713 assert( m_objectNames
.find(objectID
) != m_objectNames
.end() ) ;
714 return wxString( m_objectNames
[objectID
].c_str() ) ;
718 wxCodeDepersister::wxCodeDepersister(wxTextOutputStream
*out
)
721 m_data
= new wxCodeDepersisterInternal
;
724 wxCodeDepersister::~wxCodeDepersister()
729 void wxCodeDepersister::AllocateObject(int objectID
, wxClassInfo
*classInfo
)
731 wxString objectName
= wxString::Format( "LocalObject_%d" , objectID
) ;
732 m_fp
->WriteString( wxString::Format( "\t%s *%s = new %s;\n",
733 classInfo
->GetClassName(),
735 classInfo
->GetClassName()) );
736 m_data
->SetObjectName( objectID
, objectName
) ;
739 void wxCodeDepersister::DestroyObject(int objectID
, wxClassInfo
*WXUNUSED(classInfo
))
741 m_fp
->WriteString( wxString::Format( "\tdelete %s;\n",
742 m_data
->GetObjectName( objectID
) ) );
745 wxString
wxCodeDepersister::ValueAsCode( const wxxVariant
¶m
)
748 const wxTypeInfo
* type
= param
.GetTypeInfo() ;
749 if ( type
->GetKind() == wxT_CUSTOM
)
751 const wxCustomTypeInfo
* cti
= dynamic_cast<const wxCustomTypeInfo
*>(type
) ;
752 wxASSERT_MSG( cti
, wxT("Internal error, illegal wxCustomTypeInfo") ) ;
753 value
.Printf( "%s(%s)",cti
->GetTypeName(),param
.GetAsString() );
755 else if ( type
->GetKind() == wxT_STRING
)
757 value
.Printf( "\"%s\"",param
.GetAsString() );
761 value
.Printf( "%s", param
.GetAsString() );
766 void wxCodeDepersister::CreateObject(int objectID
,
767 const wxClassInfo
*WXUNUSED(classInfo
),
771 const wxClassInfo
**WXUNUSED(objectClassInfos
)
775 m_fp
->WriteString( wxString::Format( "\t%s->Create(", m_data
->GetObjectName(objectID
) ) );
776 for (i
= 0; i
< paramCount
; i
++)
778 if ( objectIDValues
[i
] != wxInvalidObjectID
)
779 m_fp
->WriteString( wxString::Format( "%s", m_data
->GetObjectName( objectIDValues
[i
] ) ) );
782 m_fp
->WriteString( wxString::Format( "%s", ValueAsCode(params
[i
]) ) );
784 if (i
< paramCount
- 1)
785 m_fp
->WriteString( ", ");
787 m_fp
->WriteString( ");\n");
790 void wxCodeDepersister::SetProperty(int objectID
,
791 const wxClassInfo
*WXUNUSED(classInfo
),
792 const wxPropertyInfo
* propertyInfo
,
793 const wxxVariant
&value
)
795 m_fp
->WriteString( wxString::Format( "\t%s->%s(%s);\n",
796 m_data
->GetObjectName(objectID
),
797 propertyInfo
->GetAccessor()->GetSetterName(),
798 ValueAsCode(value
)) );
801 void wxCodeDepersister::SetPropertyAsObject(int objectID
,
802 const wxClassInfo
*WXUNUSED(classInfo
),
803 const wxPropertyInfo
* propertyInfo
,
806 if ( propertyInfo
->GetTypeInfo()->GetKind() == wxT_OBJECT
)
807 m_fp
->WriteString( wxString::Format( "\t%s->%s(*%s);\n",
808 m_data
->GetObjectName(objectID
),
809 propertyInfo
->GetAccessor()->GetSetterName(),
810 m_data
->GetObjectName( valueObjectId
) ) );
812 m_fp
->WriteString( wxString::Format( "\t%s->%s(%s);\n",
813 m_data
->GetObjectName(objectID
),
814 propertyInfo
->GetAccessor()->GetSetterName(),
815 m_data
->GetObjectName( valueObjectId
) ) );
818 void wxCodeDepersister::SetConnect(int eventSourceObjectID
,
819 const wxClassInfo
*WXUNUSED(eventSourceClassInfo
),
820 const wxDelegateTypeInfo
*delegateInfo
,
821 const wxClassInfo
*eventSinkClassInfo
,
822 const wxHandlerInfo
* handlerInfo
,
823 int eventSinkObjectID
)
825 wxString ehsource
= m_data
->GetObjectName( eventSourceObjectID
) ;
826 wxString ehsink
= m_data
->GetObjectName(eventSinkObjectID
) ;
827 wxString ehsinkClass
= eventSinkClassInfo
->GetClassName() ;
828 int eventType
= delegateInfo
->GetEventType() ;
829 wxString handlerName
= handlerInfo
->GetName() ;
831 m_fp
->WriteString( wxString::Format( "\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;" ,
832 ehsource
, ehsource
, eventType
, ehsinkClass
, handlerName
, ehsink
) );