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 // Copyright: (c) 2003 Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14
15 #if wxUSE_EXTENDED_RTTI
16
17 #include "wx/xtistrm.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/object.h"
21 #include "wx/hash.h"
22 #include "wx/event.h"
23 #endif
24
25 #include "wx/tokenzr.h"
26 #include "wx/txtstrm.h"
27
28 // STL headers:
29
30 #include "wx/beforestd.h"
31 #include <map>
32 #include <vector>
33 #include <string>
34 #include "wx/afterstd.h"
35 using namespace std;
36
37
38 // ----------------------------------------------------------------------------
39 // wxObjectWriter
40 // ----------------------------------------------------------------------------
41
42 struct wxObjectWriter::wxObjectWriterInternal
43 {
44 map< const wxObject*, int > m_writtenObjects;
45 int m_nextId;
46 };
47
wxObjectWriter()48 wxObjectWriter::wxObjectWriter()
49 {
50 m_data = new wxObjectWriterInternal;
51 m_data->m_nextId = 0;
52 }
53
~wxObjectWriter()54 wxObjectWriter::~wxObjectWriter()
55 {
56 delete m_data;
57 }
58
59 struct wxObjectWriter::wxObjectWriterInternalPropertiesData
60 {
61 char nothing;
62 };
63
ClearObjectContext()64 void wxObjectWriter::ClearObjectContext()
65 {
66 delete m_data;
67 m_data = new wxObjectWriterInternal();
68 m_data->m_nextId = 0;
69 }
70
WriteObject(const wxObject * object,const wxClassInfo * classInfo,wxObjectWriterCallback * writercallback,const wxString & name,const wxStringToAnyHashMap & metadata)71 void wxObjectWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo,
72 wxObjectWriterCallback *writercallback, const wxString &name,
73 const wxStringToAnyHashMap &metadata )
74 {
75 DoBeginWriteTopLevelEntry( name );
76 WriteObject( object, classInfo, writercallback, false, metadata);
77 DoEndWriteTopLevelEntry( name );
78 }
79
WriteObject(const wxObject * object,const wxClassInfo * classInfo,wxObjectWriterCallback * writercallback,bool isEmbedded,const wxStringToAnyHashMap & metadata)80 void wxObjectWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo,
81 wxObjectWriterCallback *writercallback, bool isEmbedded,
82 const wxStringToAnyHashMap &metadata )
83 {
84 if ( !classInfo->BeforeWriteObject( object, this, writercallback, metadata) )
85 return;
86
87 if ( writercallback->BeforeWriteObject( this, object, classInfo, metadata) )
88 {
89 if ( object == NULL )
90 DoWriteNullObject();
91 else if ( IsObjectKnown( object ) )
92 DoWriteRepeatedObject( GetObjectID(object) );
93 else
94 {
95 int oid = m_data->m_nextId++;
96 if ( !isEmbedded )
97 m_data->m_writtenObjects[object] = oid;
98
99 // in case this object is a wxDynamicObject we also have to insert is superclass
100 // instance with the same id, so that object relations are streamed out correctly
101 const wxDynamicObject* dynobj = wx_dynamic_cast(const wxDynamicObject*, object);
102 if ( !isEmbedded && dynobj )
103 m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid;
104
105 DoBeginWriteObject( object, classInfo, oid, metadata );
106 wxObjectWriterInternalPropertiesData data;
107 WriteAllProperties( object, classInfo, writercallback, &data );
108 DoEndWriteObject( object, classInfo, oid );
109 }
110 writercallback->AfterWriteObject( this,object, classInfo );
111 }
112 }
113
FindConnectEntry(const wxEvtHandler * evSource,const wxEventSourceTypeInfo * dti,const wxObject * & sink,const wxHandlerInfo * & handler)114 void wxObjectWriter::FindConnectEntry(const wxEvtHandler * evSource,
115 const wxEventSourceTypeInfo* dti,
116 const wxObject* &sink,
117 const wxHandlerInfo *&handler)
118 {
119 size_t cookie;
120 for ( wxDynamicEventTableEntry* entry = evSource->GetFirstDynamicEntry(cookie);
121 entry;
122 entry = evSource->GetNextDynamicEntry(cookie) )
123 {
124 // find the match
125 if ( entry->m_fn &&
126 (dti->GetEventType() == entry->m_eventType) &&
127 (entry->m_id == -1 ) &&
128 (entry->m_fn->GetEvtHandler() != NULL ) )
129 {
130 sink = entry->m_fn->GetEvtHandler();
131 const wxClassInfo* sinkClassInfo = sink->GetClassInfo();
132 const wxHandlerInfo* sinkHandler = sinkClassInfo->GetFirstHandler();
133 while ( sinkHandler )
134 {
135 if ( sinkHandler->GetEventFunction() == entry->m_fn->GetEvtMethod() )
136 {
137 handler = sinkHandler;
138 break;
139 }
140 sinkHandler = sinkHandler->GetNext();
141 }
142 break;
143 }
144 }
145 }
WriteAllProperties(const wxObject * obj,const wxClassInfo * ci,wxObjectWriterCallback * writercallback,wxObjectWriterInternalPropertiesData * data)146 void wxObjectWriter::WriteAllProperties( const wxObject * obj, const wxClassInfo* ci,
147 wxObjectWriterCallback *writercallback,
148 wxObjectWriterInternalPropertiesData * data )
149 {
150 wxPropertyInfoMap map;
151 ci->GetProperties( map );
152 for ( int i = 0; i < ci->GetCreateParamCount(); ++i )
153 {
154 wxString name = ci->GetCreateParamName(i);
155 wxPropertyInfoMap::const_iterator iter = map.find(name);
156 const wxPropertyInfo* prop = iter == map.end() ? NULL : iter->second;
157 if ( prop )
158 {
159 WriteOneProperty( obj, prop->GetDeclaringClass(), prop, writercallback, data );
160 }
161 else
162 {
163 wxLogError( _("Create Parameter %s not found in declared RTTI Parameters"), name.c_str() );
164 }
165 map.erase( name );
166 }
167 { // Extra block for broken compilers
168 for( wxPropertyInfoMap::iterator iter = map.begin(); iter != map.end(); ++iter )
169 {
170 const wxPropertyInfo* prop = iter->second;
171 if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
172 {
173 WriteOneProperty( obj, prop->GetDeclaringClass(), prop, writercallback, data );
174 }
175 }
176 }
177 { // Extra block for broken compilers
178 for( wxPropertyInfoMap::iterator iter = map.begin(); iter != map.end(); ++iter )
179 {
180 const wxPropertyInfo* prop = iter->second;
181 if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
182 {
183 WriteOneProperty( obj, prop->GetDeclaringClass(), prop, writercallback, data );
184 }
185 }
186 }
187 }
188
189 class WXDLLIMPEXP_BASE wxObjectPropertyWriter: public wxObjectWriterFunctor
190 {
191 public:
wxObjectPropertyWriter(const wxClassTypeInfo * cti,wxObjectWriterCallback * writercallback,wxObjectWriter * writer,wxStringToAnyHashMap & props)192 wxObjectPropertyWriter(const wxClassTypeInfo* cti,
193 wxObjectWriterCallback *writercallback,
194 wxObjectWriter* writer,
195 wxStringToAnyHashMap &props) :
196 m_cti(cti),m_persister(writercallback),m_writer(writer),m_props(props)
197 {}
198
operator ()(const wxObject * vobj)199 virtual void operator()(const wxObject *vobj)
200 {
201 m_writer->WriteObject( vobj, (vobj ? vobj->GetClassInfo() : m_cti->GetClassInfo() ),
202 m_persister, m_cti->GetKind()== wxT_OBJECT, m_props );
203 }
204 private:
205 const wxClassTypeInfo* m_cti;
206 wxObjectWriterCallback *m_persister;
207 wxObjectWriter* m_writer;
208 wxStringToAnyHashMap& m_props;
209 };
210
WriteOneProperty(const wxObject * obj,const wxClassInfo * ci,const wxPropertyInfo * pi,wxObjectWriterCallback * writercallback,wxObjectWriterInternalPropertiesData * WXUNUSED (data))211 void wxObjectWriter::WriteOneProperty( const wxObject *obj, const wxClassInfo* ci,
212 const wxPropertyInfo* pi, wxObjectWriterCallback *writercallback,
213 wxObjectWriterInternalPropertiesData *WXUNUSED(data) )
214 {
215 if ( pi->GetFlags() & wxPROP_DONT_STREAM )
216 return;
217
218 // make sure that we are picking the correct object for accessing the property
219 const wxDynamicObject* dynobj = wx_dynamic_cast(const wxDynamicObject*, obj );
220 if ( dynobj && (wx_dynamic_cast(const wxDynamicClassInfo*, ci) == NULL) )
221 obj = dynobj->GetSuperClassInstance();
222
223 if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
224 {
225 wxAnyList data;
226 pi->GetAccessor()->GetPropertyCollection(obj, data);
227 const wxTypeInfo * elementType =
228 wx_dynamic_cast( const wxCollectionTypeInfo*, pi->GetTypeInfo() )->GetElementType();
229 if ( !data.empty() )
230 {
231 DoBeginWriteProperty( pi );
232 for ( wxAnyList::const_iterator iter = data.begin(); iter != data.end(); ++iter )
233 {
234 DoBeginWriteElement();
235 const wxAny* valptr = *iter;
236 if ( writercallback->BeforeWriteProperty( this, obj, pi, *valptr ) )
237 {
238 const wxClassTypeInfo* cti =
239 wx_dynamic_cast( const wxClassTypeInfo*, elementType );
240 if ( cti )
241 {
242 wxStringToAnyHashMap md;
243 wxObjectPropertyWriter pw(cti,writercallback,this, md);
244
245 const wxClassInfo* pci = cti->GetClassInfo();
246 pci->CallOnAny( *valptr, &pw);
247 }
248 else
249 {
250 DoWriteSimpleType( *valptr );
251 }
252 }
253 DoEndWriteElement();
254 }
255 DoEndWriteProperty( pi );
256 }
257 }
258 else
259 {
260 const wxEventSourceTypeInfo* dti =
261 wx_dynamic_cast( const wxEventSourceTypeInfo* , pi->GetTypeInfo() );
262 if ( dti )
263 {
264 const wxObject* sink = NULL;
265 const wxHandlerInfo *handler = NULL;
266
267 const wxEvtHandler * evSource = wx_dynamic_cast(const wxEvtHandler *, obj);
268 if ( evSource )
269 {
270 FindConnectEntry( evSource, dti, sink, handler );
271 if ( writercallback->BeforeWriteDelegate( this, obj, ci, pi, sink, handler ) )
272 {
273 if ( sink != NULL && handler != NULL )
274 {
275 DoBeginWriteProperty( pi );
276 if ( IsObjectKnown( sink ) )
277 {
278 DoWriteDelegate( obj, ci, pi, sink, GetObjectID( sink ),
279 sink->GetClassInfo(), handler );
280 DoEndWriteProperty( pi );
281 }
282 else
283 {
284 wxLogError( wxT("Streaming delegates for not already ")
285 wxT("streamed objects not yet supported") );
286 }
287 }
288 }
289 }
290 else
291 {
292 wxLogError(_("Illegal Object Class (Non-wxEvtHandler) as Event Source") );
293 }
294 }
295 else
296 {
297 wxAny value;
298 pi->GetAccessor()->GetProperty(obj, value);
299
300 // avoid streaming out void objects
301 // TODO Verify
302 if( value.IsNull() )
303 return;
304
305 if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
306 {
307 const wxEnumTypeInfo *eti =
308 wx_dynamic_cast(const wxEnumTypeInfo*, pi->GetTypeInfo() );
309 if ( eti )
310 {
311 eti->ConvertFromLong( value.As<long >(), value );
312 }
313 else
314 {
315 wxLogError( _("Type must have enum - long conversion") );
316 }
317 }
318
319 // avoid streaming out default values
320 if ( pi->GetTypeInfo()->HasStringConverters() &&
321 !pi->GetDefaultValue().IsNull() ) // TODO Verify
322 {
323 if ( wxAnyGetAsString(value) == wxAnyGetAsString(pi->GetDefaultValue()) )
324 return;
325 }
326
327 // avoid streaming out null objects
328 const wxClassTypeInfo* cti =
329 wx_dynamic_cast( const wxClassTypeInfo* , pi->GetTypeInfo() );
330
331 if ( cti && cti->GetKind() == wxT_OBJECT_PTR && wxAnyGetAsObjectPtr(value) == NULL )
332 return;
333
334 if ( writercallback->BeforeWriteProperty( this, obj, pi, value ) )
335 {
336 DoBeginWriteProperty( pi );
337 if ( cti )
338 {
339 if ( cti->HasStringConverters() )
340 {
341 wxString stringValue;
342 cti->ConvertToString( value, stringValue );
343 wxAny convertedValue(stringValue);
344 DoWriteSimpleType( convertedValue );
345 }
346 else
347 {
348 wxStringToAnyHashMap md;
349 wxObjectPropertyWriter pw(cti,writercallback,this, md);
350
351 const wxClassInfo* pci = cti->GetClassInfo();
352 pci->CallOnAny(value, &pw);
353 }
354 }
355 else
356 {
357 DoWriteSimpleType( value );
358 }
359 DoEndWriteProperty( pi );
360 }
361 }
362 }
363 }
364
GetObjectID(const wxObject * obj)365 int wxObjectWriter::GetObjectID(const wxObject *obj)
366 {
367 if ( !IsObjectKnown( obj ) )
368 return wxInvalidObjectID;
369
370 return m_data->m_writtenObjects[obj];
371 }
372
IsObjectKnown(const wxObject * obj)373 bool wxObjectWriter::IsObjectKnown( const wxObject *obj )
374 {
375 return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end();
376 }
377
378
379 // ----------------------------------------------------------------------------
380 // wxObjectReader
381 // ----------------------------------------------------------------------------
382
383 struct wxObjectReader::wxObjectReaderInternal
384 {
385 map<int,wxClassInfo*> m_classInfos;
386 };
387
wxObjectReader()388 wxObjectReader::wxObjectReader()
389 {
390 m_data = new wxObjectReaderInternal;
391 }
392
~wxObjectReader()393 wxObjectReader::~wxObjectReader()
394 {
395 delete m_data;
396 }
397
GetObjectClassInfo(int objectID)398 wxClassInfo* wxObjectReader::GetObjectClassInfo(int objectID)
399 {
400 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
401 {
402 wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) );
403 return NULL;
404 }
405 if ( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() )
406 {
407 wxLogError( _("Unknown Object passed to GetObjectClassInfo" ) );
408 return NULL;
409 }
410 return m_data->m_classInfos[objectID];
411 }
412
SetObjectClassInfo(int objectID,wxClassInfo * classInfo)413 void wxObjectReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo )
414 {
415 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
416 {
417 wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) );
418 return;
419 }
420 if ( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() )
421 {
422 wxLogError( _("Already Registered Object passed to SetObjectClassInfo" ) );
423 return;
424 }
425 m_data->m_classInfos[objectID] = classInfo;
426 }
427
HasObjectClassInfo(int objectID)428 bool wxObjectReader::HasObjectClassInfo( int objectID )
429 {
430 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
431 {
432 wxLogError( _("Invalid or Null Object ID passed to HasObjectClassInfo" ) );
433 return false;
434 }
435 return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end();
436 }
437
438
439 // ----------------------------------------------------------------------------
440 // reading xml in
441 // ----------------------------------------------------------------------------
442
443 /*
444 Reading components has not to be extended for components
445 as properties are always sought by typeinfo over all levels
446 and create params are always toplevel class only
447 */
448
449
450 // ----------------------------------------------------------------------------
451 // wxObjectRuntimeReaderCallback - depersisting to memory
452 // ----------------------------------------------------------------------------
453
454 struct wxObjectRuntimeReaderCallback::wxObjectRuntimeReaderCallbackInternal
455 {
456 map<int,wxObject *> m_objects;
457
SetObjectwxObjectRuntimeReaderCallback::wxObjectRuntimeReaderCallbackInternal458 void SetObject(int objectID, wxObject *obj )
459 {
460 if ( m_objects.find(objectID) != m_objects.end() )
461 {
462 wxLogError( _("Passing a already registered object to SetObject") );
463 return ;
464 }
465 m_objects[objectID] = obj;
466 }
GetObjectwxObjectRuntimeReaderCallback::wxObjectRuntimeReaderCallbackInternal467 wxObject* GetObject( int objectID )
468 {
469 if ( objectID == wxNullObjectID )
470 return NULL;
471 if ( m_objects.find(objectID) == m_objects.end() )
472 {
473 wxLogError( _("Passing an unknown object to GetObject") );
474 return NULL;
475 }
476
477 return m_objects[objectID];
478 }
479 };
480
wxObjectRuntimeReaderCallback()481 wxObjectRuntimeReaderCallback::wxObjectRuntimeReaderCallback()
482 {
483 m_data = new wxObjectRuntimeReaderCallbackInternal();
484 }
485
~wxObjectRuntimeReaderCallback()486 wxObjectRuntimeReaderCallback::~wxObjectRuntimeReaderCallback()
487 {
488 delete m_data;
489 }
490
AllocateObject(int objectID,wxClassInfo * classInfo,wxStringToAnyHashMap & WXUNUSED (metadata))491 void wxObjectRuntimeReaderCallback::AllocateObject(int objectID, wxClassInfo *classInfo,
492 wxStringToAnyHashMap &WXUNUSED(metadata))
493 {
494 wxObject *O;
495 O = classInfo->CreateObject();
496 m_data->SetObject(objectID, O);
497 }
498
CreateObject(int objectID,const wxClassInfo * classInfo,int paramCount,wxAny * params,int * objectIdValues,const wxClassInfo ** objectClassInfos,wxStringToAnyHashMap & WXUNUSED (metadata))499 void wxObjectRuntimeReaderCallback::CreateObject(int objectID,
500 const wxClassInfo *classInfo,
501 int paramCount,
502 wxAny *params,
503 int *objectIdValues,
504 const wxClassInfo **objectClassInfos,
505 wxStringToAnyHashMap &WXUNUSED(metadata))
506 {
507 wxObject *o;
508 o = m_data->GetObject(objectID);
509 for ( int i = 0; i < paramCount; ++i )
510 {
511 if ( objectIdValues[i] != wxInvalidObjectID )
512 {
513 wxObject *o;
514 o = m_data->GetObject(objectIdValues[i]);
515 // if this is a dynamic object and we are asked for another class
516 // than wxDynamicObject we cast it down manually.
517 wxDynamicObject *dyno = wx_dynamic_cast( wxDynamicObject *, o);
518 if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
519 {
520 o = dyno->GetSuperClassInstance();
521 }
522 params[i] = objectClassInfos[i]->ObjectPtrToAny(o);
523 }
524 }
525 classInfo->Create(o, paramCount, params);
526 }
527
ConstructObject(int objectID,const wxClassInfo * classInfo,int paramCount,wxAny * params,int * objectIdValues,const wxClassInfo ** objectClassInfos,wxStringToAnyHashMap & WXUNUSED (metadata))528 void wxObjectRuntimeReaderCallback::ConstructObject(int objectID,
529 const wxClassInfo *classInfo,
530 int paramCount,
531 wxAny *params,
532 int *objectIdValues,
533 const wxClassInfo **objectClassInfos,
534 wxStringToAnyHashMap &WXUNUSED(metadata))
535 {
536 wxObject *o;
537 for ( int i = 0; i < paramCount; ++i )
538 {
539 if ( objectIdValues[i] != wxInvalidObjectID )
540 {
541 wxObject *o;
542 o = m_data->GetObject(objectIdValues[i]);
543 // if this is a dynamic object and we are asked for another class
544 // than wxDynamicObject we cast it down manually.
545 wxDynamicObject *dyno = wx_dynamic_cast( wxDynamicObject *, o);
546 if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
547 {
548 o = dyno->GetSuperClassInstance();
549 }
550 params[i] = objectClassInfos[i]->ObjectPtrToAny(o);
551 }
552 }
553 o = classInfo->ConstructObject(paramCount, params);
554 m_data->SetObject(objectID, o);
555 }
556
557
DestroyObject(int objectID,wxClassInfo * WXUNUSED (classInfo))558 void wxObjectRuntimeReaderCallback::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
559 {
560 wxObject *o;
561 o = m_data->GetObject(objectID);
562 delete o;
563 }
564
SetProperty(int objectID,const wxClassInfo * classInfo,const wxPropertyInfo * propertyInfo,const wxAny & value)565 void wxObjectRuntimeReaderCallback::SetProperty(int objectID,
566 const wxClassInfo *classInfo,
567 const wxPropertyInfo* propertyInfo,
568 const wxAny &value)
569 {
570 wxObject *o;
571 o = m_data->GetObject(objectID);
572 classInfo->SetProperty( o, propertyInfo->GetName().c_str(), value );
573 }
574
SetPropertyAsObject(int objectID,const wxClassInfo * classInfo,const wxPropertyInfo * propertyInfo,int valueObjectId)575 void wxObjectRuntimeReaderCallback::SetPropertyAsObject(int objectID,
576 const wxClassInfo *classInfo,
577 const wxPropertyInfo* propertyInfo,
578 int valueObjectId)
579 {
580 wxObject *o, *valo;
581 o = m_data->GetObject(objectID);
582 valo = m_data->GetObject(valueObjectId);
583 const wxClassInfo* valClassInfo =
584 (wx_dynamic_cast(const wxClassTypeInfo*,propertyInfo->GetTypeInfo()))->GetClassInfo();
585
586 // if this is a dynamic object and we are asked for another class
587 // than wxDynamicObject we cast it down manually.
588 wxDynamicObject *dynvalo = wx_dynamic_cast( wxDynamicObject *, valo);
589 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
590 {
591 valo = dynvalo->GetSuperClassInstance();
592 }
593
594 classInfo->SetProperty( o, propertyInfo->GetName().c_str(),
595 valClassInfo->ObjectPtrToAny(valo) );
596 }
597
SetConnect(int eventSourceObjectID,const wxClassInfo * WXUNUSED (eventSourceClassInfo),const wxPropertyInfo * delegateInfo,const wxClassInfo * WXUNUSED (eventSinkClassInfo),const wxHandlerInfo * handlerInfo,int eventSinkObjectID)598 void wxObjectRuntimeReaderCallback::SetConnect(int eventSourceObjectID,
599 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
600 const wxPropertyInfo *delegateInfo,
601 const wxClassInfo *WXUNUSED(eventSinkClassInfo),
602 const wxHandlerInfo* handlerInfo,
603 int eventSinkObjectID )
604 {
605 wxEvtHandler *ehsource =
606 wx_dynamic_cast( wxEvtHandler* , m_data->GetObject( eventSourceObjectID ) );
607 wxEvtHandler *ehsink =
608 wx_dynamic_cast( wxEvtHandler *,m_data->GetObject(eventSinkObjectID) );
609
610 if ( ehsource && ehsink )
611 {
612 const wxEventSourceTypeInfo *delegateTypeInfo =
613 wx_dynamic_cast(const wxEventSourceTypeInfo*,delegateInfo->GetTypeInfo());
614 if( delegateTypeInfo && delegateTypeInfo->GetLastEventType() == -1 )
615 {
616 ehsource->Connect( -1, delegateTypeInfo->GetEventType(),
617 handlerInfo->GetEventFunction(), NULL /*user data*/,
618 ehsink );
619 }
620 else
621 {
622 for ( wxEventType iter = delegateTypeInfo->GetEventType();
623 iter <= delegateTypeInfo->GetLastEventType(); ++iter )
624 {
625 ehsource->Connect( -1, iter,
626 handlerInfo->GetEventFunction(), NULL /*user data*/,
627 ehsink );
628 }
629 }
630 }
631 }
632
GetObject(int objectID)633 wxObject *wxObjectRuntimeReaderCallback::GetObject(int objectID)
634 {
635 return m_data->GetObject( objectID );
636 }
637
AddToPropertyCollection(int objectID,const wxClassInfo * classInfo,const wxPropertyInfo * propertyInfo,const wxAny & value)638 void wxObjectRuntimeReaderCallback::AddToPropertyCollection( int objectID,
639 const wxClassInfo *classInfo,
640 const wxPropertyInfo* propertyInfo,
641 const wxAny &value)
642 {
643 wxObject *o;
644 o = m_data->GetObject(objectID);
645 classInfo->AddToPropertyCollection( o, propertyInfo->GetName().c_str(), value );
646 }
647
AddToPropertyCollectionAsObject(int objectID,const wxClassInfo * classInfo,const wxPropertyInfo * propertyInfo,int valueObjectId)648 void wxObjectRuntimeReaderCallback::AddToPropertyCollectionAsObject(int objectID,
649 const wxClassInfo *classInfo,
650 const wxPropertyInfo* propertyInfo,
651 int valueObjectId)
652 {
653 wxObject *o, *valo;
654 o = m_data->GetObject(objectID);
655 valo = m_data->GetObject(valueObjectId);
656 const wxCollectionTypeInfo * collectionTypeInfo =
657 wx_dynamic_cast( const wxCollectionTypeInfo *, propertyInfo->GetTypeInfo() );
658 const wxClassInfo* valClassInfo =
659 (wx_dynamic_cast(const wxClassTypeInfo*,collectionTypeInfo->GetElementType()))->GetClassInfo();
660
661 // if this is a dynamic object and we are asked for another class
662 // than wxDynamicObject we cast it down manually.
663 wxDynamicObject *dynvalo = wx_dynamic_cast( wxDynamicObject *, valo);
664 if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) )
665 {
666 valo = dynvalo->GetSuperClassInstance();
667 }
668
669 classInfo->AddToPropertyCollection( o, propertyInfo->GetName().c_str(),
670 valClassInfo->ObjectPtrToAny(valo) );
671 }
672
673 #endif // wxUSE_EXTENDED_RTTI
674