]> git.saurik.com Git - wxWidgets.git/blob - include/wx/xti.h
using Run of base class
[wxWidgets.git] / include / wx / xti.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/xti.h
3 // Purpose: runtime metadata information (extended class info)
4 // Author: Stefan Csomor
5 // Modified by: Francesco Montorsi
6 // Created: 27/07/03
7 // Copyright: (c) 1997 Julian Smart
8 // (c) 2003 Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_XTIH__
13 #define _WX_XTIH__
14
15 // We want to support properties, event sources and events sinks through
16 // explicit declarations, using templates and specialization to make the
17 // effort as painless as possible.
18 //
19 // This means we have the following domains :
20 //
21 // - Type Information for categorizing built in types as well as custom types
22 // this includes information about enums, their values and names
23 // - Type safe value storage : a kind of wxVariant, called right now wxAny
24 // which will be merged with wxVariant
25 // - Property Information and Property Accessors providing access to a class'
26 // values and exposed event delegates
27 // - Information about event handlers
28 // - extended Class Information for accessing all these
29
30 // ----------------------------------------------------------------------------
31 // headers
32 // ----------------------------------------------------------------------------
33
34 #include "wx/defs.h"
35
36 #if wxUSE_EXTENDED_RTTI
37
38 class WXDLLIMPEXP_FWD_BASE wxAny;
39 class WXDLLIMPEXP_FWD_BASE wxAnyList;
40 class WXDLLIMPEXP_FWD_BASE wxObject;
41 class WXDLLIMPEXP_FWD_BASE wxString;
42 class WXDLLIMPEXP_FWD_BASE wxClassInfo;
43 class WXDLLIMPEXP_FWD_BASE wxHashTable;
44 class WXDLLIMPEXP_FWD_BASE wxObject;
45 class WXDLLIMPEXP_FWD_BASE wxPluginLibrary;
46 class WXDLLIMPEXP_FWD_BASE wxHashTable;
47 class WXDLLIMPEXP_FWD_BASE wxHashTable_Node;
48
49 class WXDLLIMPEXP_FWD_BASE wxStringToAnyHashMap;
50 class WXDLLIMPEXP_FWD_BASE wxPropertyInfoMap;
51 class WXDLLIMPEXP_FWD_BASE wxPropertyAccessor;
52 class WXDLLIMPEXP_FWD_BASE wxObjectAllocatorAndCreator;
53 class WXDLLIMPEXP_FWD_BASE wxObjectAllocator;
54
55
56 #define wx_dynamic_cast(t, x) dynamic_cast<t>(x)
57
58 #include "wx/xtitypes.h"
59 #include "wx/xtihandler.h"
60
61 // ----------------------------------------------------------------------------
62 // wxClassInfo
63 // ----------------------------------------------------------------------------
64
65 class WXDLLIMPEXP_BASE wxObjectFunctor
66 {
67 public:
68 virtual ~wxObjectFunctor();
69
70 // Invoke the actual event handler:
71 virtual void operator()(const wxObject *) = 0;
72 };
73
74 class WXDLLIMPEXP_FWD_BASE wxPropertyInfo;
75 class WXDLLIMPEXP_FWD_BASE wxHandlerInfo;
76
77 typedef wxObject *(*wxObjectConstructorFn)(void);
78 typedef wxPropertyInfo *(*wxPropertyInfoFn)(void);
79 typedef wxHandlerInfo *(*wxHandlerInfoFn)(void);
80 typedef void (*wxVariantToObjectConverter)( const wxAny &data, wxObjectFunctor* fn );
81 typedef wxObject* (*wxVariantToObjectPtrConverter) ( const wxAny& data);
82 typedef wxAny (*wxObjectToVariantConverter)( wxObject* );
83
84 WXDLLIMPEXP_BASE wxString wxAnyGetAsString( const wxAny& data);
85 WXDLLIMPEXP_BASE const wxObject* wxAnyGetAsObjectPtr( const wxAny& data);
86
87 class WXDLLIMPEXP_BASE wxObjectWriter;
88 class WXDLLIMPEXP_BASE wxObjectWriterCallback;
89
90 typedef bool (*wxObjectStreamingCallback) ( const wxObject *, wxObjectWriter *, \
91 wxObjectWriterCallback *, const wxStringToAnyHashMap & );
92
93
94
95 class WXDLLIMPEXP_BASE wxClassInfo
96 {
97 friend class WXDLLIMPEXP_BASE wxPropertyInfo;
98 friend class /* WXDLLIMPEXP_BASE */ wxHandlerInfo;
99 friend wxObject *wxCreateDynamicObject(const wxString& name);
100
101 public:
102 wxClassInfo(const wxClassInfo **_Parents,
103 const wxChar *_UnitName,
104 const wxChar *_ClassName,
105 int size,
106 wxObjectConstructorFn ctor,
107 wxPropertyInfoFn _Props,
108 wxHandlerInfoFn _Handlers,
109 wxObjectAllocatorAndCreator* _Constructor,
110 const wxChar ** _ConstructorProperties,
111 const int _ConstructorPropertiesCount,
112 wxVariantToObjectPtrConverter _PtrConverter1,
113 wxVariantToObjectConverter _Converter2,
114 wxObjectToVariantConverter _Converter3,
115 wxObjectStreamingCallback _streamingCallback = NULL) :
116 m_className(_ClassName),
117 m_objectSize(size),
118 m_objectConstructor(ctor),
119 m_next(sm_first),
120 m_firstPropertyFn(_Props),
121 m_firstHandlerFn(_Handlers),
122 m_firstProperty(NULL),
123 m_firstHandler(NULL),
124 m_firstInited(false),
125 m_parents(_Parents),
126 m_unitName(_UnitName),
127 m_constructor(_Constructor),
128 m_constructorProperties(_ConstructorProperties),
129 m_constructorPropertiesCount(_ConstructorPropertiesCount),
130 m_variantOfPtrToObjectConverter(_PtrConverter1),
131 m_variantToObjectConverter(_Converter2),
132 m_objectToVariantConverter(_Converter3),
133 m_streamingCallback(_streamingCallback)
134 {
135 sm_first = this;
136 Register();
137 }
138
139 wxClassInfo(const wxChar *_UnitName, const wxChar *_ClassName,
140 const wxClassInfo **_Parents) :
141 m_className(_ClassName),
142 m_objectSize(0),
143 m_objectConstructor(NULL),
144 m_next(sm_first),
145 m_firstPropertyFn(NULL),
146 m_firstHandlerFn(NULL),
147 m_firstProperty(NULL),
148 m_firstHandler(NULL),
149 m_firstInited(true),
150 m_parents(_Parents),
151 m_unitName(_UnitName),
152 m_constructor(NULL),
153 m_constructorProperties(NULL),
154 m_constructorPropertiesCount(0),
155 m_variantOfPtrToObjectConverter(NULL),
156 m_variantToObjectConverter(NULL),
157 m_objectToVariantConverter(NULL),
158 m_streamingCallback(NULL)
159 {
160 sm_first = this;
161 Register();
162 }
163
164 // ctor compatible with old RTTI system
165 wxClassInfo(const wxChar *_ClassName,
166 const wxClassInfo *_Parent1,
167 const wxClassInfo *_Parent2,
168 int size,
169 wxObjectConstructorFn ctor) :
170 m_className(_ClassName),
171 m_objectSize(size),
172 m_objectConstructor(ctor),
173 m_next(sm_first),
174 m_firstPropertyFn(NULL),
175 m_firstHandlerFn(NULL),
176 m_firstProperty(NULL),
177 m_firstHandler(NULL),
178 m_firstInited(true),
179 m_parents(NULL),
180 m_unitName(NULL),
181 m_constructor(NULL),
182 m_constructorProperties(NULL),
183 m_constructorPropertiesCount(0),
184 m_variantOfPtrToObjectConverter(NULL),
185 m_variantToObjectConverter(NULL),
186 m_objectToVariantConverter(NULL),
187 m_streamingCallback(NULL)
188 {
189 sm_first = this;
190 m_parents[0] = _Parent1;
191 m_parents[1] = _Parent2;
192 m_parents[2] = NULL;
193 Register();
194 }
195
196 virtual ~wxClassInfo();
197
198 // allocates an instance of this class, this object does not have to be
199 // initialized or fully constructed as this call will be followed by a call to Create
200 virtual wxObject *AllocateObject() const
201 { return m_objectConstructor ? (*m_objectConstructor)() : 0; }
202
203 // 'old naming' for AllocateObject staying here for backward compatibility
204 wxObject *CreateObject() const { return AllocateObject(); }
205
206 // direct construction call for classes that cannot construct instances via alloc/create
207 wxObject *ConstructObject(int ParamCount, wxAny *Params) const;
208
209 bool NeedsDirectConstruction() const;
210
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; }
217
218 const wxClassInfo *GetBaseClass1() const
219 { return m_parents[0]; }
220 const wxClassInfo *GetBaseClass2() const
221 { return m_parents[0] ? m_parents[1] : NULL; }
222
223 const wxChar *GetIncludeName() const
224 { return m_unitName; }
225 const wxClassInfo **GetParents() const
226 { return m_parents; }
227 int GetSize() const
228 { return m_objectSize; }
229 bool IsDynamic() const
230 { return (NULL != m_objectConstructor); }
231
232 wxObjectConstructorFn GetConstructor() const
233 { return m_objectConstructor; }
234 const wxClassInfo *GetNext() const
235 { return m_next; }
236
237 // statics:
238
239 static void CleanUp();
240 static wxClassInfo *FindClass(const wxString& className);
241 static const wxClassInfo *GetFirst()
242 { return sm_first; }
243
244
245 // Climb upwards through inheritance hierarchy.
246 // Dual inheritance is catered for.
247
248 bool IsKindOf(const wxClassInfo *info) const;
249
250 wxDECLARE_CLASS_INFO_ITERATORS();
251
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;
259
260 // gets the streaming callback from this class or any superclass
261 wxObjectStreamingCallback GetStreamingCallback() const;
262
263 // returns the first property
264 wxPropertyInfo* GetFirstProperty() const
265 { EnsureInfosInited(); return m_firstProperty; }
266
267 // returns the first handler
268 wxHandlerInfo* GetFirstHandler() const
269 { EnsureInfosInited(); return m_firstHandler; }
270
271 // Call the Create upon an instance of the class, in the end the object is fully
272 // initialized
273 virtual bool Create (wxObject *object, int ParamCount, wxAny *Params) const;
274
275 // get number of parameters for constructor
276 virtual int GetCreateParamCount() const
277 { return m_constructorPropertiesCount; }
278
279 // get n-th constructor parameter
280 virtual const wxChar* GetCreateParamName(int n) const
281 { return m_constructorProperties[n]; }
282
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;
288
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;
294
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;
298
299 wxObject* AnyToObjectPtr( const wxAny &data) const;
300
301 wxAny ObjectPtrToAny( wxObject *object ) const;
302
303 // find property by name
304 virtual const wxPropertyInfo *FindPropertyInfo (const wxChar *PropertyName) const;
305
306 // find handler by name
307 virtual const wxHandlerInfo *FindHandlerInfo (const wxChar *handlerName) const;
308
309 // find property by name
310 virtual wxPropertyInfo *FindPropertyInfoInThisClass (const wxChar *PropertyName) const;
311
312 // find handler by name
313 virtual wxHandlerInfo *FindHandlerInfoInThisClass (const wxChar *handlerName) const;
314
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;
318
319 private:
320 const wxChar *m_className;
321 int m_objectSize;
322 wxObjectConstructorFn m_objectConstructor;
323
324 // class info object live in a linked list:
325 // pointers to its head and the next element in it
326
327 static wxClassInfo *sm_first;
328 wxClassInfo *m_next;
329
330 static wxHashTable *sm_classTable;
331
332 wxPropertyInfoFn m_firstPropertyFn;
333 wxHandlerInfoFn m_firstHandlerFn;
334
335
336 protected:
337 void EnsureInfosInited() const
338 {
339 if ( !m_firstInited)
340 {
341 if ( m_firstPropertyFn != NULL)
342 m_firstProperty = (*m_firstPropertyFn)();
343 if ( m_firstHandlerFn != NULL)
344 m_firstHandler = (*m_firstHandlerFn)();
345 m_firstInited = true;
346 }
347 }
348 mutable wxPropertyInfo* m_firstProperty;
349 mutable wxHandlerInfo* m_firstHandler;
350
351 private:
352 mutable bool m_firstInited;
353
354 const wxClassInfo** m_parents;
355 const wxChar* m_unitName;
356
357 wxObjectAllocatorAndCreator* m_constructor;
358 const wxChar ** m_constructorProperties;
359 const int m_constructorPropertiesCount;
360 wxVariantToObjectPtrConverter m_variantOfPtrToObjectConverter;
361 wxVariantToObjectConverter m_variantToObjectConverter;
362 wxObjectToVariantConverter m_objectToVariantConverter;
363 wxObjectStreamingCallback m_streamingCallback;
364
365 const wxPropertyAccessor *FindAccessor (const wxChar *propertyName) const;
366
367 protected:
368 // registers the class
369 void Register();
370 void Unregister();
371
372 DECLARE_NO_COPY_CLASS(wxClassInfo)
373 };
374
375 WXDLLIMPEXP_BASE wxObject *wxCreateDynamicObject(const wxString& name);
376
377 // ----------------------------------------------------------------------------
378 // wxDynamicClassInfo
379 // ----------------------------------------------------------------------------
380
381 // this object leads to having a pure runtime-instantiation
382
383 class WXDLLIMPEXP_BASE wxDynamicClassInfo : public wxClassInfo
384 {
385 friend class WXDLLIMPEXP_BASE wxDynamicObject;
386
387 public:
388 wxDynamicClassInfo( const wxChar *_UnitName, const wxChar *_ClassName,
389 const wxClassInfo* superClass );
390 virtual ~wxDynamicClassInfo();
391
392 // constructs a wxDynamicObject with an instance
393 virtual wxObject *AllocateObject() const;
394
395 // Call the Create method for a class
396 virtual bool Create (wxObject *object, int ParamCount, wxAny *Params) const;
397
398 // get number of parameters for constructor
399 virtual int GetCreateParamCount() const;
400
401 // get i-th constructor parameter
402 virtual const wxChar* GetCreateParamName(int i) const;
403
404 // Runtime access to objects by property name, and variant data
405 virtual void SetProperty (wxObject *object, const wxChar *PropertyName,
406 const wxAny &Value) const;
407 virtual wxAny GetProperty (wxObject *object, const wxChar *PropertyName) const;
408
409 // adds a property to this class at runtime
410 void AddProperty( const wxChar *propertyName, const wxTypeInfo* typeInfo );
411
412 // removes an existing runtime-property
413 void RemoveProperty( const wxChar *propertyName );
414
415 // renames an existing runtime-property
416 void RenameProperty( const wxChar *oldPropertyName, const wxChar *newPropertyName );
417
418 // as a handler to this class at runtime
419 void AddHandler( const wxChar *handlerName, wxObjectEventFunction address,
420 const wxClassInfo* eventClassInfo );
421
422 // removes an existing runtime-handler
423 void RemoveHandler( const wxChar *handlerName );
424
425 // renames an existing runtime-handler
426 void RenameHandler( const wxChar *oldHandlerName, const wxChar *newHandlerName );
427
428 private:
429 struct wxDynamicClassInfoInternal;
430 wxDynamicClassInfoInternal* m_data;
431 };
432
433 // ----------------------------------------------------------------------------
434 // wxDECLARE class macros
435 // ----------------------------------------------------------------------------
436
437 #define _DECLARE_DYNAMIC_CLASS(name) \
438 public: \
439 static wxClassInfo ms_classInfo; \
440 static const wxClassInfo* ms_classParents[]; \
441 static wxPropertyInfo* GetPropertiesStatic(); \
442 static wxHandlerInfo* GetHandlersStatic(); \
443 static wxClassInfo *GetClassInfoStatic() \
444 { return &name::ms_classInfo; } \
445 virtual wxClassInfo *GetClassInfo() const \
446 { return &name::ms_classInfo; }
447
448 #define wxDECLARE_DYNAMIC_CLASS(name) \
449 static wxObjectAllocatorAndCreator* ms_constructor; \
450 static const wxChar * ms_constructorProperties[]; \
451 static const int ms_constructorPropertiesCount; \
452 _DECLARE_DYNAMIC_CLASS(name)
453
454 #define wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(name) \
455 wxDECLARE_NO_ASSIGN_CLASS(name); \
456 wxDECLARE_DYNAMIC_CLASS(name)
457
458 #define wxDECLARE_DYNAMIC_CLASS_NO_COPY(name) \
459 wxDECLARE_NO_COPY_CLASS(name); \
460 wxDECLARE_DYNAMIC_CLASS(name)
461
462 #define wxDECLARE_CLASS(name) \
463 wxDECLARE_DYNAMIC_CLASS(name)
464
465 #define wxDECLARE_ABSTRACT_CLASS(name) _DECLARE_DYNAMIC_CLASS(name)
466 #define wxCLASSINFO(name) (&name::ms_classInfo)
467
468 #endif // wxUSE_EXTENDED_RTTI
469 #endif // _WX_XTIH__