1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: runtime metadata information (extended class info)
4 // Author: Stefan Csomor
5 // Modified by: Francesco Montorsi
8 // Copyright: (c) 1997 Julian Smart
9 // (c) 2003 Stefan Csomor
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
16 // We want to support properties, event sources and events sinks through
17 // explicit declarations, using templates and specialization to make the
18 // effort as painless as possible.
20 // This means we have the following domains :
22 // - Type Information for categorizing built in types as well as custom types
23 // this includes information about enums, their values and names
24 // - Type safe value storage : a kind of wxVariant, called right now wxAny
25 // which will be merged with wxVariant
26 // - Property Information and Property Accessors providing access to a class'
27 // values and exposed event delegates
28 // - Information about event handlers
29 // - extended Class Information for accessing all these
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
37 #if wxUSE_EXTENDED_RTTI
39 class WXDLLIMPEXP_FWD_BASE wxAny
;
40 class WXDLLIMPEXP_FWD_BASE wxAnyList
;
41 class WXDLLIMPEXP_FWD_BASE wxObject
;
42 class WXDLLIMPEXP_FWD_BASE wxString
;
43 class WXDLLIMPEXP_FWD_BASE wxClassInfo
;
44 class WXDLLIMPEXP_FWD_BASE wxHashTable
;
45 class WXDLLIMPEXP_FWD_BASE wxObject
;
46 class WXDLLIMPEXP_FWD_BASE wxPluginLibrary
;
47 class WXDLLIMPEXP_FWD_BASE wxHashTable
;
48 class WXDLLIMPEXP_FWD_BASE wxHashTable_Node
;
50 class WXDLLIMPEXP_FWD_BASE wxStringToAnyHashMap
;
51 class WXDLLIMPEXP_FWD_BASE wxPropertyInfoMap
;
52 class WXDLLIMPEXP_FWD_BASE wxPropertyAccessor
;
54 #define wx_dynamic_cast(t, x) dynamic_cast<t>(x)
56 #include "wx/xtitypes.h"
57 #include "wx/xtictor.h"
58 #include "wx/xtihandler.h"
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 class WXDLLIMPEXP_BASE wxObjectFunctor
67 virtual ~wxObjectFunctor();
69 // Invoke the actual event handler:
70 virtual void operator()(const wxObject
*) = 0;
73 class WXDLLIMPEXP_FWD_BASE wxPropertyInfo
;
74 class WXDLLIMPEXP_FWD_BASE wxHandlerInfo
;
76 typedef wxObject
*(*wxObjectConstructorFn
)(void);
77 typedef wxPropertyInfo
*(*wxPropertyInfoFn
)(void);
78 typedef wxHandlerInfo
*(*wxHandlerInfoFn
)(void);
79 typedef void (*wxVariantToObjectConverter
)( const wxAny
&data
, wxObjectFunctor
* fn
);
80 typedef wxObject
* (*wxVariantToObjectPtrConverter
) ( const wxAny
& data
);
81 typedef wxAny (*wxObjectToVariantConverter
)( wxObject
* );
83 WXDLLIMPEXP_BASE wxString
wxAnyGetAsString( const wxAny
& data
);
84 WXDLLIMPEXP_BASE
const wxObject
* wxAnyGetAsObjectPtr( const wxAny
& data
);
86 class WXDLLIMPEXP_BASE wxObjectWriter
;
87 class WXDLLIMPEXP_BASE wxObjectWriterCallback
;
89 typedef bool (*wxObjectStreamingCallback
) ( const wxObject
*, wxObjectWriter
*, \
90 wxObjectWriterCallback
*, const wxStringToAnyHashMap
& );
94 class WXDLLIMPEXP_BASE wxClassInfo
96 friend class WXDLLIMPEXP_BASE wxPropertyInfo
;
97 friend class WXDLLIMPEXP_BASE wxHandlerInfo
;
98 friend wxObject
*wxCreateDynamicObject(const wxString
& name
);
101 wxClassInfo(const wxClassInfo
**_Parents
,
102 const wxChar
*_UnitName
,
103 const wxChar
*_ClassName
,
105 wxObjectConstructorFn ctor
,
106 wxPropertyInfoFn _Props
,
107 wxHandlerInfoFn _Handlers
,
108 wxObjectAllocatorAndCreator
* _Constructor
,
109 const wxChar
** _ConstructorProperties
,
110 const int _ConstructorPropertiesCount
,
111 wxVariantToObjectPtrConverter _PtrConverter1
,
112 wxVariantToObjectConverter _Converter2
,
113 wxObjectToVariantConverter _Converter3
,
114 wxObjectStreamingCallback _streamingCallback
= NULL
) :
115 m_className(_ClassName
),
117 m_objectConstructor(ctor
),
119 m_firstPropertyFn(_Props
),
120 m_firstHandlerFn(_Handlers
),
121 m_firstProperty(NULL
),
122 m_firstHandler(NULL
),
123 m_firstInited(false),
125 m_unitName(_UnitName
),
126 m_constructor(_Constructor
),
127 m_constructorProperties(_ConstructorProperties
),
128 m_constructorPropertiesCount(_ConstructorPropertiesCount
),
129 m_variantOfPtrToObjectConverter(_PtrConverter1
),
130 m_variantToObjectConverter(_Converter2
),
131 m_objectToVariantConverter(_Converter3
),
132 m_streamingCallback(_streamingCallback
)
138 wxClassInfo(const wxChar
*_UnitName
, const wxChar
*_ClassName
,
139 const wxClassInfo
**_Parents
) :
140 m_className(_ClassName
),
142 m_objectConstructor(NULL
),
144 m_firstPropertyFn(NULL
),
145 m_firstHandlerFn(NULL
),
146 m_firstProperty(NULL
),
147 m_firstHandler(NULL
),
150 m_unitName(_UnitName
),
152 m_constructorProperties(NULL
),
153 m_constructorPropertiesCount(0),
154 m_variantOfPtrToObjectConverter(NULL
),
155 m_variantToObjectConverter(NULL
),
156 m_objectToVariantConverter(NULL
),
157 m_streamingCallback(NULL
)
163 // ctor compatible with old RTTI system
164 wxClassInfo(const wxChar
*_ClassName
,
165 const wxClassInfo
*_Parent1
,
166 const wxClassInfo
*_Parent2
,
168 wxObjectConstructorFn ctor
) :
169 m_className(_ClassName
),
171 m_objectConstructor(ctor
),
173 m_firstPropertyFn(NULL
),
174 m_firstHandlerFn(NULL
),
175 m_firstProperty(NULL
),
176 m_firstHandler(NULL
),
181 m_constructorProperties(NULL
),
182 m_constructorPropertiesCount(0),
183 m_variantOfPtrToObjectConverter(NULL
),
184 m_variantToObjectConverter(NULL
),
185 m_objectToVariantConverter(NULL
),
186 m_streamingCallback(NULL
)
189 m_parents
[0] = _Parent1
;
190 m_parents
[1] = _Parent2
;
195 virtual ~wxClassInfo();
197 // allocates an instance of this class, this object does not have to be
198 // initialized or fully constructed as this call will be followed by a call to Create
199 virtual wxObject
*AllocateObject() const
200 { return m_objectConstructor
? (*m_objectConstructor
)() : 0; }
202 // 'old naming' for AllocateObject staying here for backward compatibility
203 wxObject
*CreateObject() const { return AllocateObject(); }
205 // direct construction call for classes that cannot construct instances via alloc/create
206 wxObject
*ConstructObject(int ParamCount
, wxAny
*Params
) const;
208 bool NeedsDirectConstruction() const
209 { return wx_dynamic_cast(wxObjectAllocator
*, m_constructor
) != NULL
; }
211 const wxChar
*GetClassName() const
212 { return m_className
; }
213 const wxChar
*GetBaseClassName1() const
214 { return m_parents
[0] ? m_parents
[0]->GetClassName() : NULL
; }
215 const wxChar
*GetBaseClassName2() const
216 { return (m_parents
[0] && m_parents
[1]) ? m_parents
[1]->GetClassName() : NULL
; }
218 const wxClassInfo
*GetBaseClass1() const
219 { return m_parents
[0]; }
220 const wxClassInfo
*GetBaseClass2() const
221 { return m_parents
[0] ? m_parents
[1] : NULL
; }
223 const wxChar
*GetIncludeName() const
224 { return m_unitName
; }
225 const wxClassInfo
**GetParents() const
226 { return m_parents
; }
228 { return m_objectSize
; }
229 bool IsDynamic() const
230 { return (NULL
!= m_objectConstructor
); }
232 wxObjectConstructorFn
GetConstructor() const
233 { return m_objectConstructor
; }
234 const wxClassInfo
*GetNext() const
239 static void CleanUp();
240 static wxClassInfo
*FindClass(const wxString
& className
);
241 static const wxClassInfo
*GetFirst()
245 // Climb upwards through inheritance hierarchy.
246 // Dual inheritance is catered for.
248 bool IsKindOf(const wxClassInfo
*info
) const;
250 wxDECLARE_CLASS_INFO_ITERATORS();
252 // if there is a callback registered with that class it will be called
253 // before this object will be written to disk, it can veto streaming out
254 // this object by returning false, if this class has not registered a
255 // callback, the search will go up the inheritance tree if no callback has
256 // been registered true will be returned by default
257 bool BeforeWriteObject( const wxObject
*obj
, wxObjectWriter
*streamer
,
258 wxObjectWriterCallback
*writercallback
, const wxStringToAnyHashMap
&metadata
) const;
260 // gets the streaming callback from this class or any superclass
261 wxObjectStreamingCallback
GetStreamingCallback() const;
263 // returns the first property
264 wxPropertyInfo
* GetFirstProperty() const
265 { EnsureInfosInited(); return m_firstProperty
; }
267 // returns the first handler
268 wxHandlerInfo
* GetFirstHandler() const
269 { EnsureInfosInited(); return m_firstHandler
; }
271 // Call the Create upon an instance of the class, in the end the object is fully
273 virtual bool Create (wxObject
*object
, int ParamCount
, wxAny
*Params
) const;
275 // get number of parameters for constructor
276 virtual int GetCreateParamCount() const
277 { return m_constructorPropertiesCount
; }
279 // get n-th constructor parameter
280 virtual const wxChar
* GetCreateParamName(int n
) const
281 { return m_constructorProperties
[n
]; }
283 // Runtime access to objects for simple properties (get/set) by property
284 // name and variant data
285 virtual void SetProperty (wxObject
*object
, const wxChar
*propertyName
,
286 const wxAny
&value
) const;
287 virtual wxAny
GetProperty (wxObject
*object
, const wxChar
*propertyName
) const;
289 // Runtime access to objects for collection properties by property name
290 virtual wxAnyList
GetPropertyCollection(wxObject
*object
,
291 const wxChar
*propertyName
) const;
292 virtual void AddToPropertyCollection(wxObject
*object
, const wxChar
*propertyName
,
293 const wxAny
& value
) const;
295 // we must be able to cast variants to wxObject pointers, templates seem
296 // not to be suitable
297 void CallOnAny( const wxAny
&data
, wxObjectFunctor
* functor
) const;
299 wxObject
* AnyToObjectPtr( const wxAny
&data
) const;
301 wxAny
ObjectPtrToAny( wxObject
*object
) const;
303 // find property by name
304 virtual const wxPropertyInfo
*FindPropertyInfo (const wxChar
*PropertyName
) const;
306 // find handler by name
307 virtual const wxHandlerInfo
*FindHandlerInfo (const wxChar
*handlerName
) const;
309 // find property by name
310 virtual wxPropertyInfo
*FindPropertyInfoInThisClass (const wxChar
*PropertyName
) const;
312 // find handler by name
313 virtual wxHandlerInfo
*FindHandlerInfoInThisClass (const wxChar
*handlerName
) const;
315 // puts all the properties of this class and its superclasses in the map,
316 // as long as there is not yet an entry with the same name (overriding mechanism)
317 void GetProperties( wxPropertyInfoMap
&map
) const;
320 const wxChar
*m_className
;
322 wxObjectConstructorFn m_objectConstructor
;
324 // class info object live in a linked list:
325 // pointers to its head and the next element in it
327 static wxClassInfo
*sm_first
;
330 static wxHashTable
*sm_classTable
;
332 wxPropertyInfoFn m_firstPropertyFn
;
333 wxHandlerInfoFn m_firstHandlerFn
;
335 mutable bool m_firstInited
;
338 void EnsureInfosInited() const
342 if ( m_firstPropertyFn
!= NULL
)
343 m_firstProperty
= (*m_firstPropertyFn
)();
344 if ( m_firstHandlerFn
!= NULL
)
345 m_firstHandler
= (*m_firstHandlerFn
)();
346 m_firstInited
= true;
349 mutable wxPropertyInfo
* m_firstProperty
;
350 mutable wxHandlerInfo
* m_firstHandler
;
353 const wxClassInfo
** m_parents
;
354 const wxChar
* m_unitName
;
356 wxObjectAllocatorAndCreator
* m_constructor
;
357 const wxChar
** m_constructorProperties
;
358 const int m_constructorPropertiesCount
;
359 wxVariantToObjectPtrConverter m_variantOfPtrToObjectConverter
;
360 wxVariantToObjectConverter m_variantToObjectConverter
;
361 wxObjectToVariantConverter m_objectToVariantConverter
;
362 wxObjectStreamingCallback m_streamingCallback
;
364 const wxPropertyAccessor
*FindAccessor (const wxChar
*propertyName
) const;
367 // registers the class
371 DECLARE_NO_COPY_CLASS(wxClassInfo
)
374 WXDLLIMPEXP_BASE wxObject
*wxCreateDynamicObject(const wxString
& name
);
376 // ----------------------------------------------------------------------------
377 // wxDynamicClassInfo
378 // ----------------------------------------------------------------------------
380 // this object leads to having a pure runtime-instantiation
382 class WXDLLIMPEXP_BASE wxDynamicClassInfo
: public wxClassInfo
384 friend class WXDLLIMPEXP_BASE wxDynamicObject
;
387 wxDynamicClassInfo( const wxChar
*_UnitName
, const wxChar
*_ClassName
,
388 const wxClassInfo
* superClass
);
389 virtual ~wxDynamicClassInfo();
391 // constructs a wxDynamicObject with an instance
392 virtual wxObject
*AllocateObject() const;
394 // Call the Create method for a class
395 virtual bool Create (wxObject
*object
, int ParamCount
, wxAny
*Params
) const;
397 // get number of parameters for constructor
398 virtual int GetCreateParamCount() const;
400 // get i-th constructor parameter
401 virtual const wxChar
* GetCreateParamName(int i
) const;
403 // Runtime access to objects by property name, and variant data
404 virtual void SetProperty (wxObject
*object
, const wxChar
*PropertyName
,
405 const wxAny
&Value
) const;
406 virtual wxAny
GetProperty (wxObject
*object
, const wxChar
*PropertyName
) const;
408 // adds a property to this class at runtime
409 void AddProperty( const wxChar
*propertyName
, const wxTypeInfo
* typeInfo
);
411 // removes an existing runtime-property
412 void RemoveProperty( const wxChar
*propertyName
);
414 // renames an existing runtime-property
415 void RenameProperty( const wxChar
*oldPropertyName
, const wxChar
*newPropertyName
);
417 // as a handler to this class at runtime
418 void AddHandler( const wxChar
*handlerName
, wxObjectEventFunction address
,
419 const wxClassInfo
* eventClassInfo
);
421 // removes an existing runtime-handler
422 void RemoveHandler( const wxChar
*handlerName
);
424 // renames an existing runtime-handler
425 void RenameHandler( const wxChar
*oldHandlerName
, const wxChar
*newHandlerName
);
428 struct wxDynamicClassInfoInternal
;
429 wxDynamicClassInfoInternal
* m_data
;
432 // ----------------------------------------------------------------------------
433 // wxDECLARE class macros
434 // ----------------------------------------------------------------------------
436 #define _DECLARE_DYNAMIC_CLASS(name) \
438 static wxClassInfo ms_classInfo; \
439 static const wxClassInfo* ms_classParents[]; \
440 static wxPropertyInfo* GetPropertiesStatic(); \
441 static wxHandlerInfo* GetHandlersStatic(); \
442 static wxClassInfo *GetClassInfoStatic() \
443 { return &name::ms_classInfo; } \
444 virtual wxClassInfo *GetClassInfo() const \
445 { return &name::ms_classInfo; }
447 #define wxDECLARE_DYNAMIC_CLASS(name) \
448 static wxObjectAllocatorAndCreator* ms_constructor; \
449 static const wxChar * ms_constructorProperties[]; \
450 static const int ms_constructorPropertiesCount; \
451 _DECLARE_DYNAMIC_CLASS(name)
453 #define wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(name) \
454 wxDECLARE_NO_ASSIGN_CLASS(name); \
455 wxDECLARE_DYNAMIC_CLASS(name)
457 #define wxDECLARE_DYNAMIC_CLASS_NO_COPY(name) \
458 wxDECLARE_NO_COPY_CLASS(name); \
459 wxDECLARE_DYNAMIC_CLASS(name)
461 #define wxDECLARE_CLASS(name) \
462 wxDECLARE_DYNAMIC_CLASS(name)
464 #define wxDECLARE_ABSTRACT_CLASS(name) _DECLARE_DYNAMIC_CLASS(name)
465 #define wxCLASSINFO(name) (&name::ms_classInfo)
467 // --------------------------------------------------------------------------
468 // Collection Support
469 // --------------------------------------------------------------------------
471 template<typename iter
, typename collection_t
> void wxListCollectionToAnyList(
472 const collection_t
& coll
, wxAnyList
&value
)
474 for ( collection_t::compatibility_iterator current
= coll
.GetFirst(); current
;
475 current
= current
->GetNext() )
477 value
.Append( new wxAny(current
->GetData()) );
481 template<typename collection_t
> void wxArrayCollectionToVariantArray(
482 const collection_t
& coll
, wxAnyList
&value
)
484 for( size_t i
= 0; i
< coll
.GetCount(); i
++ )
486 value
.Append( new wxAny(coll
[i
]) );
490 #endif // wxUSE_EXTENDED_RTTI