1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/xti.cpp
3 // Purpose: runtime metadata information (extended class info)
4 // Author: Stefan Csomor
8 // Copyright: (c) 1997 Julian Smart
9 // (c) 2003 Stefan Csomor
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
20 #if wxUSE_EXTENDED_RTTI
23 #include "wx/object.h"
29 #include "wx/xml/xml.h"
30 #include "wx/tokenzr.h"
35 #include "wx/beforestd.h"
39 #include "wx/afterstd.h"
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 wxEnumData::wxEnumData( wxEnumMemberData
* data
)
50 for ( m_count
= 0; m_members
[m_count
].m_name
; m_count
++)
54 bool wxEnumData::HasEnumMemberValue(const wxChar
*name
, int *value
) const
57 for (i
= 0; m_members
[i
].m_name
; i
++ )
59 if (!wxStrcmp(name
, m_members
[i
].m_name
))
62 *value
= m_members
[i
].m_value
;
69 int wxEnumData::GetEnumMemberValue(const wxChar
*name
) const
72 for (i
= 0; m_members
[i
].m_name
; i
++ )
74 if (!wxStrcmp(name
, m_members
[i
].m_name
))
76 return m_members
[i
].m_value
;
82 const wxChar
*wxEnumData::GetEnumMemberName(int value
) const
85 for (i
= 0; m_members
[i
].m_name
; i
++)
86 if (value
== m_members
[i
].m_value
)
87 return m_members
[i
].m_name
;
92 int wxEnumData::GetEnumMemberValueByIndex( int idx
) const
94 // we should cache the count in order to avoid out-of-bounds errors
95 return m_members
[idx
].m_value
;
98 const wxChar
* wxEnumData::GetEnumMemberNameByIndex( int idx
) const
100 // we should cache the count in order to avoid out-of-bounds errors
101 return m_members
[idx
].m_name
;
104 // ----------------------------------------------------------------------------
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 // ----------------------------------------------------------------------------
112 // streamer specializations
113 // for all built-in types
117 template<> void wxStringReadValue(const wxString
&s
, bool &data
)
120 wxSscanf(s
, _T("%d"), &intdata
);
121 data
= (bool)(intdata
!= 0);
124 template<> void wxStringWriteValue(wxString
&s
, const bool &data
)
126 s
= wxString::Format(_T("%d"), data
);
131 template<> void wxStringReadValue(const wxString
&s
, char &data
)
134 wxSscanf(s
, _T("%d"), &intdata
);
135 data
= char(intdata
);
138 template<> void wxStringWriteValue(wxString
&s
, const char &data
)
140 s
= wxString::Format(_T("%d"), data
);
145 template<> void wxStringReadValue(const wxString
&s
, unsigned char &data
)
148 wxSscanf(s
, _T("%d"), &intdata
);
149 data
= (unsigned char)(intdata
);
152 template<> void wxStringWriteValue(wxString
&s
, const unsigned char &data
)
154 s
= wxString::Format(_T("%d"), data
);
159 template<> void wxStringReadValue(const wxString
&s
, int &data
)
161 wxSscanf(s
, _T("%d"), &data
);
164 template<> void wxStringWriteValue(wxString
&s
, const int &data
)
166 s
= wxString::Format(_T("%d"), data
);
171 template<> void wxStringReadValue(const wxString
&s
, unsigned int &data
)
173 wxSscanf(s
, _T("%d"), &data
);
176 template<> void wxStringWriteValue(wxString
&s
, const unsigned int &data
)
178 s
= wxString::Format(_T("%d"), data
);
183 template<> void wxStringReadValue(const wxString
&s
, long &data
)
185 wxSscanf(s
, _T("%ld"), &data
);
188 template<> void wxStringWriteValue(wxString
&s
, const long &data
)
190 s
= wxString::Format(_T("%ld"), data
);
195 template<> void wxStringReadValue(const wxString
&s
, unsigned long &data
)
197 wxSscanf(s
, _T("%ld"), &data
);
200 template<> void wxStringWriteValue(wxString
&s
, const unsigned long &data
)
202 s
= wxString::Format(_T("%ld"), data
);
206 template<> void wxStringReadValue(const wxString
&s
, wxLongLong_t
&data
)
208 wxSscanf(s
, _T("%lld"), &data
);
211 template<> void wxStringWriteValue(wxString
&s
, const wxLongLong_t
&data
)
213 s
= wxString::Format(_T("%lld"), data
);
216 template<> void wxStringReadValue(const wxString
&s
, wxULongLong_t
&data
)
218 wxSscanf(s
, _T("%lld"), &data
);
221 template<> void wxStringWriteValue(wxString
&s
, const wxULongLong_t
&data
)
223 s
= wxString::Format(_T("%lld"), data
);
228 template<> void wxStringReadValue(const wxString
&s
, float &data
)
230 wxSscanf(s
, _T("%f"), &data
);
233 template<> void wxStringWriteValue(wxString
&s
, const float &data
)
235 s
= wxString::Format(_T("%f"), data
);
240 template<> void wxStringReadValue(const wxString
&s
, double &data
)
242 wxSscanf(s
, _T("%lf"), &data
);
245 template<> void wxStringWriteValue(wxString
&s
, const double &data
)
247 s
= wxString::Format(_T("%lf"), data
);
252 template<> void wxStringReadValue(const wxString
&s
, wxString
&data
)
257 template<> void wxStringWriteValue(wxString
&s
, const wxString
&data
)
266 #if wxUSE_FUNC_TEMPLATE_POINTER
267 #define wxBUILTIN_TYPE_INFO( element, type ) \
269 s_typeInfo##type(element, &wxToStringConverter<type>, \
270 &wxFromStringConverter<type>, typeid(type).name());
272 #define wxBUILTIN_TYPE_INFO( element, type ) \
273 void _toString##element( const wxAny& data, wxString &result ) \
274 { wxToStringConverter<type, data, result); } \
275 void _fromString##element( const wxString& data, wxAny &result ) \
276 { wxFromStringConverter<type, data, result); } \
277 wxBuiltInTypeInfo s_typeInfo##type(element, &_toString##element, \
278 &_fromString##element, typeid(type).name());
281 typedef unsigned char unsigned_char
;
282 typedef unsigned int unsigned_int
;
283 typedef unsigned long unsigned_long
;
285 wxBuiltInTypeInfo
s_typeInfovoid( wxT_VOID
, NULL
, NULL
, typeid(void).name());
286 wxBUILTIN_TYPE_INFO( wxT_BOOL
, bool);
287 wxBUILTIN_TYPE_INFO( wxT_CHAR
, char);
288 wxBUILTIN_TYPE_INFO( wxT_UCHAR
, unsigned_char
);
289 wxBUILTIN_TYPE_INFO( wxT_INT
, int);
290 wxBUILTIN_TYPE_INFO( wxT_UINT
, unsigned_int
);
291 wxBUILTIN_TYPE_INFO( wxT_LONG
, long);
292 wxBUILTIN_TYPE_INFO( wxT_ULONG
, unsigned_long
);
293 wxBUILTIN_TYPE_INFO( wxT_FLOAT
, float);
294 wxBUILTIN_TYPE_INFO( wxT_DOUBLE
, double);
295 wxBUILTIN_TYPE_INFO( wxT_STRING
, wxString
);
298 wxBUILTIN_TYPE_INFO(wxT_LONGLONG
, wxLongLong_t
)
299 wxBUILTIN_TYPE_INFO(wxT_ULONGLONG
, wxULongLong_t
)
302 // this are compiler induced specialization which are never used anywhere
304 wxILLEGAL_TYPE_SPECIALIZATION( char const * )
305 wxILLEGAL_TYPE_SPECIALIZATION( char * )
306 wxILLEGAL_TYPE_SPECIALIZATION( unsigned char * )
307 wxILLEGAL_TYPE_SPECIALIZATION( int * )
308 wxILLEGAL_TYPE_SPECIALIZATION( bool * )
309 wxILLEGAL_TYPE_SPECIALIZATION( long * )
310 wxILLEGAL_TYPE_SPECIALIZATION( wxString
* )
314 template<> void wxStringReadValue(const wxString
&s
, wxRange
&data
)
316 int minValue
, maxValue
;
317 wxSscanf(s
, wxT("%d,%d"), &minValue
, &maxValue
);
318 data
= wxRange(minValue
, maxValue
);
321 template<> void wxStringWriteValue(wxString
&s
, const wxRange
&data
)
323 s
= wxString::Format(wxT("%d,%d"), data
.GetMin() , data
.GetMax());
326 wxCUSTOM_TYPE_INFO(wxRange
, wxToStringConverter
<wxRange
> , wxFromStringConverter
<wxRange
>)
330 wxCOLLECTION_TYPE_INFO( wxString
, wxArrayString
);
332 template<> void wxCollectionToVariantArray( wxArrayString
const &theArray
,
335 wxArrayCollectionToVariantArray( theArray
, value
);
338 wxTypeInfoMap
*wxTypeInfo::ms_typeTable
= NULL
;
340 wxTypeInfo
*wxTypeInfo::FindType(const wxString
& typeName
)
342 wxTypeInfoMap::iterator iter
= ms_typeTable
->find(typeName
);
344 if (iter
== ms_typeTable
->end())
347 return (wxTypeInfo
*)iter
->second
;
350 wxClassTypeInfo::wxClassTypeInfo( wxTypeKind kind
, wxClassInfo
* classInfo
,
351 wxVariant2StringFnc to
,
352 wxString2VariantFnc from
,
353 const wxString
&name
) :
354 wxTypeInfo( kind
, to
, from
, name
)
356 wxASSERT_MSG( kind
== wxT_OBJECT_PTR
|| kind
== wxT_OBJECT
,
357 wxT("Illegal Kind for Enum Type")); m_classInfo
= classInfo
;
360 wxEventSourceTypeInfo::wxEventSourceTypeInfo( int eventType
, wxClassInfo
* eventClass
,
361 wxVariant2StringFnc to
,
362 wxString2VariantFnc from
) :
363 wxTypeInfo ( wxT_DELEGATE
, to
, from
, wxEmptyString
)
365 m_eventClass
= eventClass
;
366 m_eventType
= eventType
;
367 m_lastEventType
= -1;
370 wxEventSourceTypeInfo::wxEventSourceTypeInfo( int eventType
, int lastEventType
,
371 wxClassInfo
* eventClass
,
372 wxVariant2StringFnc to
,
373 wxString2VariantFnc from
) :
374 wxTypeInfo ( wxT_DELEGATE
, to
, from
, wxEmptyString
)
376 m_eventClass
= eventClass
;
377 m_eventType
= eventType
;
378 m_lastEventType
= lastEventType
;
381 void wxTypeInfo::Register()
383 if ( ms_typeTable
== NULL
)
384 ms_typeTable
= new wxTypeInfoMap();
386 if( !m_name
.empty() )
387 (*ms_typeTable
)[m_name
] = this;
390 void wxTypeInfo::Unregister()
392 if( !m_name
.empty() )
393 ms_typeTable
->erase(m_name
);
396 // removing header dependancy on string tokenizer
398 void wxSetStringToArray( const wxString
&s
, wxArrayString
&array
)
400 wxStringTokenizer
tokenizer(s
, wxT("| \t\n"), wxTOKEN_STRTOK
);
403 while (tokenizer
.HasMoreTokens())
405 array
.Add(tokenizer
.GetNextToken());
409 // ----------------------------------------------------------------------------
411 // ----------------------------------------------------------------------------
413 void wxPropertyInfo::Insert(wxPropertyInfo
* &iter
)
420 wxPropertyInfo
* i
= iter
;
428 void wxPropertyInfo::Remove()
430 if ( this == m_itsClass
->m_firstProperty
)
432 m_itsClass
->m_firstProperty
= m_next
;
436 wxPropertyInfo
*info
= m_itsClass
->m_firstProperty
;
439 if ( info
->m_next
== this )
441 info
->m_next
= m_next
;
451 // ----------------------------------------------------------------------------
453 // ----------------------------------------------------------------------------
455 void wxHandlerInfo::Insert(wxHandlerInfo
* &iter
)
462 wxHandlerInfo
* i
= iter
;
470 void wxHandlerInfo::Remove()
472 if ( this == m_itsClass
->m_firstHandler
)
474 m_itsClass
->m_firstHandler
= m_next
;
478 wxHandlerInfo
*info
= m_itsClass
->m_firstHandler
;
481 if ( info
->m_next
== this )
483 info
->m_next
= m_next
;
493 // ----------------------------------------------------------------------------
495 // ----------------------------------------------------------------------------
497 bool wxClassInfo::Create(wxObject
*object
, int ParamCount
, wxAny
*Params
) const
499 if ( ParamCount
!= m_constructorPropertiesCount
)
501 // FIXME: shouldn't we just return false and let the caller handle it?
502 wxLogError( _("Illegal Parameter Count for Create Method") );
506 return m_constructor
->Create( object
, Params
);
509 wxObject
*wxClassInfo::ConstructObject(int ParamCount
, wxAny
*Params
) const
511 if ( ParamCount
!= m_constructorPropertiesCount
)
513 // FIXME: shouldn't we just return NULL and let the caller handle this case?
514 wxLogError( _("Illegal Parameter Count for ConstructObject Method") );
518 wxObject
*object
= NULL
;
519 if (!m_constructor
->Create( object
, Params
))
524 bool wxClassInfo::IsKindOf(const wxClassInfo
*info
) const
531 for ( int i
= 0; m_parents
[i
]; ++ i
)
533 if ( m_parents
[i
]->IsKindOf( info
) )
540 const wxPropertyAccessor
*wxClassInfo::FindAccessor(const wxChar
*PropertyName
) const
542 const wxPropertyInfo
* info
= FindPropertyInfo( PropertyName
);
545 return info
->GetAccessor();
550 wxPropertyInfo
*wxClassInfo::FindPropertyInfoInThisClass (const wxChar
*PropertyName
) const
552 wxPropertyInfo
* info
= GetFirstProperty();
556 if ( wxStrcmp( info
->GetName(), PropertyName
) == 0 )
558 info
= info
->GetNext();
564 const wxPropertyInfo
*wxClassInfo::FindPropertyInfo (const wxChar
*PropertyName
) const
566 const wxPropertyInfo
* info
= FindPropertyInfoInThisClass( PropertyName
);
570 const wxClassInfo
** parents
= GetParents();
571 for ( int i
= 0; parents
[i
]; ++ i
)
573 if ( ( info
= parents
[i
]->FindPropertyInfo( PropertyName
) ) != NULL
)
580 wxHandlerInfo
*wxClassInfo::FindHandlerInfoInThisClass (const wxChar
*PropertyName
) const
582 wxHandlerInfo
* info
= GetFirstHandler();
586 if ( wxStrcmp( info
->GetName(), PropertyName
) == 0 )
588 info
= info
->GetNext();
594 const wxHandlerInfo
*wxClassInfo::FindHandlerInfo (const wxChar
*PropertyName
) const
596 const wxHandlerInfo
* info
= FindHandlerInfoInThisClass( PropertyName
);
601 const wxClassInfo
** parents
= GetParents();
602 for ( int i
= 0; parents
[i
]; ++ i
)
604 if ( ( info
= parents
[i
]->FindHandlerInfo( PropertyName
) ) != NULL
)
611 wxObjectStreamingCallback
wxClassInfo::GetStreamingCallback() const
613 if ( m_streamingCallback
)
614 return m_streamingCallback
;
616 wxObjectStreamingCallback retval
= NULL
;
617 const wxClassInfo
** parents
= GetParents();
618 for ( int i
= 0; parents
[i
] && retval
== NULL
; ++ i
)
620 retval
= parents
[i
]->GetStreamingCallback();
625 bool wxClassInfo::BeforeWriteObject( const wxObject
*obj
, wxObjectWriter
*streamer
,
626 wxObjectWriterCallback
*writercallback
, const wxStringToAnyHashMap
&metadata
) const
628 wxObjectStreamingCallback sb
= GetStreamingCallback();
630 return (*sb
)(obj
, streamer
, writercallback
, metadata
);
635 void wxClassInfo::SetProperty(wxObject
*object
, const wxChar
*propertyName
,
636 const wxAny
&value
) const
638 const wxPropertyAccessor
*accessor
;
640 accessor
= FindAccessor(propertyName
);
641 wxASSERT(accessor
->HasSetter());
642 accessor
->SetProperty( object
, value
);
645 wxAny
wxClassInfo::GetProperty(wxObject
*object
, const wxChar
*propertyName
) const
647 const wxPropertyAccessor
*accessor
;
649 accessor
= FindAccessor(propertyName
);
650 wxASSERT(accessor
->HasGetter());
652 accessor
->GetProperty(object
,result
);
656 wxAnyList
wxClassInfo::GetPropertyCollection(wxObject
*object
,
657 const wxChar
*propertyName
) const
659 const wxPropertyAccessor
*accessor
;
661 accessor
= FindAccessor(propertyName
);
662 wxASSERT(accessor
->HasGetter());
664 accessor
->GetPropertyCollection(object
,result
);
668 void wxClassInfo::AddToPropertyCollection(wxObject
*object
, const wxChar
*propertyName
,
669 const wxAny
& value
) const
671 const wxPropertyAccessor
*accessor
;
673 accessor
= FindAccessor(propertyName
);
674 wxASSERT(accessor
->HasAdder());
675 accessor
->AddToPropertyCollection( object
, value
);
678 // void wxClassInfo::GetProperties( wxPropertyInfoMap &map ) const
679 // The map parameter (the name map that is) seems something special
680 // to MSVC and so we use a other name.
681 void wxClassInfo::GetProperties( wxPropertyInfoMap
&infomap
) const
683 const wxPropertyInfo
*pi
= GetFirstProperty();
686 if ( infomap
.find( pi
->GetName() ) == infomap
.end() )
687 infomap
[pi
->GetName()] = (wxPropertyInfo
*) pi
;
692 const wxClassInfo
** parents
= GetParents();
693 for ( int i
= 0; parents
[i
]; ++ i
)
695 parents
[i
]->GetProperties( infomap
);
699 wxObject
* wxClassInfo::AnyToObjectPtr( const wxAny
&data
) const
701 return m_variantOfPtrToObjectConverter(data
);
704 void wxClassInfo::CallOnAny( const wxAny
&data
, wxObjectFunctor
* functor
) const
706 if ( data
.GetTypeInfo()->GetKind() == wxT_OBJECT
)
707 return m_variantToObjectConverter(data
, functor
);
709 return (*functor
)(m_variantOfPtrToObjectConverter(data
));
712 wxAny
wxClassInfo::ObjectPtrToAny( wxObject
* obj
) const
714 return m_objectToVariantConverter(obj
);
717 bool wxClassInfo::NeedsDirectConstruction() const
719 return wx_dynamic_cast(wxObjectAllocator
*, m_constructor
) != NULL
;
722 // ----------------------------------------------------------------------------
723 // wxDynamicObject support
724 // ----------------------------------------------------------------------------
726 // Dynamic Objects are objects that have a real superclass instance and carry their
727 // own attributes in a hash map. Like this it is possible to create the objects and
728 // stream them, as if their class information was already available from compiled data
730 struct wxDynamicObject::wxDynamicObjectInternal
732 wxDynamicObjectInternal() {}
734 wxStringToAnyHashMap m_properties
;
737 typedef list
< wxDynamicObject
* > wxDynamicObjectList
;
739 struct wxDynamicClassInfo::wxDynamicClassInfoInternal
741 wxDynamicObjectList m_dynamicObjects
;
744 // instantiates this object with an instance of its superclass
745 wxDynamicObject::wxDynamicObject(wxObject
* superClassInstance
, const wxDynamicClassInfo
*info
)
747 m_superClassInstance
= superClassInstance
;
749 m_data
= new wxDynamicObjectInternal
;
752 wxDynamicObject::~wxDynamicObject()
754 wx_dynamic_cast(const wxDynamicClassInfo
*, m_classInfo
)->
755 m_data
->m_dynamicObjects
.remove( this );
757 delete m_superClassInstance
;
760 void wxDynamicObject::SetProperty (const wxChar
*propertyName
, const wxAny
&value
)
762 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(propertyName
),
763 wxT("Accessing Unknown Property in a Dynamic Object") );
764 m_data
->m_properties
[propertyName
] = value
;
767 wxAny
wxDynamicObject::GetProperty (const wxChar
*propertyName
) const
769 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(propertyName
),
770 wxT("Accessing Unknown Property in a Dynamic Object") );
771 return m_data
->m_properties
[propertyName
];
774 void wxDynamicObject::RemoveProperty( const wxChar
*propertyName
)
776 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(propertyName
),
777 wxT("Removing Unknown Property in a Dynamic Object") );
778 m_data
->m_properties
.erase( propertyName
);
781 void wxDynamicObject::RenameProperty( const wxChar
*oldPropertyName
,
782 const wxChar
*newPropertyName
)
784 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(oldPropertyName
),
785 wxT("Renaming Unknown Property in a Dynamic Object") );
787 wxAny value
= m_data
->m_properties
[oldPropertyName
];
788 m_data
->m_properties
.erase( oldPropertyName
);
789 m_data
->m_properties
[newPropertyName
] = value
;
793 // ----------------------------------------------------------------------------
794 // wxDynamicClassInfo
795 // ----------------------------------------------------------------------------
797 wxDynamicClassInfo::wxDynamicClassInfo( const wxChar
*unitName
,
798 const wxChar
*className
,
799 const wxClassInfo
* superClass
) :
800 wxClassInfo( unitName
, className
, new const wxClassInfo
*[2])
802 GetParents()[0] = superClass
;
803 GetParents()[1] = NULL
;
804 m_data
= new wxDynamicClassInfoInternal
;
807 wxDynamicClassInfo::~wxDynamicClassInfo()
809 delete[] GetParents();
813 wxObject
*wxDynamicClassInfo::AllocateObject() const
815 wxObject
* parent
= GetParents()[0]->AllocateObject();
816 wxDynamicObject
*obj
= new wxDynamicObject( parent
, this );
817 m_data
->m_dynamicObjects
.push_back( obj
);
821 bool wxDynamicClassInfo::Create (wxObject
*object
, int paramCount
, wxAny
*params
) const
823 wxDynamicObject
*dynobj
= wx_dynamic_cast( wxDynamicObject
*, object
);
824 wxASSERT_MSG( dynobj
,
825 wxT("cannot call wxDynamicClassInfo::Create on ")
826 wxT("an object other than wxDynamicObject") );
828 return GetParents()[0]->Create( dynobj
->GetSuperClassInstance(), paramCount
, params
);
831 // get number of parameters for constructor
832 int wxDynamicClassInfo::GetCreateParamCount() const
834 return GetParents()[0]->GetCreateParamCount();
837 // get i-th constructor parameter
838 const wxChar
* wxDynamicClassInfo::GetCreateParamName(int i
) const
840 return GetParents()[0]->GetCreateParamName( i
);
843 void wxDynamicClassInfo::SetProperty(wxObject
*object
, const wxChar
*propertyName
, const wxAny
&value
) const
845 wxDynamicObject
* dynobj
= wx_dynamic_cast(wxDynamicObject
*, object
);
846 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
847 if ( FindPropertyInfoInThisClass(propertyName
) )
848 dynobj
->SetProperty( propertyName
, value
);
850 GetParents()[0]->SetProperty( dynobj
->GetSuperClassInstance(), propertyName
, value
);
853 wxAny
wxDynamicClassInfo::GetProperty(wxObject
*object
, const wxChar
*propertyName
) const
855 wxDynamicObject
* dynobj
= wx_dynamic_cast(wxDynamicObject
*, object
);
856 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
857 if ( FindPropertyInfoInThisClass(propertyName
) )
858 return dynobj
->GetProperty( propertyName
);
860 return GetParents()[0]->GetProperty( dynobj
->GetSuperClassInstance(), propertyName
);
863 void wxDynamicClassInfo::AddProperty( const wxChar
*propertyName
, const wxTypeInfo
* typeInfo
)
866 new wxPropertyInfo( m_firstProperty
, this, propertyName
, typeInfo
->GetTypeName(), new wxGenericPropertyAccessor( propertyName
), wxAny() );
869 void wxDynamicClassInfo::AddHandler( const wxChar
*handlerName
, wxObjectEventFunction address
, const wxClassInfo
* eventClassInfo
)
872 new wxHandlerInfo( m_firstHandler
, this, handlerName
, address
, eventClassInfo
);
875 // removes an existing runtime-property
876 void wxDynamicClassInfo::RemoveProperty( const wxChar
*propertyName
)
878 for ( wxDynamicObjectList::iterator iter
= m_data
->m_dynamicObjects
.begin(); iter
!= m_data
->m_dynamicObjects
.end(); ++iter
)
879 (*iter
)->RemoveProperty( propertyName
);
880 delete FindPropertyInfoInThisClass(propertyName
);
883 // removes an existing runtime-handler
884 void wxDynamicClassInfo::RemoveHandler( const wxChar
*handlerName
)
886 delete FindHandlerInfoInThisClass(handlerName
);
889 // renames an existing runtime-property
890 void wxDynamicClassInfo::RenameProperty( const wxChar
*oldPropertyName
, const wxChar
*newPropertyName
)
892 wxPropertyInfo
* pi
= FindPropertyInfoInThisClass(oldPropertyName
);
893 wxASSERT_MSG( pi
,wxT("not existing property") );
894 pi
->m_name
= newPropertyName
;
895 wx_dynamic_cast(wxGenericPropertyAccessor
*, pi
->GetAccessor())->RenameProperty( oldPropertyName
, newPropertyName
);
896 for ( wxDynamicObjectList::iterator iter
= m_data
->m_dynamicObjects
.begin(); iter
!= m_data
->m_dynamicObjects
.end(); ++iter
)
897 (*iter
)->RenameProperty( oldPropertyName
, newPropertyName
);
900 // renames an existing runtime-handler
901 void wxDynamicClassInfo::RenameHandler( const wxChar
*oldHandlerName
, const wxChar
*newHandlerName
)
903 wxASSERT_MSG(FindHandlerInfoInThisClass(oldHandlerName
),wxT("not existing handler") );
904 FindHandlerInfoInThisClass(oldHandlerName
)->m_name
= newHandlerName
;
907 // ----------------------------------------------------------------------------
908 // wxGenericPropertyAccessor
909 // ----------------------------------------------------------------------------
911 struct wxGenericPropertyAccessor::wxGenericPropertyAccessorInternal
916 wxGenericPropertyAccessor::wxGenericPropertyAccessor( const wxString
& propertyName
)
917 : wxPropertyAccessor( NULL
, NULL
, NULL
, NULL
)
919 m_data
= new wxGenericPropertyAccessorInternal
;
920 m_propertyName
= propertyName
;
921 m_getterName
= wxT("Get")+propertyName
;
922 m_setterName
= wxT("Set")+propertyName
;
925 wxGenericPropertyAccessor::~wxGenericPropertyAccessor()
930 void wxGenericPropertyAccessor::SetProperty(wxObject
*object
, const wxAny
&value
) const
932 wxDynamicObject
* dynobj
= wx_dynamic_cast(wxDynamicObject
*, object
);
933 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
934 dynobj
->SetProperty(m_propertyName
, value
);
937 void wxGenericPropertyAccessor::GetProperty(const wxObject
*object
, wxAny
& value
) const
939 const wxDynamicObject
* dynobj
= wx_dynamic_cast( const wxDynamicObject
* , object
);
940 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
941 value
= dynobj
->GetProperty( m_propertyName
);
944 // ----------------------------------------------------------------------------
945 // wxGenericPropertyAccessor
946 // ----------------------------------------------------------------------------
948 wxString
wxAnyGetAsString( const wxAny
& data
)
950 if ( data
.IsNull() || data
.GetTypeInfo()==NULL
)
951 return wxEmptyString
;
954 data
.GetTypeInfo()->ConvertToString(data
,s
);
958 const wxObject
* wxAnyGetAsObjectPtr( const wxAny
& data
)
960 if ( !data
.IsNull() )
962 const wxClassTypeInfo
* ti
= wx_dynamic_cast(const wxClassTypeInfo
*, data
.GetTypeInfo());
964 return ti
->GetClassInfo()->AnyToObjectPtr(data
);
969 wxObjectFunctor::~wxObjectFunctor()
972 #endif // wxUSE_EXTENDED_RTTI