]>
Commit | Line | Data |
---|---|---|
70e88103 SC |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: src/common/xtistrm.cpp | |
2abce515 | 3 | // Purpose: streaming runtime metadata information |
70e88103 | 4 | // Author: Stefan Csomor |
2abce515 | 5 | // Modified by: |
70e88103 SC |
6 | // Created: 27/07/03 |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 2003 Stefan Csomor | |
65571936 | 9 | // Licence: wxWindows licence |
70e88103 SC |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
70e88103 SC |
12 | // For compilers that support precompilation, includes "wx.h". |
13 | #include "wx/wxprec.h" | |
14 | ||
15 | #ifdef __BORLANDC__ | |
8e3f3880 | 16 | #pragma hdrstop |
70e88103 SC |
17 | #endif |
18 | ||
8e3f3880 WS |
19 | #if wxUSE_EXTENDED_RTTI |
20 | ||
d5da0ce7 WS |
21 | #include "wx/xtistrm.h" |
22 | ||
70e88103 | 23 | #ifndef WX_PRECOMP |
8e3f3880 WS |
24 | #include "wx/object.h" |
25 | #include "wx/hash.h" | |
d5da0ce7 | 26 | #include "wx/event.h" |
70e88103 SC |
27 | #endif |
28 | ||
70e88103 | 29 | #include "wx/tokenzr.h" |
70e88103 | 30 | #include "wx/txtstrm.h" |
8347b97a | 31 | |
ab6e4913 | 32 | #include "wx/beforestd.h" |
70e88103 SC |
33 | #include <map> |
34 | #include <vector> | |
35 | #include <string> | |
ab6e4913 | 36 | #include "wx/afterstd.h" |
70e88103 SC |
37 | |
38 | using namespace std ; | |
39 | ||
16776ad9 SC |
40 | struct wxWriter::wxWriterInternal |
41 | { | |
42 | map< const wxObject* , int > m_writtenObjects ; | |
43 | int m_nextId ; | |
44 | } ; | |
45 | ||
46 | wxWriter::wxWriter() | |
47 | { | |
48 | m_data = new wxWriterInternal ; | |
49 | m_data->m_nextId = 0 ; | |
50 | } | |
51 | ||
52 | wxWriter::~wxWriter() | |
53 | { | |
54 | delete m_data ; | |
55 | } | |
56 | ||
57 | struct wxWriter::wxWriterInternalPropertiesData | |
58 | { | |
cb73e600 | 59 | char nothing ; |
16776ad9 SC |
60 | } ; |
61 | ||
ab6e4913 SC |
62 | void wxWriter::ClearObjectContext() |
63 | { | |
64 | delete m_data ; | |
65 | m_data = new wxWriterInternal() ; | |
66 | m_data->m_nextId = 0 ; | |
67 | } | |
68 | ||
4f8ffae1 | 69 | void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , const wxString &name , wxxVariantArray &metadata ) |
16776ad9 | 70 | { |
ab6e4913 | 71 | DoBeginWriteTopLevelEntry( name ) ; |
4f8ffae1 | 72 | WriteObject( object , classInfo , persister , false , metadata) ; |
ab6e4913 SC |
73 | DoEndWriteTopLevelEntry( name ) ; |
74 | } | |
75 | ||
4f8ffae1 | 76 | void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , bool isEmbedded, wxxVariantArray &metadata ) |
ab6e4913 | 77 | { |
9c8046dd | 78 | if ( !classInfo->BeforeWriteObject( object , this , persister , metadata) ) |
c90b8250 SC |
79 | return ; |
80 | ||
4f8ffae1 | 81 | if ( persister->BeforeWriteObject( this , object , classInfo , metadata) ) |
16776ad9 | 82 | { |
ab6e4913 SC |
83 | if ( object == NULL ) |
84 | DoWriteNullObject() ; | |
85 | else if ( IsObjectKnown( object ) ) | |
86 | DoWriteRepeatedObject( GetObjectID(object) ) ; | |
2d51f067 SC |
87 | else |
88 | { | |
89 | int oid = m_data->m_nextId++ ; | |
ab6e4913 SC |
90 | if ( !isEmbedded ) |
91 | m_data->m_writtenObjects[object] = oid ; | |
92 | ||
2d51f067 SC |
93 | // in case this object is a wxDynamicObject we also have to insert is superclass |
94 | // instance with the same id, so that object relations are streamed out correctly | |
95 | const wxDynamicObject* dynobj = dynamic_cast<const wxDynamicObject *>( object ) ; | |
ab6e4913 | 96 | if ( !isEmbedded && dynobj ) |
2d51f067 SC |
97 | m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid ; |
98 | ||
4f8ffae1 | 99 | DoBeginWriteObject( object , classInfo , oid , metadata ) ; |
2d51f067 SC |
100 | wxWriterInternalPropertiesData data ; |
101 | WriteAllProperties( object , classInfo , persister , &data ) ; | |
ab6e4913 | 102 | DoEndWriteObject( object , classInfo , oid ) ; |
2d51f067 | 103 | } |
ab6e4913 | 104 | persister->AfterWriteObject( this ,object , classInfo ) ; |
16776ad9 SC |
105 | } |
106 | } | |
107 | ||
9c8046dd | 108 | void wxWriter::FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler) |
ab6e4913 SC |
109 | { |
110 | wxList *dynamicEvents = evSource->GetDynamicEventTable() ; | |
111 | ||
112 | if ( dynamicEvents ) | |
113 | { | |
114 | wxList::compatibility_iterator node = dynamicEvents->GetFirst(); | |
115 | while (node) | |
116 | { | |
117 | wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData(); | |
118 | ||
119 | // find the match | |
2abce515 | 120 | if ( entry->m_fn && |
9c8046dd SC |
121 | (dti->GetEventType() == entry->m_eventType) && |
122 | (entry->m_id == -1 ) && | |
123 | (entry->m_eventSink != NULL ) ) | |
ab6e4913 SC |
124 | { |
125 | sink = entry->m_eventSink ; | |
126 | const wxClassInfo* sinkClassInfo = sink->GetClassInfo() ; | |
127 | const wxHandlerInfo* sinkHandler = sinkClassInfo->GetFirstHandler() ; | |
128 | while ( sinkHandler ) | |
129 | { | |
130 | if ( sinkHandler->GetEventFunction() == entry->m_fn ) | |
131 | { | |
132 | handler = sinkHandler ; | |
133 | break ; | |
134 | } | |
135 | sinkHandler = sinkHandler->GetNext() ; | |
136 | } | |
137 | break ; | |
138 | } | |
139 | node = node->GetNext(); | |
140 | } | |
141 | } | |
142 | } | |
16776ad9 SC |
143 | void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data ) |
144 | { | |
cb73e600 SC |
145 | wxPropertyInfoMap map ; |
146 | ci->GetProperties( map ) ; | |
147 | for ( int i = 0 ; i < ci->GetCreateParamCount() ; ++i ) | |
16a45a23 | 148 | { |
cb73e600 SC |
149 | wxString name = ci->GetCreateParamName(i) ; |
150 | const wxPropertyInfo* prop = map.find(name)->second ; | |
8f2b1cfd SC |
151 | if ( prop ) |
152 | { | |
153 | WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ; | |
154 | } | |
155 | else | |
156 | { | |
157 | wxLogError( _("Create Parameter not found in declared RTTI Parameters") ) ; | |
158 | } | |
cb73e600 SC |
159 | map.erase( name ) ; |
160 | } | |
af498247 VZ |
161 | { // Extra block for broken compilers |
162 | for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter ) | |
cb73e600 | 163 | { |
af498247 VZ |
164 | const wxPropertyInfo* prop = iter->second ; |
165 | if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH ) | |
166 | { | |
167 | WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ; | |
168 | } | |
cb73e600 SC |
169 | } |
170 | } | |
af498247 VZ |
171 | { // Extra block for broken compilers |
172 | for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter ) | |
16a45a23 | 173 | { |
af498247 VZ |
174 | const wxPropertyInfo* prop = iter->second ; |
175 | if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) ) | |
176 | { | |
177 | WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ; | |
178 | } | |
16a45a23 SC |
179 | } |
180 | } | |
cb73e600 SC |
181 | } |
182 | ||
2abce515 | 183 | void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *WXUNUSED(data) ) |
cb73e600 | 184 | { |
9c8046dd SC |
185 | if ( pi->GetFlags() & wxPROP_DONT_STREAM ) |
186 | return ; | |
187 | ||
cb73e600 SC |
188 | // make sure that we are picking the correct object for accessing the property |
189 | const wxDynamicObject* dynobj = dynamic_cast< const wxDynamicObject* > (obj ) ; | |
190 | if ( dynobj && (dynamic_cast<const wxDynamicClassInfo*>(ci) == NULL) ) | |
191 | obj = dynobj->GetSuperClassInstance() ; | |
16a45a23 | 192 | |
cb73e600 | 193 | if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION ) |
16776ad9 | 194 | { |
cb73e600 SC |
195 | wxxVariantArray data ; |
196 | pi->GetAccessor()->GetPropertyCollection(obj, data) ; | |
197 | const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ; | |
198 | for ( size_t i = 0 ; i < data.GetCount() ; ++i ) | |
16776ad9 | 199 | { |
ed45345e SC |
200 | if ( i == 0 ) |
201 | DoBeginWriteProperty( pi ) ; | |
202 | ||
cb73e600 SC |
203 | DoBeginWriteElement() ; |
204 | wxxVariant value = data[i] ; | |
8805dbab | 205 | if ( persister->BeforeWriteProperty( this , obj, pi , value ) ) |
16776ad9 | 206 | { |
cb73e600 SC |
207 | const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ; |
208 | if ( cti ) | |
16776ad9 | 209 | { |
cb73e600 SC |
210 | const wxClassInfo* pci = cti->GetClassInfo() ; |
211 | wxObject *vobj = pci->VariantToInstance( value ) ; | |
212 | wxxVariantArray md ; | |
213 | WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md ) ; | |
16776ad9 | 214 | } |
cb73e600 | 215 | else |
16776ad9 | 216 | { |
2abce515 | 217 | DoWriteSimpleType( value ) ; |
cb73e600 SC |
218 | } |
219 | } | |
220 | DoEndWriteElement() ; | |
ed45345e SC |
221 | if ( i == data.GetCount() - 1 ) |
222 | DoEndWriteProperty( pi ) ; | |
223 | } | |
224 | } | |
cb73e600 SC |
225 | else |
226 | { | |
227 | const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ; | |
228 | if ( dti ) | |
229 | { | |
230 | const wxObject* sink = NULL ; | |
231 | const wxHandlerInfo *handler = NULL ; | |
ab6e4913 | 232 | |
9c8046dd | 233 | const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ; |
8f2b1cfd | 234 | if ( evSource ) |
cb73e600 | 235 | { |
8f2b1cfd SC |
236 | FindConnectEntry( evSource , dti , sink , handler ) ; |
237 | if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) ) | |
cb73e600 | 238 | { |
8f2b1cfd SC |
239 | if ( sink != NULL && handler != NULL ) |
240 | { | |
241 | DoBeginWriteProperty( pi ) ; | |
242 | if ( IsObjectKnown( sink ) ) | |
243 | { | |
244 | DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ; | |
245 | DoEndWriteProperty( pi ) ; | |
246 | } | |
247 | else | |
248 | { | |
249 | wxLogError( _("Streaming delegates for not already streamed objects not yet supported") ) ; | |
250 | } | |
251 | } | |
16776ad9 | 252 | } |
cb73e600 | 253 | } |
8f2b1cfd SC |
254 | else |
255 | { | |
256 | wxLogError(_("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ; | |
257 | } | |
cb73e600 SC |
258 | } |
259 | else | |
260 | { | |
261 | wxxVariant value ; | |
262 | pi->GetAccessor()->GetProperty(obj, value) ; | |
ed45345e SC |
263 | |
264 | // avoid streaming out void objects | |
265 | if( value.IsEmpty() ) | |
266 | return ; | |
267 | ||
268 | if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG ) | |
269 | { | |
270 | const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ; | |
8f2b1cfd SC |
271 | if ( eti ) |
272 | { | |
2c4c3987 | 273 | eti->ConvertFromLong( value.wxTEMPLATED_MEMBER_CALL(Get , long) , value ) ; |
8f2b1cfd SC |
274 | } |
275 | else | |
276 | { | |
277 | wxLogError( _("Type must have enum - long conversion") ) ; | |
278 | } | |
ed45345e SC |
279 | } |
280 | ||
281 | // avoid streaming out default values | |
282 | if ( pi->GetTypeInfo()->HasStringConverters() && !pi->GetDefaultValue().IsEmpty() ) | |
283 | { | |
284 | if ( value.GetAsString() == pi->GetDefaultValue().GetAsString() ) | |
285 | return ; | |
286 | } | |
cab1a605 | 287 | |
ed45345e SC |
288 | // avoid streaming out null objects |
289 | const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ; | |
290 | ||
291 | if ( cti && value.GetAsObject() == NULL ) | |
292 | return ; | |
293 | ||
8805dbab | 294 | if ( persister->BeforeWriteProperty( this , obj, pi , value ) ) |
cb73e600 | 295 | { |
ed45345e | 296 | DoBeginWriteProperty( pi ) ; |
cb73e600 | 297 | if ( cti ) |
16776ad9 | 298 | { |
cb73e600 SC |
299 | const wxClassInfo* pci = cti->GetClassInfo() ; |
300 | wxObject *vobj = pci->VariantToInstance( value ) ; | |
ed45345e SC |
301 | if ( vobj && pi->GetTypeInfo()->HasStringConverters() ) |
302 | { | |
303 | wxString stringValue ; | |
304 | cti->ConvertToString( value , stringValue ) ; | |
305 | wxxVariant convertedValue(stringValue) ; | |
306 | DoWriteSimpleType( convertedValue ) ; | |
307 | } | |
308 | else | |
309 | { | |
310 | wxxVariantArray md ; | |
311 | WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ; | |
312 | } | |
cb73e600 SC |
313 | } |
314 | else | |
2abce515 | 315 | { |
cb73e600 | 316 | DoWriteSimpleType( value ) ; |
16776ad9 | 317 | } |
ed45345e | 318 | DoEndWriteProperty( pi ) ; |
16776ad9 SC |
319 | } |
320 | } | |
16776ad9 | 321 | } |
4f8ffae1 | 322 | } |
70e88103 | 323 | |
2abce515 | 324 | int wxWriter::GetObjectID(const wxObject *obj) |
16776ad9 SC |
325 | { |
326 | if ( !IsObjectKnown( obj ) ) | |
327 | return wxInvalidObjectID ; | |
328 | ||
329 | return m_data->m_writtenObjects[obj] ; | |
330 | } | |
331 | ||
2abce515 | 332 | bool wxWriter::IsObjectKnown( const wxObject *obj ) |
16776ad9 SC |
333 | { |
334 | return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ; | |
335 | } | |
336 | ||
70e88103 SC |
337 | |
338 | // ---------------------------------------------------------------------------- | |
2abce515 | 339 | // reading objects in |
70e88103 SC |
340 | // ---------------------------------------------------------------------------- |
341 | ||
70e88103 SC |
342 | struct wxReader::wxReaderInternal |
343 | { | |
45212047 | 344 | map<int,wxClassInfo*> m_classInfos; |
70e88103 SC |
345 | }; |
346 | ||
2abce515 | 347 | wxReader::wxReader() |
70e88103 | 348 | { |
45212047 | 349 | m_data = new wxReaderInternal; |
70e88103 SC |
350 | } |
351 | ||
352 | wxReader::~wxReader() | |
353 | { | |
45212047 | 354 | delete m_data; |
70e88103 SC |
355 | } |
356 | ||
45212047 | 357 | wxClassInfo* wxReader::GetObjectClassInfo(int objectID) |
70e88103 | 358 | { |
8f2b1cfd SC |
359 | if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID ) |
360 | { | |
361 | wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) ) ; | |
362 | return NULL ; | |
363 | } | |
364 | if ( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() ) | |
365 | { | |
366 | wxLogError( _("Unknown Object passed to GetObjectClassInfo" ) ) ; | |
367 | return NULL ; | |
368 | } | |
45212047 | 369 | return m_data->m_classInfos[objectID] ; |
70e88103 SC |
370 | } |
371 | ||
45212047 | 372 | void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo ) |
70e88103 | 373 | { |
8f2b1cfd SC |
374 | if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID ) |
375 | { | |
376 | wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) ) ; | |
377 | return ; | |
378 | } | |
379 | if ( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ) | |
380 | { | |
381 | wxLogError( _("Already Registered Object passed to SetObjectClassInfo" ) ) ; | |
382 | return ; | |
383 | } | |
16776ad9 | 384 | m_data->m_classInfos[objectID] = classInfo ; |
70e88103 SC |
385 | } |
386 | ||
2abce515 | 387 | bool wxReader::HasObjectClassInfo( int objectID ) |
70e88103 | 388 | { |
8f2b1cfd SC |
389 | if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID ) |
390 | { | |
391 | wxLogError( _("Invalid or Null Object ID passed to HasObjectClassInfo" ) ) ; | |
afc89ff4 | 392 | return false ; |
8f2b1cfd | 393 | } |
16776ad9 | 394 | return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ; |
70e88103 SC |
395 | } |
396 | ||
70e88103 | 397 | |
45212047 | 398 | // ---------------------------------------------------------------------------- |
2abce515 | 399 | // reading xml in |
45212047 | 400 | // ---------------------------------------------------------------------------- |
70e88103 | 401 | |
2abce515 | 402 | /* |
16776ad9 SC |
403 | Reading components has not to be extended for components |
404 | as properties are always sought by typeinfo over all levels | |
405 | and create params are always toplevel class only | |
70e88103 SC |
406 | */ |
407 | ||
70e88103 SC |
408 | |
409 | // ---------------------------------------------------------------------------- | |
2abce515 | 410 | // depersisting to memory |
70e88103 SC |
411 | // ---------------------------------------------------------------------------- |
412 | ||
45212047 | 413 | struct wxRuntimeDepersister::wxRuntimeDepersisterInternal |
70e88103 | 414 | { |
45212047 SC |
415 | map<int,wxObject *> m_objects; |
416 | ||
16776ad9 SC |
417 | void SetObject(int objectID, wxObject *obj ) |
418 | { | |
8f2b1cfd SC |
419 | if ( m_objects.find(objectID) != m_objects.end() ) |
420 | { | |
421 | wxLogError( _("Passing a already registered object to SetObject") ) ; | |
422 | return ; | |
423 | } | |
16776ad9 SC |
424 | m_objects[objectID] = obj ; |
425 | } | |
426 | wxObject* GetObject( int objectID ) | |
427 | { | |
428 | if ( objectID == wxNullObjectID ) | |
429 | return NULL ; | |
8f2b1cfd SC |
430 | if ( m_objects.find(objectID) == m_objects.end() ) |
431 | { | |
90523bdb | 432 | wxLogError( _("Passing an unknown object to GetObject") ) ; |
8f2b1cfd SC |
433 | return NULL ; |
434 | } | |
16776ad9 | 435 | |
16776ad9 SC |
436 | return m_objects[objectID] ; |
437 | } | |
45212047 SC |
438 | } ; |
439 | ||
440 | wxRuntimeDepersister::wxRuntimeDepersister() | |
441 | { | |
16776ad9 | 442 | m_data = new wxRuntimeDepersisterInternal() ; |
70e88103 SC |
443 | } |
444 | ||
45212047 | 445 | wxRuntimeDepersister::~wxRuntimeDepersister() |
70e88103 | 446 | { |
16776ad9 | 447 | delete m_data ; |
70e88103 SC |
448 | } |
449 | ||
4f8ffae1 | 450 | void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo , |
9c8046dd | 451 | wxxVariantArray &WXUNUSED(metadata)) |
70e88103 SC |
452 | { |
453 | wxObject *O; | |
45212047 SC |
454 | O = classInfo->CreateObject(); |
455 | m_data->SetObject(objectID, O); | |
456 | } | |
457 | ||
458 | void wxRuntimeDepersister::CreateObject(int objectID, | |
16776ad9 SC |
459 | const wxClassInfo *classInfo, |
460 | int paramCount, | |
461 | wxxVariant *params, | |
462 | int *objectIdValues, | |
4f8ffae1 | 463 | const wxClassInfo **objectClassInfos , |
9c8046dd | 464 | wxxVariantArray &WXUNUSED(metadata)) |
45212047 SC |
465 | { |
466 | wxObject *o; | |
467 | o = m_data->GetObject(objectID); | |
16776ad9 SC |
468 | for ( int i = 0 ; i < paramCount ; ++i ) |
469 | { | |
470 | if ( objectIdValues[i] != wxInvalidObjectID ) | |
471 | { | |
472 | wxObject *o; | |
473 | o = m_data->GetObject(objectIdValues[i]); | |
2d51f067 SC |
474 | // if this is a dynamic object and we are asked for another class |
475 | // than wxDynamicObject we cast it down manually. | |
476 | wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ; | |
477 | if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) ) | |
478 | { | |
479 | o = dyno->GetSuperClassInstance() ; | |
480 | } | |
16776ad9 SC |
481 | params[i] = objectClassInfos[i]->InstanceToVariant(o) ; |
482 | } | |
483 | } | |
45212047 SC |
484 | classInfo->Create(o, paramCount, params); |
485 | } | |
486 | ||
ed45345e SC |
487 | void wxRuntimeDepersister::ConstructObject(int objectID, |
488 | const wxClassInfo *classInfo, | |
489 | int paramCount, | |
490 | wxxVariant *params, | |
491 | int *objectIdValues, | |
492 | const wxClassInfo **objectClassInfos , | |
493 | wxxVariantArray &WXUNUSED(metadata)) | |
494 | { | |
495 | wxObject *o; | |
496 | for ( int i = 0 ; i < paramCount ; ++i ) | |
497 | { | |
498 | if ( objectIdValues[i] != wxInvalidObjectID ) | |
499 | { | |
500 | wxObject *o; | |
501 | o = m_data->GetObject(objectIdValues[i]); | |
502 | // if this is a dynamic object and we are asked for another class | |
503 | // than wxDynamicObject we cast it down manually. | |
504 | wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ; | |
505 | if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) ) | |
506 | { | |
507 | o = dyno->GetSuperClassInstance() ; | |
508 | } | |
509 | params[i] = objectClassInfos[i]->InstanceToVariant(o) ; | |
510 | } | |
511 | } | |
512 | o = classInfo->ConstructObject(paramCount, params); | |
513 | m_data->SetObject(objectID, o); | |
514 | } | |
515 | ||
516 | ||
2abce515 | 517 | void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo)) |
45212047 SC |
518 | { |
519 | wxObject *o; | |
520 | o = m_data->GetObject(objectID); | |
16776ad9 | 521 | delete o ; |
70e88103 SC |
522 | } |
523 | ||
45212047 | 524 | void wxRuntimeDepersister::SetProperty(int objectID, |
2d51f067 | 525 | const wxClassInfo *classInfo, |
16776ad9 SC |
526 | const wxPropertyInfo* propertyInfo, |
527 | const wxxVariant &value) | |
70e88103 | 528 | { |
45212047 SC |
529 | wxObject *o; |
530 | o = m_data->GetObject(objectID); | |
2d51f067 | 531 | classInfo->SetProperty( o , propertyInfo->GetName() , value ) ; |
45212047 SC |
532 | } |
533 | ||
534 | void wxRuntimeDepersister::SetPropertyAsObject(int objectID, | |
2d51f067 | 535 | const wxClassInfo *classInfo, |
16776ad9 SC |
536 | const wxPropertyInfo* propertyInfo, |
537 | int valueObjectId) | |
45212047 SC |
538 | { |
539 | wxObject *o, *valo; | |
540 | o = m_data->GetObject(objectID); | |
541 | valo = m_data->GetObject(valueObjectId); | |
2d51f067 SC |
542 | const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(propertyInfo->GetTypeInfo()))->GetClassInfo() ; |
543 | // if this is a dynamic object and we are asked for another class | |
544 | // than wxDynamicObject we cast it down manually. | |
545 | wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ; | |
546 | if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) ) | |
547 | { | |
548 | valo = dynvalo->GetSuperClassInstance() ; | |
549 | } | |
550 | ||
551 | classInfo->SetProperty( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ; | |
45212047 SC |
552 | } |
553 | ||
554 | void wxRuntimeDepersister::SetConnect(int eventSourceObjectID, | |
16776ad9 | 555 | const wxClassInfo *WXUNUSED(eventSourceClassInfo), |
8805dbab | 556 | const wxPropertyInfo *delegateInfo , |
16776ad9 SC |
557 | const wxClassInfo *WXUNUSED(eventSinkClassInfo) , |
558 | const wxHandlerInfo* handlerInfo , | |
559 | int eventSinkObjectID ) | |
45212047 | 560 | { |
9c8046dd | 561 | wxEvtHandler *ehsource = dynamic_cast< wxEvtHandler* >( m_data->GetObject( eventSourceObjectID ) ) ; |
16776ad9 | 562 | wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ; |
70e88103 | 563 | |
16776ad9 SC |
564 | if ( ehsource && ehsink ) |
565 | { | |
8805dbab SC |
566 | const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo()); |
567 | if( delegateTypeInfo && delegateTypeInfo->GetLastEventType() == -1 ) | |
1d73f416 | 568 | { |
8805dbab | 569 | ehsource->Connect( -1 , delegateTypeInfo->GetEventType() , |
1d73f416 SC |
570 | handlerInfo->GetEventFunction() , NULL /*user data*/ , |
571 | ehsink ) ; | |
572 | } | |
573 | else | |
574 | { | |
8805dbab | 575 | for ( wxEventType iter = delegateTypeInfo->GetEventType() ; iter <= delegateTypeInfo->GetLastEventType() ; ++iter ) |
1d73f416 SC |
576 | { |
577 | ehsource->Connect( -1 , iter , | |
578 | handlerInfo->GetEventFunction() , NULL /*user data*/ , | |
579 | ehsink ) ; | |
580 | } | |
cab1a605 | 581 | } |
16776ad9 | 582 | } |
70e88103 SC |
583 | } |
584 | ||
45212047 SC |
585 | wxObject *wxRuntimeDepersister::GetObject(int objectID) |
586 | { | |
16776ad9 | 587 | return m_data->GetObject( objectID ) ; |
45212047 SC |
588 | } |
589 | ||
16a45a23 SC |
590 | // adds an element to a property collection |
591 | void wxRuntimeDepersister::AddToPropertyCollection( int objectID , | |
4f8ffae1 SC |
592 | const wxClassInfo *classInfo, |
593 | const wxPropertyInfo* propertyInfo , | |
2abce515 | 594 | const wxxVariant &value) |
16a45a23 SC |
595 | { |
596 | wxObject *o; | |
597 | o = m_data->GetObject(objectID); | |
598 | classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , value ) ; | |
599 | } | |
600 | ||
601 | // sets the corresponding property (value is an object) | |
602 | void wxRuntimeDepersister::AddToPropertyCollectionAsObject(int objectID, | |
4f8ffae1 SC |
603 | const wxClassInfo *classInfo, |
604 | const wxPropertyInfo* propertyInfo , | |
2abce515 | 605 | int valueObjectId) |
16a45a23 SC |
606 | { |
607 | wxObject *o, *valo; | |
608 | o = m_data->GetObject(objectID); | |
609 | valo = m_data->GetObject(valueObjectId); | |
610 | const wxCollectionTypeInfo * collectionTypeInfo = dynamic_cast< const wxCollectionTypeInfo * >(propertyInfo->GetTypeInfo() ) ; | |
611 | const wxClassInfo* valClassInfo = (dynamic_cast<const wxClassTypeInfo*>(collectionTypeInfo->GetElementType()))->GetClassInfo() ; | |
612 | // if this is a dynamic object and we are asked for another class | |
613 | // than wxDynamicObject we cast it down manually. | |
614 | wxDynamicObject *dynvalo = dynamic_cast< wxDynamicObject * > (valo) ; | |
615 | if ( dynvalo!=NULL && (valClassInfo != dynvalo->GetClassInfo()) ) | |
616 | { | |
617 | valo = dynvalo->GetSuperClassInstance() ; | |
618 | } | |
619 | ||
620 | classInfo->AddToPropertyCollection( o , propertyInfo->GetName() , valClassInfo->InstanceToVariant(valo) ) ; | |
621 | } | |
45212047 | 622 | |
70e88103 | 623 | // ---------------------------------------------------------------------------- |
2abce515 | 624 | // depersisting to code |
70e88103 SC |
625 | // ---------------------------------------------------------------------------- |
626 | ||
45212047 SC |
627 | struct wxCodeDepersister::wxCodeDepersisterInternal |
628 | { | |
67b283a9 JS |
629 | #if wxUSE_UNICODE |
630 | map<int,wstring> m_objectNames ; | |
631 | #else | |
45212047 | 632 | map<int,string> m_objectNames ; |
67b283a9 | 633 | #endif |
45212047 | 634 | |
16776ad9 SC |
635 | void SetObjectName(int objectID, const wxString &name ) |
636 | { | |
8f2b1cfd SC |
637 | if ( m_objectNames.find(objectID) != m_objectNames.end() ) |
638 | { | |
639 | wxLogError( _("Passing a already registered object to SetObjectName") ) ; | |
640 | return ; | |
641 | } | |
67b283a9 | 642 | m_objectNames[objectID] = (const wxChar *)name; |
16776ad9 | 643 | } |
8f2b1cfd | 644 | |
16776ad9 SC |
645 | wxString GetObjectName( int objectID ) |
646 | { | |
647 | if ( objectID == wxNullObjectID ) | |
67b283a9 | 648 | return wxT("NULL") ; |
16776ad9 | 649 | |
8f2b1cfd SC |
650 | if ( m_objectNames.find(objectID) == m_objectNames.end() ) |
651 | { | |
652 | wxLogError( _("Passing an unkown object to GetObject") ) ; | |
653 | return wxEmptyString ; | |
654 | } | |
16776ad9 SC |
655 | return wxString( m_objectNames[objectID].c_str() ) ; |
656 | } | |
45212047 | 657 | } ; |
70e88103 | 658 | |
2abce515 | 659 | wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out) |
16776ad9 | 660 | : m_fp(out) |
70e88103 | 661 | { |
16776ad9 | 662 | m_data = new wxCodeDepersisterInternal ; |
45212047 SC |
663 | } |
664 | ||
665 | wxCodeDepersister::~wxCodeDepersister() | |
666 | { | |
16776ad9 | 667 | delete m_data ; |
45212047 SC |
668 | } |
669 | ||
4f8ffae1 | 670 | void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo , |
9c8046dd | 671 | wxxVariantArray &WXUNUSED(metadata)) |
45212047 | 672 | { |
67b283a9 JS |
673 | wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ; |
674 | m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s;\n"), | |
16776ad9 | 675 | classInfo->GetClassName(), |
2abce515 | 676 | objectName.c_str(), |
16776ad9 SC |
677 | classInfo->GetClassName()) ); |
678 | m_data->SetObjectName( objectID , objectName ) ; | |
45212047 SC |
679 | } |
680 | ||
2abce515 | 681 | void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo)) |
45212047 | 682 | { |
67b283a9 | 683 | m_fp->WriteString( wxString::Format( wxT("\tdelete %s;\n"), |
2abce515 | 684 | m_data->GetObjectName( objectID).c_str() ) ); |
45212047 SC |
685 | } |
686 | ||
687 | wxString wxCodeDepersister::ValueAsCode( const wxxVariant ¶m ) | |
688 | { | |
16776ad9 SC |
689 | wxString value ; |
690 | const wxTypeInfo* type = param.GetTypeInfo() ; | |
691 | if ( type->GetKind() == wxT_CUSTOM ) | |
692 | { | |
693 | const wxCustomTypeInfo* cti = dynamic_cast<const wxCustomTypeInfo*>(type) ; | |
8f2b1cfd SC |
694 | if ( cti ) |
695 | { | |
696 | value.Printf( wxT("%s(%s)"), cti->GetTypeName().c_str(),param.GetAsString().c_str() ); | |
697 | } | |
698 | else | |
699 | { | |
700 | wxLogError ( _("Internal error, illegal wxCustomTypeInfo") ) ; | |
701 | } | |
16776ad9 SC |
702 | } |
703 | else if ( type->GetKind() == wxT_STRING ) | |
704 | { | |
67b283a9 | 705 | value.Printf( wxT("\"%s\""),param.GetAsString().c_str() ); |
16776ad9 SC |
706 | } |
707 | else | |
708 | { | |
67b283a9 | 709 | value.Printf( wxT("%s"), param.GetAsString().c_str() ); |
16776ad9 SC |
710 | } |
711 | return value ; | |
70e88103 SC |
712 | } |
713 | ||
45212047 | 714 | void wxCodeDepersister::CreateObject(int objectID, |
16776ad9 SC |
715 | const wxClassInfo *WXUNUSED(classInfo), |
716 | int paramCount, | |
717 | wxxVariant *params, | |
718 | int *objectIDValues, | |
4f8ffae1 | 719 | const wxClassInfo **WXUNUSED(objectClassInfos) , |
9c8046dd | 720 | wxxVariantArray &WXUNUSED(metadata) |
16776ad9 | 721 | ) |
70e88103 SC |
722 | { |
723 | int i; | |
67b283a9 | 724 | m_fp->WriteString( wxString::Format( wxT("\t%s->Create("), m_data->GetObjectName(objectID).c_str() ) ); |
45212047 | 725 | for (i = 0; i < paramCount; i++) |
70e88103 | 726 | { |
16776ad9 | 727 | if ( objectIDValues[i] != wxInvalidObjectID ) |
67b283a9 | 728 | m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) ); |
16776ad9 SC |
729 | else |
730 | { | |
67b283a9 | 731 | m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) ); |
16776ad9 SC |
732 | } |
733 | if (i < paramCount - 1) | |
67b283a9 | 734 | m_fp->WriteString( wxT(", ")); |
70e88103 | 735 | } |
67b283a9 | 736 | m_fp->WriteString( wxT(");\n") ); |
70e88103 SC |
737 | } |
738 | ||
ed45345e SC |
739 | void wxCodeDepersister::ConstructObject(int objectID, |
740 | const wxClassInfo *classInfo, | |
741 | int paramCount, | |
742 | wxxVariant *params, | |
743 | int *objectIDValues, | |
744 | const wxClassInfo **WXUNUSED(objectClassInfos) , | |
745 | wxxVariantArray &WXUNUSED(metadata) | |
746 | ) | |
747 | { | |
67b283a9 JS |
748 | wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ; |
749 | m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s("), | |
ed45345e SC |
750 | classInfo->GetClassName(), |
751 | objectName.c_str(), | |
752 | classInfo->GetClassName()) ); | |
753 | m_data->SetObjectName( objectID , objectName ) ; | |
754 | ||
755 | int i; | |
756 | for (i = 0; i < paramCount; i++) | |
757 | { | |
758 | if ( objectIDValues[i] != wxInvalidObjectID ) | |
67b283a9 | 759 | m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) ); |
ed45345e SC |
760 | else |
761 | { | |
67b283a9 | 762 | m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) ); |
ed45345e SC |
763 | } |
764 | if (i < paramCount - 1) | |
67b283a9 | 765 | m_fp->WriteString( wxT(", ") ); |
ed45345e | 766 | } |
67b283a9 | 767 | m_fp->WriteString( wxT(");\n") ); |
ed45345e SC |
768 | } |
769 | ||
45212047 | 770 | void wxCodeDepersister::SetProperty(int objectID, |
16776ad9 SC |
771 | const wxClassInfo *WXUNUSED(classInfo), |
772 | const wxPropertyInfo* propertyInfo, | |
773 | const wxxVariant &value) | |
70e88103 | 774 | { |
67b283a9 | 775 | m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"), |
2abce515 SC |
776 | m_data->GetObjectName(objectID).c_str(), |
777 | propertyInfo->GetAccessor()->GetSetterName().c_str(), | |
778 | ValueAsCode(value).c_str()) ); | |
45212047 SC |
779 | } |
780 | ||
781 | void wxCodeDepersister::SetPropertyAsObject(int objectID, | |
16776ad9 SC |
782 | const wxClassInfo *WXUNUSED(classInfo), |
783 | const wxPropertyInfo* propertyInfo, | |
784 | int valueObjectId) | |
785 | { | |
786 | if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT ) | |
67b283a9 | 787 | m_fp->WriteString( wxString::Format( wxT("\t%s->%s(*%s);\n"), |
2abce515 SC |
788 | m_data->GetObjectName(objectID).c_str(), |
789 | propertyInfo->GetAccessor()->GetSetterName().c_str(), | |
790 | m_data->GetObjectName( valueObjectId).c_str() ) ); | |
16776ad9 | 791 | else |
67b283a9 | 792 | m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"), |
2abce515 SC |
793 | m_data->GetObjectName(objectID).c_str(), |
794 | propertyInfo->GetAccessor()->GetSetterName().c_str(), | |
795 | m_data->GetObjectName( valueObjectId).c_str() ) ); | |
70e88103 SC |
796 | } |
797 | ||
16a45a23 | 798 | void wxCodeDepersister::AddToPropertyCollection( int objectID , |
9c8046dd | 799 | const wxClassInfo *WXUNUSED(classInfo), |
4f8ffae1 | 800 | const wxPropertyInfo* propertyInfo , |
2abce515 | 801 | const wxxVariant &value) |
16a45a23 | 802 | { |
67b283a9 | 803 | m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"), |
2abce515 SC |
804 | m_data->GetObjectName(objectID).c_str(), |
805 | propertyInfo->GetAccessor()->GetAdderName().c_str(), | |
806 | ValueAsCode(value).c_str()) ); | |
16a45a23 SC |
807 | } |
808 | ||
809 | // sets the corresponding property (value is an object) | |
9c8046dd SC |
810 | void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID), |
811 | const wxClassInfo *WXUNUSED(classInfo), | |
812 | const wxPropertyInfo* WXUNUSED(propertyInfo) , | |
2abce515 | 813 | int WXUNUSED(valueObjectId)) |
16a45a23 SC |
814 | { |
815 | // TODO | |
816 | } | |
817 | ||
45212047 | 818 | void wxCodeDepersister::SetConnect(int eventSourceObjectID, |
16776ad9 | 819 | const wxClassInfo *WXUNUSED(eventSourceClassInfo), |
8805dbab | 820 | const wxPropertyInfo *delegateInfo , |
16776ad9 SC |
821 | const wxClassInfo *eventSinkClassInfo , |
822 | const wxHandlerInfo* handlerInfo , | |
823 | int eventSinkObjectID ) | |
824 | { | |
825 | wxString ehsource = m_data->GetObjectName( eventSourceObjectID ) ; | |
826 | wxString ehsink = m_data->GetObjectName(eventSinkObjectID) ; | |
827 | wxString ehsinkClass = eventSinkClassInfo->GetClassName() ; | |
8805dbab | 828 | const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo()); |
8f2b1cfd SC |
829 | if ( delegateTypeInfo ) |
830 | { | |
831 | int eventType = delegateTypeInfo->GetEventType() ; | |
832 | wxString handlerName = handlerInfo->GetName() ; | |
16776ad9 | 833 | |
8f2b1cfd SC |
834 | m_fp->WriteString( wxString::Format( wxT("\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;") , |
835 | ehsource.c_str() , ehsource.c_str() , eventType , ehsinkClass.c_str() , handlerName.c_str() , ehsink.c_str() ) ); | |
836 | } | |
837 | else | |
838 | { | |
839 | wxLogError(_("delegate has no type info")); | |
840 | } | |
70e88103 SC |
841 | } |
842 | ||
7ec69821 | 843 | #include "wx/arrimpl.cpp" |
ab6e4913 SC |
844 | |
845 | WX_DEFINE_OBJARRAY(wxxVariantArray); | |
846 | ||
8e3f3880 | 847 | #endif // wxUSE_EXTENDED_RTTI |