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) : m_className(_ClassName)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 wxClassInfo(const wxChar * _UnitName,const wxChar * _ClassName,const wxClassInfo ** _Parents)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 wxClassInfo(const wxChar * _ClassName,const wxClassInfo * _Parent1,const wxClassInfo * _Parent2,int size,wxObjectConstructorFn ctor)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 AllocateObject()200 virtual wxObject *AllocateObject() const 201 { return m_objectConstructor ? (*m_objectConstructor)() : 0; } 202 203 // 'old naming' for AllocateObject staying here for backward compatibility CreateObject()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 GetClassName()211 const wxChar *GetClassName() const 212 { return m_className; } GetBaseClassName1()213 const wxChar *GetBaseClassName1() const 214 { return m_parents[0] ? m_parents[0]->GetClassName() : NULL; } GetBaseClassName2()215 const wxChar *GetBaseClassName2() const 216 { return (m_parents[0] && m_parents[1]) ? m_parents[1]->GetClassName() : NULL; } 217 GetBaseClass1()218 const wxClassInfo *GetBaseClass1() const 219 { return m_parents[0]; } GetBaseClass2()220 const wxClassInfo *GetBaseClass2() const 221 { return m_parents[0] ? m_parents[1] : NULL; } 222 GetIncludeName()223 const wxChar *GetIncludeName() const 224 { return m_unitName; } GetParents()225 const wxClassInfo **GetParents() const 226 { return m_parents; } GetSize()227 int GetSize() const 228 { return m_objectSize; } IsDynamic()229 bool IsDynamic() const 230 { return (NULL != m_objectConstructor); } 231 GetConstructor()232 wxObjectConstructorFn GetConstructor() const 233 { return m_objectConstructor; } GetNext()234 const wxClassInfo *GetNext() const 235 { return m_next; } 236 237 // statics: 238 239 static void CleanUp(); 240 static wxClassInfo *FindClass(const wxString& className); GetFirst()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 GetFirstProperty()264 wxPropertyInfo* GetFirstProperty() const 265 { EnsureInfosInited(); return m_firstProperty; } 266 267 // returns the first handler GetFirstHandler()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 GetCreateParamCount()276 virtual int GetCreateParamCount() const 277 { return m_constructorPropertiesCount; } 278 279 // get n-th constructor parameter GetCreateParamName(int n)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: EnsureInfosInited()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__ 470