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