1///////////////////////////////////////////////////////////////////////////// 2// Name: src/common/xtistrm.cpp 3// Purpose: streaming runtime metadata information 4// Author: Stefan Csomor 5// Modified by: 6// Created: 27/07/03 7// RCS-ID: $Id: xtistrm.cpp 38939 2006-04-27 12:47:14Z ABX $ 8// Copyright: (c) 2003 Stefan Csomor 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __BORLANDC__ 16 #pragma hdrstop 17#endif 18 19#if wxUSE_EXTENDED_RTTI 20 21#include "wx/xtistrm.h" 22 23#ifndef WX_PRECOMP 24 #include "wx/object.h" 25 #include "wx/hash.h" 26 #include "wx/event.h" 27#endif 28 29#include "wx/tokenzr.h" 30#include "wx/txtstrm.h" 31 32#include "wx/beforestd.h" 33#include <map> 34#include <vector> 35#include <string> 36#include "wx/afterstd.h" 37 38using namespace std ; 39 40struct wxWriter::wxWriterInternal 41{ 42 map< const wxObject* , int > m_writtenObjects ; 43 int m_nextId ; 44} ; 45 46wxWriter::wxWriter() 47{ 48 m_data = new wxWriterInternal ; 49 m_data->m_nextId = 0 ; 50} 51 52wxWriter::~wxWriter() 53{ 54 delete m_data ; 55} 56 57struct wxWriter::wxWriterInternalPropertiesData 58{ 59 char nothing ; 60} ; 61 62void wxWriter::ClearObjectContext() 63{ 64 delete m_data ; 65 m_data = new wxWriterInternal() ; 66 m_data->m_nextId = 0 ; 67} 68 69void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , const wxString &name , wxxVariantArray &metadata ) 70{ 71 DoBeginWriteTopLevelEntry( name ) ; 72 WriteObject( object , classInfo , persister , false , metadata) ; 73 DoEndWriteTopLevelEntry( name ) ; 74} 75 76void wxWriter::WriteObject(const wxObject *object, const wxClassInfo *classInfo , wxPersister *persister , bool isEmbedded, wxxVariantArray &metadata ) 77{ 78 if ( !classInfo->BeforeWriteObject( object , this , persister , metadata) ) 79 return ; 80 81 if ( persister->BeforeWriteObject( this , object , classInfo , metadata) ) 82 { 83 if ( object == NULL ) 84 DoWriteNullObject() ; 85 else if ( IsObjectKnown( object ) ) 86 DoWriteRepeatedObject( GetObjectID(object) ) ; 87 else 88 { 89 int oid = m_data->m_nextId++ ; 90 if ( !isEmbedded ) 91 m_data->m_writtenObjects[object] = oid ; 92 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 ) ; 96 if ( !isEmbedded && dynobj ) 97 m_data->m_writtenObjects[dynobj->GetSuperClassInstance()] = oid ; 98 99 DoBeginWriteObject( object , classInfo , oid , metadata ) ; 100 wxWriterInternalPropertiesData data ; 101 WriteAllProperties( object , classInfo , persister , &data ) ; 102 DoEndWriteObject( object , classInfo , oid ) ; 103 } 104 persister->AfterWriteObject( this ,object , classInfo ) ; 105 } 106} 107 108void wxWriter::FindConnectEntry(const wxEvtHandler * evSource,const wxDelegateTypeInfo* dti, const wxObject* &sink , const wxHandlerInfo *&handler) 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 120 if ( entry->m_fn && 121 (dti->GetEventType() == entry->m_eventType) && 122 (entry->m_id == -1 ) && 123 (entry->m_eventSink != NULL ) ) 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} 143void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci , wxPersister *persister, wxWriterInternalPropertiesData * data ) 144{ 145 wxPropertyInfoMap map ; 146 ci->GetProperties( map ) ; 147 for ( int i = 0 ; i < ci->GetCreateParamCount() ; ++i ) 148 { 149 wxString name = ci->GetCreateParamName(i) ; 150 const wxPropertyInfo* prop = map.find(name)->second ; 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 } 159 map.erase( name ) ; 160 } 161 { // Extra block for broken compilers 162 for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter ) 163 { 164 const wxPropertyInfo* prop = iter->second ; 165 if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH ) 166 { 167 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ; 168 } 169 } 170 } 171 { // Extra block for broken compilers 172 for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter ) 173 { 174 const wxPropertyInfo* prop = iter->second ; 175 if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) ) 176 { 177 WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ; 178 } 179 } 180 } 181} 182 183void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , const wxPropertyInfo* pi , wxPersister *persister , wxWriterInternalPropertiesData *WXUNUSED(data) ) 184{ 185 if ( pi->GetFlags() & wxPROP_DONT_STREAM ) 186 return ; 187 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() ; 192 193 if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION ) 194 { 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 ) 199 { 200 if ( i == 0 ) 201 DoBeginWriteProperty( pi ) ; 202 203 DoBeginWriteElement() ; 204 wxxVariant value = data[i] ; 205 if ( persister->BeforeWriteProperty( this , obj, pi , value ) ) 206 { 207 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ; 208 if ( cti ) 209 { 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 ) ; 214 } 215 else 216 { 217 DoWriteSimpleType( value ) ; 218 } 219 } 220 DoEndWriteElement() ; 221 if ( i == data.GetCount() - 1 ) 222 DoEndWriteProperty( pi ) ; 223 } 224 } 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 ; 232 233 const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ; 234 if ( evSource ) 235 { 236 FindConnectEntry( evSource , dti , sink , handler ) ; 237 if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) ) 238 { 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 } 252 } 253 } 254 else 255 { 256 wxLogError(_("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ; 257 } 258 } 259 else 260 { 261 wxxVariant value ; 262 pi->GetAccessor()->GetProperty(obj, value) ; 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() ) ; 271 if ( eti ) 272 { 273 eti->ConvertFromLong( value.wxTEMPLATED_MEMBER_CALL(Get , long) , value ) ; 274 } 275 else 276 { 277 wxLogError( _("Type must have enum - long conversion") ) ; 278 } 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 } 287 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 294 if ( persister->BeforeWriteProperty( this , obj, pi , value ) ) 295 { 296 DoBeginWriteProperty( pi ) ; 297 if ( cti ) 298 { 299 const wxClassInfo* pci = cti->GetClassInfo() ; 300 wxObject *vobj = pci->VariantToInstance( value ) ; 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 } 313 } 314 else 315 { 316 DoWriteSimpleType( value ) ; 317 } 318 DoEndWriteProperty( pi ) ; 319 } 320 } 321 } 322} 323 324int wxWriter::GetObjectID(const wxObject *obj) 325{ 326 if ( !IsObjectKnown( obj ) ) 327 return wxInvalidObjectID ; 328 329 return m_data->m_writtenObjects[obj] ; 330} 331 332bool wxWriter::IsObjectKnown( const wxObject *obj ) 333{ 334 return m_data->m_writtenObjects.find( obj ) != m_data->m_writtenObjects.end() ; 335} 336 337 338// ---------------------------------------------------------------------------- 339// reading objects in 340// ---------------------------------------------------------------------------- 341 342struct wxReader::wxReaderInternal 343{ 344 map<int,wxClassInfo*> m_classInfos; 345}; 346 347wxReader::wxReader() 348{ 349 m_data = new wxReaderInternal; 350} 351 352wxReader::~wxReader() 353{ 354 delete m_data; 355} 356 357wxClassInfo* wxReader::GetObjectClassInfo(int objectID) 358{ 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 } 369 return m_data->m_classInfos[objectID] ; 370} 371 372void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo ) 373{ 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 } 384 m_data->m_classInfos[objectID] = classInfo ; 385} 386 387bool wxReader::HasObjectClassInfo( int objectID ) 388{ 389 if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID ) 390 { 391 wxLogError( _("Invalid or Null Object ID passed to HasObjectClassInfo" ) ) ; 392 return NULL ; 393 } 394 return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ; 395} 396 397 398// ---------------------------------------------------------------------------- 399// reading xml in 400// ---------------------------------------------------------------------------- 401 402/* 403Reading components has not to be extended for components 404as properties are always sought by typeinfo over all levels 405and create params are always toplevel class only 406*/ 407 408 409// ---------------------------------------------------------------------------- 410// depersisting to memory 411// ---------------------------------------------------------------------------- 412 413struct wxRuntimeDepersister::wxRuntimeDepersisterInternal 414{ 415 map<int,wxObject *> m_objects; 416 417 void SetObject(int objectID, wxObject *obj ) 418 { 419 if ( m_objects.find(objectID) != m_objects.end() ) 420 { 421 wxLogError( _("Passing a already registered object to SetObject") ) ; 422 return ; 423 } 424 m_objects[objectID] = obj ; 425 } 426 wxObject* GetObject( int objectID ) 427 { 428 if ( objectID == wxNullObjectID ) 429 return NULL ; 430 if ( m_objects.find(objectID) == m_objects.end() ) 431 { 432 wxLogError( _("Passing an unkown object to GetObject") ) ; 433 return NULL ; 434 } 435 436 return m_objects[objectID] ; 437 } 438} ; 439 440wxRuntimeDepersister::wxRuntimeDepersister() 441{ 442 m_data = new wxRuntimeDepersisterInternal() ; 443} 444 445wxRuntimeDepersister::~wxRuntimeDepersister() 446{ 447 delete m_data ; 448} 449 450void wxRuntimeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo , 451 wxxVariantArray &WXUNUSED(metadata)) 452{ 453 wxObject *O; 454 O = classInfo->CreateObject(); 455 m_data->SetObject(objectID, O); 456} 457 458void wxRuntimeDepersister::CreateObject(int objectID, 459 const wxClassInfo *classInfo, 460 int paramCount, 461 wxxVariant *params, 462 int *objectIdValues, 463 const wxClassInfo **objectClassInfos , 464 wxxVariantArray &WXUNUSED(metadata)) 465{ 466 wxObject *o; 467 o = m_data->GetObject(objectID); 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]); 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 } 481 params[i] = objectClassInfos[i]->InstanceToVariant(o) ; 482 } 483 } 484 classInfo->Create(o, paramCount, params); 485} 486 487void 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 517void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo)) 518{ 519 wxObject *o; 520 o = m_data->GetObject(objectID); 521 delete o ; 522} 523 524void wxRuntimeDepersister::SetProperty(int objectID, 525 const wxClassInfo *classInfo, 526 const wxPropertyInfo* propertyInfo, 527 const wxxVariant &value) 528{ 529 wxObject *o; 530 o = m_data->GetObject(objectID); 531 classInfo->SetProperty( o , propertyInfo->GetName() , value ) ; 532} 533 534void wxRuntimeDepersister::SetPropertyAsObject(int objectID, 535 const wxClassInfo *classInfo, 536 const wxPropertyInfo* propertyInfo, 537 int valueObjectId) 538{ 539 wxObject *o, *valo; 540 o = m_data->GetObject(objectID); 541 valo = m_data->GetObject(valueObjectId); 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) ) ; 552} 553 554void wxRuntimeDepersister::SetConnect(int eventSourceObjectID, 555 const wxClassInfo *WXUNUSED(eventSourceClassInfo), 556 const wxPropertyInfo *delegateInfo , 557 const wxClassInfo *WXUNUSED(eventSinkClassInfo) , 558 const wxHandlerInfo* handlerInfo , 559 int eventSinkObjectID ) 560{ 561 wxEvtHandler *ehsource = dynamic_cast< wxEvtHandler* >( m_data->GetObject( eventSourceObjectID ) ) ; 562 wxEvtHandler *ehsink = dynamic_cast< wxEvtHandler *>(m_data->GetObject(eventSinkObjectID) ) ; 563 564 if ( ehsource && ehsink ) 565 { 566 const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo()); 567 if( delegateTypeInfo && delegateTypeInfo->GetLastEventType() == -1 ) 568 { 569 ehsource->Connect( -1 , delegateTypeInfo->GetEventType() , 570 handlerInfo->GetEventFunction() , NULL /*user data*/ , 571 ehsink ) ; 572 } 573 else 574 { 575 for ( wxEventType iter = delegateTypeInfo->GetEventType() ; iter <= delegateTypeInfo->GetLastEventType() ; ++iter ) 576 { 577 ehsource->Connect( -1 , iter , 578 handlerInfo->GetEventFunction() , NULL /*user data*/ , 579 ehsink ) ; 580 } 581 } 582 } 583} 584 585wxObject *wxRuntimeDepersister::GetObject(int objectID) 586{ 587 return m_data->GetObject( objectID ) ; 588} 589 590// adds an element to a property collection 591void wxRuntimeDepersister::AddToPropertyCollection( int objectID , 592 const wxClassInfo *classInfo, 593 const wxPropertyInfo* propertyInfo , 594 const wxxVariant &value) 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) 602void wxRuntimeDepersister::AddToPropertyCollectionAsObject(int objectID, 603 const wxClassInfo *classInfo, 604 const wxPropertyInfo* propertyInfo , 605 int valueObjectId) 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} 622 623// ---------------------------------------------------------------------------- 624// depersisting to code 625// ---------------------------------------------------------------------------- 626 627struct wxCodeDepersister::wxCodeDepersisterInternal 628{ 629#if wxUSE_UNICODE 630 map<int,wstring> m_objectNames ; 631#else 632 map<int,string> m_objectNames ; 633#endif 634 635 void SetObjectName(int objectID, const wxString &name ) 636 { 637 if ( m_objectNames.find(objectID) != m_objectNames.end() ) 638 { 639 wxLogError( _("Passing a already registered object to SetObjectName") ) ; 640 return ; 641 } 642 m_objectNames[objectID] = (const wxChar *)name; 643 } 644 645 wxString GetObjectName( int objectID ) 646 { 647 if ( objectID == wxNullObjectID ) 648 return wxT("NULL") ; 649 650 if ( m_objectNames.find(objectID) == m_objectNames.end() ) 651 { 652 wxLogError( _("Passing an unkown object to GetObject") ) ; 653 return wxEmptyString ; 654 } 655 return wxString( m_objectNames[objectID].c_str() ) ; 656 } 657} ; 658 659wxCodeDepersister::wxCodeDepersister(wxTextOutputStream *out) 660: m_fp(out) 661{ 662 m_data = new wxCodeDepersisterInternal ; 663} 664 665wxCodeDepersister::~wxCodeDepersister() 666{ 667 delete m_data ; 668} 669 670void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo , 671 wxxVariantArray &WXUNUSED(metadata)) 672{ 673 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ; 674 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s;\n"), 675 classInfo->GetClassName(), 676 objectName.c_str(), 677 classInfo->GetClassName()) ); 678 m_data->SetObjectName( objectID , objectName ) ; 679} 680 681void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo)) 682{ 683 m_fp->WriteString( wxString::Format( wxT("\tdelete %s;\n"), 684 m_data->GetObjectName( objectID).c_str() ) ); 685} 686 687wxString wxCodeDepersister::ValueAsCode( const wxxVariant ¶m ) 688{ 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) ; 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 } 702 } 703 else if ( type->GetKind() == wxT_STRING ) 704 { 705 value.Printf( wxT("\"%s\""),param.GetAsString().c_str() ); 706 } 707 else 708 { 709 value.Printf( wxT("%s"), param.GetAsString().c_str() ); 710 } 711 return value ; 712} 713 714void wxCodeDepersister::CreateObject(int objectID, 715 const wxClassInfo *WXUNUSED(classInfo), 716 int paramCount, 717 wxxVariant *params, 718 int *objectIDValues, 719 const wxClassInfo **WXUNUSED(objectClassInfos) , 720 wxxVariantArray &WXUNUSED(metadata) 721 ) 722{ 723 int i; 724 m_fp->WriteString( wxString::Format( wxT("\t%s->Create("), m_data->GetObjectName(objectID).c_str() ) ); 725 for (i = 0; i < paramCount; i++) 726 { 727 if ( objectIDValues[i] != wxInvalidObjectID ) 728 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) ); 729 else 730 { 731 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) ); 732 } 733 if (i < paramCount - 1) 734 m_fp->WriteString( wxT(", ")); 735 } 736 m_fp->WriteString( wxT(");\n") ); 737} 738 739void 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{ 748 wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ; 749 m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s("), 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 ) 759 m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) ); 760 else 761 { 762 m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) ); 763 } 764 if (i < paramCount - 1) 765 m_fp->WriteString( wxT(", ") ); 766 } 767 m_fp->WriteString( wxT(");\n") ); 768} 769 770void wxCodeDepersister::SetProperty(int objectID, 771 const wxClassInfo *WXUNUSED(classInfo), 772 const wxPropertyInfo* propertyInfo, 773 const wxxVariant &value) 774{ 775 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"), 776 m_data->GetObjectName(objectID).c_str(), 777 propertyInfo->GetAccessor()->GetSetterName().c_str(), 778 ValueAsCode(value).c_str()) ); 779} 780 781void wxCodeDepersister::SetPropertyAsObject(int objectID, 782 const wxClassInfo *WXUNUSED(classInfo), 783 const wxPropertyInfo* propertyInfo, 784 int valueObjectId) 785{ 786 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT ) 787 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(*%s);\n"), 788 m_data->GetObjectName(objectID).c_str(), 789 propertyInfo->GetAccessor()->GetSetterName().c_str(), 790 m_data->GetObjectName( valueObjectId).c_str() ) ); 791 else 792 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"), 793 m_data->GetObjectName(objectID).c_str(), 794 propertyInfo->GetAccessor()->GetSetterName().c_str(), 795 m_data->GetObjectName( valueObjectId).c_str() ) ); 796} 797 798void wxCodeDepersister::AddToPropertyCollection( int objectID , 799 const wxClassInfo *WXUNUSED(classInfo), 800 const wxPropertyInfo* propertyInfo , 801 const wxxVariant &value) 802{ 803 m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"), 804 m_data->GetObjectName(objectID).c_str(), 805 propertyInfo->GetAccessor()->GetAdderName().c_str(), 806 ValueAsCode(value).c_str()) ); 807} 808 809// sets the corresponding property (value is an object) 810void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID), 811 const wxClassInfo *WXUNUSED(classInfo), 812 const wxPropertyInfo* WXUNUSED(propertyInfo) , 813 int WXUNUSED(valueObjectId)) 814{ 815 // TODO 816} 817 818void wxCodeDepersister::SetConnect(int eventSourceObjectID, 819 const wxClassInfo *WXUNUSED(eventSourceClassInfo), 820 const wxPropertyInfo *delegateInfo , 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() ; 828 const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo()); 829 if ( delegateTypeInfo ) 830 { 831 int eventType = delegateTypeInfo->GetEventType() ; 832 wxString handlerName = handlerInfo->GetName() ; 833 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 } 841} 842 843#include "wx/arrimpl.cpp" 844 845WX_DEFINE_OBJARRAY(wxxVariantArray); 846 847#endif // wxUSE_EXTENDED_RTTI 848