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 //wxASSERT_MSG( iter != ms_typeTable->end(),
345 // wxT("lookup for a non-existent type-info") );
346 // FM 3/6/2007 - disabled because otherwise
347 // wxPropertyInfo::GetCollectionElementTypeInfo
349 if (iter
== ms_typeTable
->end())
352 return (wxTypeInfo
*)iter
->second
;
356 wxClassTypeInfo
::wxClassTypeInfo( wxTypeKind kind
, wxClassInfo
* classInfo
,
357 wxVariant2StringFnc to
,
358 wxString2VariantFnc from
,
360 wxTypeInfo( kind
, to
, from
, name
)
362 wxASSERT_MSG( kind
== wxT_OBJECT_PTR
||
364 wxT("Illegal Kind for Enum Type")); m_classInfo
= classInfo
;
368 wxClassTypeInfo
::wxClassTypeInfo( wxTypeKind kind
, wxClassInfo
* classInfo
,
369 wxVariant2StringFnc to
,
370 wxString2VariantFnc from
,
371 const wxString
&name
) :
372 wxTypeInfo( kind
, to
, from
, name
)
374 wxASSERT_MSG( kind
== wxT_OBJECT_PTR
|| kind
== wxT_OBJECT
,
375 wxT("Illegal Kind for Enum Type")); m_classInfo
= classInfo
;
378 wxEventSourceTypeInfo
::wxEventSourceTypeInfo( int eventType
, wxClassInfo
* eventClass
,
379 wxVariant2StringFnc to
,
380 wxString2VariantFnc from
) :
381 wxTypeInfo ( wxT_DELEGATE
, to
, from
, wxEmptyString
)
383 m_eventClass
= eventClass
;
384 m_eventType
= eventType
;
385 m_lastEventType
= -1;
388 wxEventSourceTypeInfo
::wxEventSourceTypeInfo( int eventType
, int lastEventType
,
389 wxClassInfo
* eventClass
,
390 wxVariant2StringFnc to
,
391 wxString2VariantFnc from
) :
392 wxTypeInfo ( wxT_DELEGATE
, to
, from
, wxEmptyString
)
394 m_eventClass
= eventClass
;
395 m_eventType
= eventType
;
396 m_lastEventType
= lastEventType
;
399 void wxTypeInfo
::Register()
401 if ( ms_typeTable
== NULL
)
402 ms_typeTable
= new wxTypeInfoMap();
404 if( !m_name
.empty() )
405 (*ms_typeTable
)[m_name
] = this;
408 void wxTypeInfo
::Unregister()
410 if( !m_name
.empty() )
411 ms_typeTable
->erase(m_name
);
414 // removing header dependancy on string tokenizer
416 void wxSetStringToArray( const wxString
&s
, wxArrayString
&array
)
418 wxStringTokenizer
tokenizer(s
, wxT("| \t\n"), wxTOKEN_STRTOK
);
421 while (tokenizer
.HasMoreTokens())
423 array
.Add(tokenizer
.GetNextToken());
427 // ----------------------------------------------------------------------------
429 // ----------------------------------------------------------------------------
431 void wxPropertyInfo
::Insert(wxPropertyInfo
* &iter
)
438 wxPropertyInfo
* i
= iter
;
446 void wxPropertyInfo
::Remove()
448 if ( this == m_itsClass
->m_firstProperty
)
450 m_itsClass
->m_firstProperty
= m_next
;
454 wxPropertyInfo
*info
= m_itsClass
->m_firstProperty
;
457 if ( info
->m_next
== this )
459 info
->m_next
= m_next
;
469 // ----------------------------------------------------------------------------
471 // ----------------------------------------------------------------------------
473 void wxHandlerInfo
::Insert(wxHandlerInfo
* &iter
)
480 wxHandlerInfo
* i
= iter
;
488 void wxHandlerInfo
::Remove()
490 if ( this == m_itsClass
->m_firstHandler
)
492 m_itsClass
->m_firstHandler
= m_next
;
496 wxHandlerInfo
*info
= m_itsClass
->m_firstHandler
;
499 if ( info
->m_next
== this )
501 info
->m_next
= m_next
;
511 // ----------------------------------------------------------------------------
513 // ----------------------------------------------------------------------------
515 bool wxClassInfo
::Create(wxObject
*object
, int ParamCount
, wxAny
*Params
) const
517 if ( ParamCount
!= m_constructorPropertiesCount
)
519 // FIXME: shouldn't we just return false and let the caller handle it?
520 wxLogError( _("Illegal Parameter Count for Create Method") );
524 return m_constructor
->Create( object
, Params
);
527 wxObject
*wxClassInfo
::ConstructObject(int ParamCount
, wxAny
*Params
) const
529 if ( ParamCount
!= m_constructorPropertiesCount
)
531 // FIXME: shouldn't we just return NULL and let the caller handle this case?
532 wxLogError( _("Illegal Parameter Count for ConstructObject Method") );
536 wxObject
*object
= NULL
;
537 if (!m_constructor
->Create( object
, Params
))
542 bool wxClassInfo
::IsKindOf(const wxClassInfo
*info
) const
549 for ( int i
= 0; m_parents
[i
]; ++ i
)
551 if ( m_parents
[i
]->IsKindOf( info
) )
558 const wxPropertyAccessor
*wxClassInfo
::FindAccessor(const wxChar
*PropertyName
) const
560 const wxPropertyInfo
* info
= FindPropertyInfo( PropertyName
);
563 return info
->GetAccessor();
568 wxPropertyInfo
*wxClassInfo
::FindPropertyInfoInThisClass (const wxChar
*PropertyName
) const
570 wxPropertyInfo
* info
= GetFirstProperty();
574 if ( wxStrcmp( info
->GetName(), PropertyName
) == 0 )
576 info
= info
->GetNext();
582 const wxPropertyInfo
*wxClassInfo
::FindPropertyInfo (const wxChar
*PropertyName
) const
584 const wxPropertyInfo
* info
= FindPropertyInfoInThisClass( PropertyName
);
588 const wxClassInfo
** parents
= GetParents();
589 for ( int i
= 0; parents
[i
]; ++ i
)
591 if ( ( info
= parents
[i
]->FindPropertyInfo( PropertyName
) ) != NULL
)
598 wxHandlerInfo
*wxClassInfo
::FindHandlerInfoInThisClass (const wxChar
*PropertyName
) const
600 wxHandlerInfo
* info
= GetFirstHandler();
604 if ( wxStrcmp( info
->GetName(), PropertyName
) == 0 )
606 info
= info
->GetNext();
612 const wxHandlerInfo
*wxClassInfo
::FindHandlerInfo (const wxChar
*PropertyName
) const
614 const wxHandlerInfo
* info
= FindHandlerInfoInThisClass( PropertyName
);
619 const wxClassInfo
** parents
= GetParents();
620 for ( int i
= 0; parents
[i
]; ++ i
)
622 if ( ( info
= parents
[i
]->FindHandlerInfo( PropertyName
) ) != NULL
)
629 wxObjectStreamingCallback wxClassInfo
::GetStreamingCallback() const
631 if ( m_streamingCallback
)
632 return m_streamingCallback
;
634 wxObjectStreamingCallback retval
= NULL
;
635 const wxClassInfo
** parents
= GetParents();
636 for ( int i
= 0; parents
[i
] && retval
== NULL
; ++ i
)
638 retval
= parents
[i
]->GetStreamingCallback();
643 bool wxClassInfo
::BeforeWriteObject( const wxObject
*obj
, wxObjectWriter
*streamer
,
644 wxObjectWriterCallback
*writercallback
, const wxStringToAnyHashMap
&metadata
) const
646 wxObjectStreamingCallback sb
= GetStreamingCallback();
648 return (*sb
)(obj
, streamer
, writercallback
, metadata
);
653 void wxClassInfo
::SetProperty(wxObject
*object
, const wxChar
*propertyName
,
654 const wxAny
&value
) const
656 const wxPropertyAccessor
*accessor
;
658 accessor
= FindAccessor(propertyName
);
659 wxASSERT(accessor
->HasSetter());
660 accessor
->SetProperty( object
, value
);
663 wxAny wxClassInfo
::GetProperty(wxObject
*object
, const wxChar
*propertyName
) const
665 const wxPropertyAccessor
*accessor
;
667 accessor
= FindAccessor(propertyName
);
668 wxASSERT(accessor
->HasGetter());
670 accessor
->GetProperty(object
,result
);
674 wxAnyList wxClassInfo
::GetPropertyCollection(wxObject
*object
,
675 const wxChar
*propertyName
) const
677 const wxPropertyAccessor
*accessor
;
679 accessor
= FindAccessor(propertyName
);
680 wxASSERT(accessor
->HasGetter());
682 accessor
->GetPropertyCollection(object
,result
);
686 void wxClassInfo
::AddToPropertyCollection(wxObject
*object
, const wxChar
*propertyName
,
687 const wxAny
& value
) const
689 const wxPropertyAccessor
*accessor
;
691 accessor
= FindAccessor(propertyName
);
692 wxASSERT(accessor
->HasAdder());
693 accessor
->AddToPropertyCollection( object
, value
);
696 // void wxClassInfo::GetProperties( wxPropertyInfoMap &map ) const
697 // The map parameter (the name map that is) seems something special
698 // to MSVC and so we use a other name.
699 void wxClassInfo
::GetProperties( wxPropertyInfoMap
&infomap
) const
701 const wxPropertyInfo
*pi
= GetFirstProperty();
704 if ( infomap
.find( pi
->GetName() ) == infomap
.end() )
705 infomap
[pi
->GetName()] = (wxPropertyInfo
*) pi
;
710 const wxClassInfo
** parents
= GetParents();
711 for ( int i
= 0; parents
[i
]; ++ i
)
713 parents
[i
]->GetProperties( infomap
);
717 wxObject
* wxClassInfo
::AnyToObjectPtr( const wxAny
&data
) const
719 return m_variantOfPtrToObjectConverter(data
);
722 void wxClassInfo
::CallOnAny( const wxAny
&data
, wxObjectFunctor
* functor
) const
724 if ( data
.GetTypeInfo()->GetKind() == wxT_OBJECT
)
725 return m_variantToObjectConverter(data
, functor
);
727 return (*functor
)(m_variantOfPtrToObjectConverter(data
));
730 wxAny wxClassInfo
::ObjectPtrToAny( wxObject
* obj
) const
732 return m_objectToVariantConverter(obj
);
735 bool wxClassInfo
::NeedsDirectConstruction() const
737 return wx_dynamic_cast(wxObjectAllocator
*, m_constructor
) != NULL
;
740 // ----------------------------------------------------------------------------
741 // wxDynamicObject support
742 // ----------------------------------------------------------------------------
744 // Dynamic Objects are objects that have a real superclass instance and carry their
745 // own attributes in a hash map. Like this it is possible to create the objects and
746 // stream them, as if their class information was already available from compiled data
748 struct wxDynamicObject
::wxDynamicObjectInternal
750 wxDynamicObjectInternal() {}
752 wxStringToAnyHashMap m_properties
;
755 typedef list
< wxDynamicObject
* > wxDynamicObjectList
;
757 struct wxDynamicClassInfo
::wxDynamicClassInfoInternal
759 wxDynamicObjectList m_dynamicObjects
;
762 // instantiates this object with an instance of its superclass
763 wxDynamicObject
::wxDynamicObject(wxObject
* superClassInstance
, const wxDynamicClassInfo
*info
)
765 m_superClassInstance
= superClassInstance
;
767 m_data
= new wxDynamicObjectInternal
;
770 wxDynamicObject
::~wxDynamicObject()
772 wx_dynamic_cast(const wxDynamicClassInfo
*, m_classInfo
)->
773 m_data
->m_dynamicObjects
.remove( this );
775 delete m_superClassInstance
;
778 void wxDynamicObject
::SetProperty (const wxChar
*propertyName
, const wxAny
&value
)
780 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(propertyName
),
781 wxT("Accessing Unknown Property in a Dynamic Object") );
782 m_data
->m_properties
[propertyName
] = value
;
785 wxAny wxDynamicObject
::GetProperty (const wxChar
*propertyName
) const
787 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(propertyName
),
788 wxT("Accessing Unknown Property in a Dynamic Object") );
789 return m_data
->m_properties
[propertyName
];
792 void wxDynamicObject
::RemoveProperty( const wxChar
*propertyName
)
794 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(propertyName
),
795 wxT("Removing Unknown Property in a Dynamic Object") );
796 m_data
->m_properties
.erase( propertyName
);
799 void wxDynamicObject
::RenameProperty( const wxChar
*oldPropertyName
,
800 const wxChar
*newPropertyName
)
802 wxASSERT_MSG(m_classInfo
->FindPropertyInfoInThisClass(oldPropertyName
),
803 wxT("Renaming Unknown Property in a Dynamic Object") );
805 wxAny value
= m_data
->m_properties
[oldPropertyName
];
806 m_data
->m_properties
.erase( oldPropertyName
);
807 m_data
->m_properties
[newPropertyName
] = value
;
811 // ----------------------------------------------------------------------------
812 // wxDynamicClassInfo
813 // ----------------------------------------------------------------------------
815 wxDynamicClassInfo
::wxDynamicClassInfo( const wxChar
*unitName
,
816 const wxChar
*className
,
817 const wxClassInfo
* superClass
) :
818 wxClassInfo( unitName
, className
, new const wxClassInfo
*[2])
820 GetParents()[0] = superClass
;
821 GetParents()[1] = NULL
;
822 m_data
= new wxDynamicClassInfoInternal
;
825 wxDynamicClassInfo
::~wxDynamicClassInfo()
827 delete[] GetParents();
831 wxObject
*wxDynamicClassInfo
::AllocateObject() const
833 wxObject
* parent
= GetParents()[0]->AllocateObject();
834 wxDynamicObject
*obj
= new wxDynamicObject( parent
, this );
835 m_data
->m_dynamicObjects
.push_back( obj
);
839 bool wxDynamicClassInfo
::Create (wxObject
*object
, int paramCount
, wxAny
*params
) const
841 wxDynamicObject
*dynobj
= wx_dynamic_cast( wxDynamicObject
*, object
);
842 wxASSERT_MSG( dynobj
,
843 wxT("cannot call wxDynamicClassInfo::Create on ")
844 wxT("an object other than wxDynamicObject") );
846 return GetParents()[0]->Create( dynobj
->GetSuperClassInstance(), paramCount
, params
);
849 // get number of parameters for constructor
850 int wxDynamicClassInfo
::GetCreateParamCount() const
852 return GetParents()[0]->GetCreateParamCount();
855 // get i-th constructor parameter
856 const wxChar
* wxDynamicClassInfo
::GetCreateParamName(int i
) const
858 return GetParents()[0]->GetCreateParamName( i
);
861 void wxDynamicClassInfo
::SetProperty(wxObject
*object
, const wxChar
*propertyName
, const wxAny
&value
) const
863 wxDynamicObject
* dynobj
= wx_dynamic_cast(wxDynamicObject
*, object
);
864 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
865 if ( FindPropertyInfoInThisClass(propertyName
) )
866 dynobj
->SetProperty( propertyName
, value
);
868 GetParents()[0]->SetProperty( dynobj
->GetSuperClassInstance(), propertyName
, value
);
871 wxAny wxDynamicClassInfo
::GetProperty(wxObject
*object
, const wxChar
*propertyName
) const
873 wxDynamicObject
* dynobj
= wx_dynamic_cast(wxDynamicObject
*, object
);
874 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
875 if ( FindPropertyInfoInThisClass(propertyName
) )
876 return dynobj
->GetProperty( propertyName
);
878 return GetParents()[0]->GetProperty( dynobj
->GetSuperClassInstance(), propertyName
);
881 void wxDynamicClassInfo
::AddProperty( const wxChar
*propertyName
, const wxTypeInfo
* typeInfo
)
884 new wxPropertyInfo( m_firstProperty
, this, propertyName
, typeInfo
->GetTypeName(), new wxGenericPropertyAccessor( propertyName
), wxAny() );
887 void wxDynamicClassInfo
::AddHandler( const wxChar
*handlerName
, wxObjectEventFunction address
, const wxClassInfo
* eventClassInfo
)
890 new wxHandlerInfo( m_firstHandler
, this, handlerName
, address
, eventClassInfo
);
893 // removes an existing runtime-property
894 void wxDynamicClassInfo
::RemoveProperty( const wxChar
*propertyName
)
896 for ( wxDynamicObjectList
::iterator iter
= m_data
->m_dynamicObjects
.begin(); iter
!= m_data
->m_dynamicObjects
.end(); ++iter
)
897 (*iter
)->RemoveProperty( propertyName
);
898 delete FindPropertyInfoInThisClass(propertyName
);
901 // removes an existing runtime-handler
902 void wxDynamicClassInfo
::RemoveHandler( const wxChar
*handlerName
)
904 delete FindHandlerInfoInThisClass(handlerName
);
907 // renames an existing runtime-property
908 void wxDynamicClassInfo
::RenameProperty( const wxChar
*oldPropertyName
, const wxChar
*newPropertyName
)
910 wxPropertyInfo
* pi
= FindPropertyInfoInThisClass(oldPropertyName
);
911 wxASSERT_MSG( pi
,wxT("not existing property") );
912 pi
->m_name
= newPropertyName
;
913 wx_dynamic_cast(wxGenericPropertyAccessor
*, pi
->GetAccessor())->RenameProperty( oldPropertyName
, newPropertyName
);
914 for ( wxDynamicObjectList
::iterator iter
= m_data
->m_dynamicObjects
.begin(); iter
!= m_data
->m_dynamicObjects
.end(); ++iter
)
915 (*iter
)->RenameProperty( oldPropertyName
, newPropertyName
);
918 // renames an existing runtime-handler
919 void wxDynamicClassInfo
::RenameHandler( const wxChar
*oldHandlerName
, const wxChar
*newHandlerName
)
921 wxASSERT_MSG(FindHandlerInfoInThisClass(oldHandlerName
),wxT("not existing handler") );
922 FindHandlerInfoInThisClass(oldHandlerName
)->m_name
= newHandlerName
;
925 // ----------------------------------------------------------------------------
926 // wxGenericPropertyAccessor
927 // ----------------------------------------------------------------------------
929 struct wxGenericPropertyAccessor
::wxGenericPropertyAccessorInternal
934 wxGenericPropertyAccessor
::wxGenericPropertyAccessor( const wxString
& propertyName
)
935 : wxPropertyAccessor( NULL
, NULL
, NULL
, NULL
)
937 m_data
= new wxGenericPropertyAccessorInternal
;
938 m_propertyName
= propertyName
;
939 m_getterName
= wxT("Get")+propertyName
;
940 m_setterName
= wxT("Set")+propertyName
;
943 wxGenericPropertyAccessor
::~wxGenericPropertyAccessor()
948 void wxGenericPropertyAccessor
::SetProperty(wxObject
*object
, const wxAny
&value
) const
950 wxDynamicObject
* dynobj
= wx_dynamic_cast(wxDynamicObject
*, object
);
951 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
952 dynobj
->SetProperty(m_propertyName
, value
);
955 void wxGenericPropertyAccessor
::GetProperty(const wxObject
*object
, wxAny
& value
) const
957 const wxDynamicObject
* dynobj
= wx_dynamic_cast( const wxDynamicObject
* , object
);
958 wxASSERT_MSG( dynobj
, wxT("cannot call wxDynamicClassInfo::SetProperty on an object other than wxDynamicObject") );
959 value
= dynobj
->GetProperty( m_propertyName
);
962 // ----------------------------------------------------------------------------
963 // wxGenericPropertyAccessor
964 // ----------------------------------------------------------------------------
966 wxString
wxAnyGetAsString( const wxAny
& data
)
968 if ( data
.IsNull() || data
.GetTypeInfo()==NULL
)
969 return wxEmptyString
;
972 data
.GetTypeInfo()->ConvertToString(data
,s
);
976 const wxObject
* wxAnyGetAsObjectPtr( const wxAny
& data
)
978 if ( !data
.IsNull() )
980 const wxClassTypeInfo
* ti
= wx_dynamic_cast(const wxClassTypeInfo
*, data
.GetTypeInfo());
982 return ti
->GetClassInfo()->AnyToObjectPtr(data
);
987 wxObjectFunctor
::~wxObjectFunctor()
990 #endif // wxUSE_EXTENDED_RTTI