diff --git a/include/wx/object.h b/include/wx/object.h index 1a2a2c8038..b215797a0e 100644 --- a/include/wx/object.h +++ b/include/wx/object.h @@ -28,6 +28,16 @@ class WXDLLIMPEXP_BASE wxObject; #if wxUSE_DYNAMIC_CLASSES +#ifndef wxUSE_XTI +#define wxUSE_XTI 0 +#endif + +#if wxUSE_XTI + +#include "wx/xti.h" + +#else + // ---------------------------------------------------------------------------- // conditional compilation // ---------------------------------------------------------------------------- @@ -104,6 +114,7 @@ public: static void CleanUpClasses(); + public: const wxChar *m_className; const wxChar *m_baseClassName1; @@ -198,6 +209,9 @@ WXDLLIMPEXP_BASE wxObject *wxCreateDynamicObject(const wxChar *name); #define IMPLEMENT_CLASS IMPLEMENT_ABSTRACT_CLASS #define IMPLEMENT_CLASS2 IMPLEMENT_ABSTRACT_CLASS2 +#endif // !wxUSE_XTI + + // ----------------------------------- // for pluggable classes // ----------------------------------- @@ -265,7 +279,6 @@ name##PluginSentinel m_pluginsentinel; #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) \ IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) - #define CLASSINFO(name) (&name::sm_class##name) #else // !wxUSE_DYNAMIC_CLASSES @@ -298,7 +311,6 @@ name##PluginSentinel m_pluginsentinel; #endif // wxUSE_DYNAMIC_CLASSES - #define wxIS_KIND_OF(obj, className) obj->IsKindOf(&className::sm_class##className) // Just seems a bit nicer-looking (pretend it's not a macro) diff --git a/include/wx/xti.h b/include/wx/xti.h new file mode 100644 index 0000000000..efc4a1bd3f --- /dev/null +++ b/include/wx/xti.h @@ -0,0 +1,1110 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/xti.h +// Purpose: runtime metadata information (extended class info) +// Author: Stefan Csomor +// Modified by: +// Created: 27/07/03 +// RCS-ID: $Id$ +// Copyright: (c) 1997 Julian Smart +// (c) 2003 Stefan Csomor +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_XTIH__ +#define _WX_XTIH__ + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma interface "xti.h" +#endif + +// We want to support properties, event sources and events sinks through +// explicit declarations, using templates and specialization to make the +// effort as painless as possible. +// +// This means we have the following domains : +// +// - Type Information for categorizing built in types as well as custom types +// this includes information about enums, their values and names +// - Type safe value storage : a kind of wxVariant, called right now wxxVariant +// which will be merged with wxVariant +// - Property Information and Property Accessors providing access to a class' +// values and exposed event delegates +// - Information about event handlers +// - extended Class Information for accessing all these + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/defs.h" +#include "wx/memory.h" +#include "wx/set.h" +#include "wx/string.h" + +class WXDLLIMPEXP_BASE wxObject; +class WXDLLIMPEXP_BASE wxClassInfo; +class WXDLLIMPEXP_BASE wxHashTable; +class WXDLLIMPEXP_BASE wxObjectRefData; +class WXDLLIMPEXP_BASE wxEvent; + +typedef void (wxObject::*wxObjectEventFunction)(wxEvent&); + +// ---------------------------------------------------------------------------- +// Enum Support +// +// In the header files there would no change from pure c++ code, in the +// implementation, an enum would have +// to be enumerated eg : +// +// WX_BEGIN_ENUM( wxFlavor ) +// WX_ENUM_MEMBER( Vanilla ) +// WX_ENUM_MEMBER( Chocolate ) +// WX_ENUM_MEMBER( Strawberry ) +// WX_END_ENUM( wxFlavor ) +// ---------------------------------------------------------------------------- + +struct WXDLLIMPEXP_BASE wxEnumMemberData +{ + const wxChar* m_name; + int m_value; +}; + +class WXDLLIMPEXP_BASE wxEnumData +{ +public : + wxEnumData( wxEnumMemberData* data ) ; + + // returns true if the member has been found and sets the int value + // pointed to accordingly (if ptr != null ) + // if not found returns false, value left unchanged + bool HasEnumMemberValue( const wxChar *name , int *value = NULL ) ; + + // returns the value of the member, if not found in debug mode an + // assert is issued, in release 0 is returned + int GetEnumMemberValue(const wxChar *name ); + + // returns the name of the enum member having the passed in value + // returns an emtpy string if not found + const wxChar *GetEnumMemberName(int value); + + // returns the number of members in this enum + int GetEnumCount() { return m_count ; } + + // returns the value of the nth member + int GetEnumMemberValueByIndex( int n ) ; + + // returns the value of the nth member + const wxChar *GetEnumMemberNameByIndex( int n ) ; +private : + wxEnumMemberData *m_members; + int m_count ; +}; + +#define WX_BEGIN_ENUM( e ) \ + wxEnumMemberData s_enumDataMembers##e[] = { + +#define WX_ENUM_MEMBER( v ) { #v, v } , + +#define WX_END_ENUM( e ) { NULL , 0 } } ; \ + wxEnumData s_enumData##e( s_enumDataMembers##e ) ; \ + wxEnumData *wxGetEnumData(e) { return &s_enumData##e ; } \ + template<> const wxTypeInfo* wxGetTypeInfo( e * ){ static wxEnumTypeInfo s_typeInfo(wxT_ENUM , &s_enumData##e) ; return &s_typeInfo ; } \ + template<> void wxStringReadValue(const wxString& s , e &data ) \ + { \ + data = (e) s_enumData##e.GetEnumMemberValue(s) ; \ + } \ + template<> void wxStringWriteValue(wxString &s , const e &data ) \ + { \ + s = s_enumData##e.GetEnumMemberName((int)data) ; \ + } + +// ---------------------------------------------------------------------------- +// Set Support +// +// in the header : +// +// enum wxFlavor +// { +// Vanilla, +// Chocolate, +// Strawberry, +// }; +// +// typedef wxSet wxCoupe ; +// +// in the implementation file : +// +// WX_BEGIN_ENUM( wxFlavor ) +// WX_ENUM_MEMBER( Vanilla ) +// WX_ENUM_MEMBER( Chocolate ) +// WX_ENUM_MEMBER( Strawberry ) +// WX_END_ENUM( wxFlavor ) +// +// WX_IMPLEMENT_SET_STREAMING( wxCoupe , wxFlavor ) +// +// implementation note : no partial specialization for streaming, but a delegation to a +// different class +// +// ---------------------------------------------------------------------------- + +// in order to remove dependancy on string tokenizer +void wxSetStringToArray( const wxString &s , wxArrayString &array ) ; + +template +void wxSetFromString(const wxString &s , wxSet &data ) +{ + wxEnumData* edata = wxGetEnumData((e) 0) ; + data.Clear() ; + + wxArrayString array ; + wxSetStringToArray( s , array ) ; + wxString flag; + for ( int i = 0 ; i < array.Count() ; ++i ) + { + flag = array[i] ; + int ivalue ; + if ( edata->HasEnumMemberValue( flag , &ivalue ) ) + { + data.Set( (e) ivalue ) ; + } + } +} + +template +void wxSetToString( wxString &s , const wxSet &data ) +{ + wxEnumData* edata = wxGetEnumData((e) 0) ; + int count = edata->GetEnumCount() ; + int i ; + s.Clear() ; + for ( i = 0 ; i < count ; i++ ) + { + e value = (e) edata->GetEnumMemberValueByIndex(i) ; + if ( data.Contains( value ) ) + { + // this could also be done by the templated calls + if ( !s.IsEmpty() ) + s +="|" ; + s += edata->GetEnumMemberNameByIndex(i) ; + } + } +} + +// if the wxSet specialization above does not work for all compilers, add this to the WX_IMPLEMENT_SET_STREAMING macro +// template<> const wxTypeInfo* wxGetTypeInfo( SetName * ){ static wxEnumTypeInfo s_typeInfo(wxT_SET , &s_enumData##e) ; return &s_typeInfo ; }\ + +#define WX_IMPLEMENT_SET_STREAMING(SetName,e) \ + template<> void wxStringReadValue(const wxString &s , wxSet &data ) \ + { \ + wxSetFromString( s , data ) ; \ + } \ + template<> void wxStringWriteValue( wxString &s , const wxSet &data ) \ + { \ + wxSetToString( s , data ) ; \ + } \ + + +// ---------------------------------------------------------------------------- +// Type Information +// ---------------------------------------------------------------------------- + +enum wxTypeKind +{ + wxT_VOID = 0, // unknown type + wxT_BOOL, + wxT_CHAR, + wxT_UCHAR, + wxT_INT, + wxT_UINT, + wxT_LONG, + wxT_ULONG, + wxT_FLOAT, + wxT_DOUBLE, + wxT_STRING, // must be wxString + wxT_SET, // must be wxSet<> template + wxT_ENUM, + wxT_OBJECT, // must be a component (pointer !!!) + wxT_CUSTOM, // user defined type (e.g. wxPoint) + wxT_DELEGATE , // for connecting against an event source + wxT_LAST_TYPE_KIND // sentinel for bad data, asserts, debugging +}; + +class WXDLLIMPEXP_BASE wxTypeInfo +{ +public : + wxTypeInfo() : m_kind( wxT_VOID) {} + virtual ~wxTypeInfo() {} + wxTypeKind GetKind() const { return m_kind ; } +protected : + wxTypeKind m_kind ; +}; + +class WXDLLIMPEXP_BASE wxBuiltInTypeInfo : public wxTypeInfo +{ +public : + wxBuiltInTypeInfo( wxTypeKind kind ) { assert( kind < wxT_SET ) ; m_kind = kind ;} +} ; + +class WXDLLIMPEXP_BASE wxCustomTypeInfo : public wxTypeInfo +{ +public : + wxCustomTypeInfo( const wxChar *typeName ) + { m_kind = wxT_CUSTOM ; m_typeName = typeName ;} + const wxChar *GetTypeName() const { assert( m_kind == wxT_CUSTOM ) ; return m_typeName ; } +private : + const wxChar *m_typeName; // Kind == wxT_CUSTOM +} ; + +class WXDLLIMPEXP_BASE wxEnumTypeInfo : public wxTypeInfo +{ +public : + wxEnumTypeInfo( wxTypeKind kind , wxEnumData* enumInfo ) + { assert( kind == wxT_ENUM || kind == wxT_SET ) ; m_kind = kind ; m_enumInfo = enumInfo ;} + const wxEnumData* GetEnumData() const { assert( m_kind == wxT_ENUM || m_kind == wxT_SET ) ; return m_enumInfo ; } +private : + wxEnumData *m_enumInfo; // Kind == wxT_ENUM or Kind == wxT_SET +} ; + +class WXDLLIMPEXP_BASE wxClassTypeInfo : public wxTypeInfo +{ +public : + wxClassTypeInfo( wxClassInfo* classInfo ) + { m_kind = wxT_OBJECT ; m_classInfo = classInfo ;} + const wxClassInfo *GetClassInfo() const { assert( m_kind == wxT_OBJECT ) ; return m_classInfo ; } +private : + wxClassInfo *m_classInfo; // Kind == wxT_OBJECT - could be NULL +} ; + +// a delegate is an exposed event source + +class WXDLLIMPEXP_BASE wxDelegateTypeInfo : public wxTypeInfo +{ +public : + wxDelegateTypeInfo( int eventType , wxClassInfo* eventClass ) + { m_kind = wxT_DELEGATE ; m_eventClass = eventClass ; m_eventType = eventType ;} + const wxClassInfo *GetEventClass() const { assert( m_kind == wxT_DELEGATE ) ; return m_eventClass ; } + int GetEventType() const { assert( m_kind == wxT_DELEGATE ) ; return m_eventType ; } +private : + const wxClassInfo *m_eventClass; // (extended will merge into classinfo) + int m_eventType ; +} ; + +template const wxTypeInfo* wxGetTypeInfo( T * ) ; + +template const wxTypeInfo* wxGetTypeInfo( wxSet * ) +{ + static wxEnumTypeInfo s_typeInfo(wxT_SET , wxGetEnumData((T) 0) ) ; return &s_typeInfo ; +} + +// this macro is for usage with custom, non-object derived classes and structs, wxPoint is such a custom type + +#define WX_CUSTOM_TYPE_INFO( e ) \ + template<> const wxTypeInfo* wxGetTypeInfo( e * ){ static wxCustomTypeInfo s_typeInfo(#e) ; return &s_typeInfo ; } \ + +// ---------------------------------------------------------------------------- +// value streaming +// +// streaming is defined for xml constructs right now, the aim is to make this +// pluggable in the future +// ---------------------------------------------------------------------------- + +// convenience function (avoids including xml headers in users code) + +class wxXmlNode ; +void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data ) ; +wxString wxXmlGetContentFromNode( wxXmlNode *node ) ; + +// templated streaming, every type must have their specialization for these methods + +template +void wxStringReadValue( const wxString &s , T &data ) ; + +template +void wxStringWriteValue( wxString &s , const T &data) ; + +// for simple types this default implementation is ok, composited structures will have to +// loop through their properties + +template +void wxXmlReadValue( wxXmlNode *node , T &data ) +{ + wxStringReadValue( wxXmlGetContentFromNode( node ) , data ) ; +} + +template +void wxXmlWriteValue( wxXmlNode *node , const T &data) +{ + wxString s ; + wxStringWriteValue( s, data ) ; + wxXmlAddContentToNode( node ,s ) ; +} + +// ---------------------------------------------------------------------------- +// wxxVariant as typesafe data holder +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxxVariantData +{ +public: + virtual ~wxxVariantData() {} + + // return a heap allocated duplicate + virtual wxxVariantData* Clone() const = 0 ; + + // returns the type info of the contentc + virtual const wxTypeInfo* GetTypeInfo() const = 0 ; + + // write the value into an xml node + virtual void Write( wxXmlNode* node ) const = 0 ; + + // read the value from the xml node + virtual void Read( wxXmlNode* node ) = 0 ; + + // write the value into a string + virtual void Write( wxString &s ) const = 0 ; + + // read the value from a string + virtual void Read( const wxString &s) = 0 ; +} ; + +template class WXDLLIMPEXP_BASE wxxVariantDataT : public wxxVariantData +{ +public: + wxxVariantDataT(T d) : m_data(d) {} + virtual ~wxxVariantDataT() {} + + // get a copy of the stored data + T Get() const { return m_data; } + + // set the data + void Set(T d) { m_data = d; } + + // return a heap allocated duplicate + virtual wxxVariantData* Clone() const { return new wxxVariantDataT( Get() ) ; } + + // returns the type info of the contentc + virtual const wxTypeInfo* GetTypeInfo() const { return wxGetTypeInfo( (T*) NULL ) ; } + + // write the value into an xml node + virtual void Write( wxXmlNode* node ) const { wxXmlWriteValue( node , m_data ) ; } + + // read the value from the xml node + virtual void Read( wxXmlNode* node ) { wxXmlReadValue( node , m_data ) ; } + + // write the value into a string + virtual void Write( wxString &s ) const { wxStringWriteValue( s , m_data ) ; } + + // read the value from a string + virtual void Read( const wxString &s) { wxStringReadValue( s , m_data ) ; } + +private: + T m_data; +}; + +class WXDLLIMPEXP_BASE wxxVariant +{ +public : + wxxVariant() { m_data = NULL ; } + wxxVariant( wxxVariantData* data , const wxString& name = wxT("") ) : m_data(data) , m_name(name) {} + wxxVariant( const wxxVariant &d ) { if ( d.m_data ) m_data = d.m_data->Clone() ; else m_data = NULL ; m_name = d.m_name ; } + + template wxxVariant( T data , const wxString& name = wxT("") ) : + m_data(new wxxVariantDataT(data) ), m_name(name) {} + ~wxxVariant() { delete m_data ; } + + // get a copy of the stored data + template T Get() const + { + wxxVariantDataT *dataptr = dynamic_cast*> (m_data) ; + assert( dataptr ) ; + return dataptr->Get() ; + } + + // stores the data + template Set(T data) const + { + delete m_data ; + m_data = new wxxVariantDataT(data) ; + } + + wxxVariant& operator=(const wxxVariant &d) + { + m_data = d.m_data->Clone() ; + m_name = d.m_name ; + return *this ; + } + + // gets the stored data casted to a wxObject* , returning NULL if cast is not possible + wxObject* GetAsObject() const ; + + // write the value into an xml node + void Write( wxXmlNode* node ) const { m_data->Write( node ) ; } + + // read the value from the xml node + void Read( wxXmlNode* node ) { m_data->Read( node ) ; } + + // write the value into a string + void Write( wxString &s ) const { m_data->Write( s ) ; } + + // read the value from a string + void Read( const wxString &s) { m_data->Read( s ) ; } + + // returns this value as string + wxString GetAsString() const + { + wxString s ; + Write( s ) ; + return s ; + } + + void SetFromString( const wxString &s) + { + Read( s ) ; + } +private : + wxxVariantData* m_data ; + wxString m_name ; +} ; + +// ---------------------------------------------------------------------------- +// Property Support +// +// wxPropertyInfo is used to inquire of the property by name. It doesn't +// provide access to the property, only information about it. If you +// want access, look at wxPropertyAccessor. +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxPropertyAccessor +{ +public : + virtual void SetProperty(wxObject *object, const wxxVariant &value) const = 0 ; + virtual wxxVariant GetProperty(wxObject *object) const = 0 ; + virtual bool HasSetter() const = 0 ; + virtual bool HasGetter() const = 0 ; + const char * GetGetterName() const { return m_setterName ; } + const char * GetSetterName() const { return m_getterName ; } + virtual wxxVariant ReadValue( wxXmlNode* node ) const = 0 ; + virtual void WriteValue( wxXmlNode* node , wxObject *o ) const = 0 ; + virtual wxxVariant ReadValue( const wxString &value ) const = 0 ; + virtual void WriteValue( wxString& value , wxObject *o ) const = 0 ; +protected : + const char *m_setterName ; + const char *m_getterName ; +}; + +template +void wxXmlReadValue( wxXmlNode *node , T &data ) ; + +template +void wxXmlWriteValue( wxXmlNode *node , const T &data) ; + +template +class WXDLLIMPEXP_BASE wxPropertyAccessorT : public wxPropertyAccessor +{ +public: + typedef void (Klass::*setter_t)(T value); + typedef void (Klass::*setter_ref_t)(T& value); + typedef T (Klass::*getter_t)() const; + typedef const T& (Klass::*getter_ref_t)() const; + + wxPropertyAccessorT(setter_t setter, getter_t getter, const char *g, const char *s) + : m_setter(setter), m_setter_ref(NULL), m_getter(getter) ,m_getter_ref(NULL) {m_setterName = s;m_getterName=g ;} + wxPropertyAccessorT(setter_ref_t setter, getter_t getter, const char *g, const char *s) + : m_setter(NULL), m_setter_ref(setter), m_getter(getter) , m_getter_ref(NULL){m_setterName = s;m_getterName=g ;} + wxPropertyAccessorT(setter_ref_t setter, getter_ref_t getter, const char *g, const char *s) + : m_setter(NULL), m_setter_ref(setter), m_getter(NULL) , m_getter_ref(getter){m_setterName = s;m_getterName=g ;} + wxPropertyAccessorT(setter_t setter, getter_ref_t getter, const char *g, const char *s) + : m_setter(NULL), m_setter(setter), m_getter(NULL) , m_getter_ref(getter){m_setterName = s;m_getterName=g ;} + + // returns true if this accessor has a setter + bool HasSetter() const { return m_setter != NULL || m_setter_ref != NULL ; } + + // return true if this accessor has a getter + bool HasGetter() const { return m_getter != NULL || m_getter_ref != NULL ; } + + // set the property this accessor is responsible for in an object + void SetProperty(wxObject *o, const wxxVariant &v) const + { + Klass *obj = dynamic_cast(o); + T value = v.Get(); + if (m_setter) + (obj->*(m_setter))(value); + else + (obj->*(m_setter_ref))(value); + } + + // gets the property this accessor is responsible for from an object + wxxVariant GetProperty(wxObject *o) const + { + return wxxVariant( (wxxVariantData* ) DoGetProperty( o ) ) ; + } + + // write the property this accessor is responsible for from an object into + // a xml node + void WriteValue( wxXmlNode* node , wxObject *o ) const + { + DoGetProperty( o )->Write( node ) ; + } + + // write the property this accessor is responsible for from an object into + // a string + void WriteValue( wxString& s , wxObject *o ) const + { + DoGetProperty( o )->Write( s ) ; + } + + // read a wxxVariant having the correct type for the property this accessor + // is responsible for from an xml node + wxxVariant ReadValue( wxXmlNode* node ) const + { + T data ; + wxXmlReadValue( node , data ) ; + return wxxVariant( data ) ; + } + + // read a wxxVariant having the correct type for the property this accessor + // is responsible for from a string + wxxVariant ReadValue( const wxString &value ) const + { + T data ; + wxStringReadValue( value , data ) ; + return wxxVariant( data ) ; + } + +private : + wxxVariantDataT* DoGetProperty(wxObject *o) const + { + Klass *obj = dynamic_cast(o); + if ( m_getter ) + return new wxxVariantDataT( (obj->*(m_getter))() ) ; + else + return new wxxVariantDataT( (obj->*(m_getter_ref))() ) ; + } + + setter_t m_setter; + setter_ref_t m_setter_ref; + getter_t m_getter; + getter_ref_t m_getter_ref ; +}; + +class WXDLLIMPEXP_BASE wxPropertyInfo +{ +public : + wxPropertyInfo( wxPropertyInfo* &iter , const char *name , const char *typeName , const wxTypeInfo* typeInfo , wxPropertyAccessor *accessor , wxxVariant dv ) : + m_name( name ) , m_typeName(typeName) , m_typeInfo( typeInfo ) , m_accessor( accessor ) , m_defaultValue( dv ) + { + m_next = iter ; + iter = this ; + } + // return the name of this property + const char * GetName() const { return m_name ; } + + // return the typename of this property + const char * GetTypeName() const { return m_typeName ; } + + // return the type info of this property + const wxTypeInfo * GetTypeInfo() const { return m_typeInfo ; } + + // return the accessor for this property + wxPropertyAccessor* GetAccessor() const { return m_accessor ; } + + // returns NULL if this is the last property of this class + wxPropertyInfo* GetNext() const { return m_next ; } +private : + const char * m_name; + const char * m_typeName ; + const wxTypeInfo* m_typeInfo ; + wxPropertyAccessor* m_accessor ; + wxxVariant m_defaultValue; + // string representation of the default value + // to be assigned by the designer to the property + // when the component is dropped on the container. + wxPropertyInfo* m_next ; +}; + +#define WX_BEGIN_PROPERTIES_TABLE(theClass) \ + const wxPropertyInfo *theClass::GetPropertiesStatic() \ + { \ + typedef theClass class_t; \ + static wxPropertyInfo* first = NULL ; + +#define WX_END_PROPERTIES_TABLE() \ + return first ; } + +#define WX_PROPERTY( name , type , setter , getter ,defaultValue ) \ + static wxPropertyAccessorT _accessor##name( setter , getter , #setter , #getter ) ; \ + static wxPropertyInfo _propertyInfo##name( first , #name , #type , wxGetTypeInfo( (type*) NULL ) ,&_accessor##name , wxxVariant(defaultValue) ) ; + +#define WX_DELEGATE( name , eventType , eventClass ) \ + static wxDelegateTypeInfo _typeInfo##name( eventType , CLASSINFO( eventClass ) ) ; \ + static wxPropertyInfo _propertyInfo##name( first , #name , NULL , &_typeInfo##name , NULL , wxxVariant() ) ; \ + +// ---------------------------------------------------------------------------- +// Handler Info +// +// this is describing an event sink +// ---------------------------------------------------------------------------- + +class wxHandlerInfo +{ +public : + wxHandlerInfo( wxHandlerInfo* &iter , const wxChar *name , wxObjectEventFunction address , const wxClassInfo* eventClassInfo ) : + m_name( name ) , m_eventClassInfo( eventClassInfo ) , m_eventFunction( address ) + { + m_next = iter ; + iter = this ; + } + + // get the name of the handler method + const char * GetName() const { return m_name ; } + + // return the class info of the event + const wxClassInfo * GetEventClassInfo() const { return m_eventClassInfo ; } + + // get the handler function pointer + wxObjectEventFunction GetEventFunction() const { return m_eventFunction ; } + + // returns NULL if this is the last handler of this class + wxHandlerInfo* GetNext() const { return m_next ; } +private : + const wxChar * m_name; + wxObjectEventFunction m_eventFunction ; + const wxClassInfo* m_eventClassInfo ; + wxHandlerInfo* m_next ; +}; + +#define WX_HANDLER(name,eventClassType) \ + static wxHandlerInfo _handlerInfo##name( first , #name , (wxObjectEventFunction) &name , CLASSINFO( eventClassType ) ) ; + +#define WX_BEGIN_HANDLERS_TABLE(theClass) \ + const wxHandlerInfo *theClass::GetHandlersStatic() \ + { \ + typedef theClass class_t; \ + static wxHandlerInfo* first = NULL ; + +#define WX_END_HANDLERS_TABLE() \ + return first ; } + +// ---------------------------------------------------------------------------- +// Constructor Bridges +// +// allow to set up constructors with params during runtime +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxConstructorBridge +{ +public : + virtual void Create(wxObject *o, wxxVariant *args) = 0; +}; + +// Creator Bridges for all Numbers of Params + +// no params + +template +struct wxConstructorBridge_0 : public wxConstructorBridge +{ + void Create(wxObject *o, wxxVariant *) + { + Class *obj = dynamic_cast(o); + obj->Create(); + } +}; + +struct wxConstructorBridge_Dummy : public wxConstructorBridge +{ + void Create(wxObject *, wxxVariant *) + { + } +} ; + +#define WX_CONSTRUCTOR_0(klass) \ + wxConstructorBridge_0 constructor##klass ; \ + wxConstructorBridge* klass::sm_constructor##klass = &constructor##klass ; \ + const char *klass::sm_constructorProperties##klass[] = { NULL } ; \ + const int klass::sm_constructorPropertiesCount##klass = 0 ; + +#define WX_CONSTRUCTOR_DUMMY(klass) \ + wxConstructorBridge_Dummy constructor##klass ; \ + wxConstructorBridge* klass::sm_constructor##klass = &constructor##klass ; \ + const char *klass::sm_constructorProperties##klass[] = { NULL } ; \ + const int klass::sm_constructorPropertiesCount##klass = 0 ; + +// 1 param + +template +struct wxConstructorBridge_1 : public wxConstructorBridge +{ + void Create(wxObject *o, wxxVariant *args) + { + Class *obj = dynamic_cast(o); + obj->Create( + args[0].Get() + ); + } +}; + +#define WX_CONSTRUCTOR_1(klass,t0,v0) \ + wxConstructorBridge_1 constructor##klass ; \ + wxConstructorBridge* klass::sm_constructor##klass = &constructor##klass ; \ + const char *klass::sm_constructorProperties##klass[] = { #v0 } ; \ + const int klass::sm_constructorPropertiesCount##klass = 1 ; + +// 2 params + +template +struct wxConstructorBridge_2 : public wxConstructorBridge +{ + void Create(wxObject *o, wxxVariant *args[]) + { + Class *obj = dynamic_cast(o); + obj->Create( + args[0].Get() , + args[1].Get() + ); + } +}; + +#define WX_CONSTRUCTOR_2(klass,t0,v0,t1,v1) \ + wxConstructorBridge_2 constructor##klass ; \ + klass::sm_constructor##klass = &constructor##klass ; \ + klass::sm_constructorProperties##klass[] = { #v0 , #v1 } ; \ + klass::sm_constructorPropertiesCount##klass = 2; + +// 3 params + +template +struct wxConstructorBridge_3 : public wxConstructorBridge +{ + void Create(wxObject *o, wxxVariant *args[]) + { + Class *obj = dynamic_cast(o); + obj->Create( + args[0].Get() , + args[1].Get() , + args[2].Get() + ); + } +}; + +#define WX_CONSTRUCTOR_3(klass,t0,v0,t1,v1,t2,v2) \ + wxConstructorBridge_3 constructor##klass ; \ + klass::sm_constructor##klass = &constructor##klass ; \ + klass::sm_constructorProperties##klass[] = { #v0 , #v1 , #v2 } ; \ + klass::sm_constructorPropertiesCount##klass = 3 ; + +// 4 params + +template +struct wxConstructorBridge_4 : public wxConstructorBridge +{ + void Create(wxObject *o, wxxVariant *args[]) + { + Class *obj = dynamic_cast(o); + obj->Create( + args[0].Get() , + args[1].Get() , + args[2].Get() , + args[3].Get() + ); + } +}; + +#define WX_CONSTRUCTOR_4(klass,t0,v0,t1,v1,t2,v2,t3,v3) \ + wxConstructorBridge_4 constructor##klass ; \ + klass::sm_constructor##klass = &constructor##klass ; \ + klass::sm_constructorProperties##klass[] = { #v0 , #v1 , #v2 , #v3 } ; \ + klass::sm_constructorPropertiesCount##klass = 4 ; + +// ---------------------------------------------------------------------------- +// wxClassInfo +// ---------------------------------------------------------------------------- + +typedef wxObject *(*wxObjectConstructorFn)(void); +typedef wxObject* (*wxVariantToObjectConverter)( const wxxVariant &data ) ; +typedef wxxVariant (*wxObjectToVariantConverter)( wxObject* ) ; + +class WXDLLIMPEXP_BASE wxClassInfo +{ +public: + wxClassInfo(const wxClassInfo **_Parents, + const char *_UnitName, + const char *_ClassName, + int size, + wxObjectConstructorFn ctor , + const wxPropertyInfo *_Props , + wxConstructorBridge* _Constructor , + const char ** _ConstructorProperties , + const int _ConstructorPropertiesCount , + wxVariantToObjectConverter _Converter1 , + wxObjectToVariantConverter _Converter2 + ) : m_parents(_Parents) , m_unitName(_UnitName) ,m_className(_ClassName), + m_objectSize(size), m_objectConstructor(ctor) , m_firstProperty(_Props ) , m_constructor( _Constructor ) , + m_constructorProperties(_ConstructorProperties) , m_constructorPropertiesCount(_ConstructorPropertiesCount), + m_variantToObjectConverter( _Converter1 ) , m_objectToVariantConverter( _Converter2 ) , m_next(sm_first) + { + sm_first = this; + Register( m_className , this ) ; + } + + ~wxClassInfo() ; + + wxObject *CreateObject() { return m_objectConstructor ? (*m_objectConstructor)() : 0; } + + const wxChar *GetClassName() const { return m_className; } + const wxClassInfo **GetParents() const { return m_parents; } + int GetSize() const { return m_objectSize; } + + wxObjectConstructorFn GetConstructor() const { return m_objectConstructor; } + static const wxClassInfo *GetFirst() { return sm_first; } + const wxClassInfo *GetNext() const { return m_next; } + static wxClassInfo *FindClass(const wxChar *className); + + // Climb upwards through inheritance hierarchy. + // Dual inheritance is catered for. + + bool IsKindOf(const wxClassInfo *info) const + { + if ( info != 0 ) + { + if ( info == this ) + return true ; + + for ( int i = 0 ; m_parents[i] ; ++ i ) + { + if ( m_parents[i]->IsKindOf( info ) ) + return true ; + } + } + return false ; + } + + // Initializes parent pointers and hash table for fast searching. + // this is going to be removed by Register/Unregister calls + // in Constructor / Destructor together with making the hash map private + + static void InitializeClasses(); + + // Cleans up hash table used for fast searching. + + static void CleanUpClasses(); + + // returns the first property + const wxPropertyInfo* GetFirstProperty() const { return m_firstProperty ; } + + // returns the first handler + const wxHandlerInfo* GetFirstHandler() const { return m_firstHandler ; } + + // Call the Create method for a class + virtual void Create (wxObject *object, int ParamCount, wxxVariant *Params) + { + wxASSERT( ParamCount == m_constructorPropertiesCount ) ; + m_constructor->Create( object , Params ) ; + } + + // get number of parameters for constructor + virtual int GetCreateParamCount() const { return m_constructorPropertiesCount; } + + // get i-th constructor parameter + virtual const wxChar* GetCreateParamName(int i) const { return m_constructorProperties[i] ; } + + // Runtime access to objects by property name, and variant data + virtual void SetProperty (wxObject *object, const char *PropertyName, const wxxVariant &Value); + virtual wxxVariant GetProperty (wxObject *object, const char *PropertyName); + + // we must be able to cast variants to wxObject pointers, templates seem not to be suitable + wxObject* VariantToInstance( const wxxVariant &data ) const { return m_variantToObjectConverter( data ) ; } + wxxVariant InstanceToVariant( wxObject *object ) const { return m_objectToVariantConverter( object ) ; } + + // find property by name + virtual const wxPropertyInfo *FindPropInfo (const char *PropertyName) const ; + +public: + const wxChar *m_className; + int m_objectSize; + wxObjectConstructorFn m_objectConstructor; + + // class info object live in a linked list: + // pointers to its head and the next element in it + + static wxClassInfo *sm_first; + wxClassInfo *m_next; + + // FIXME: this should be private (currently used directly by way too + // many clients) + static wxHashTable *sm_classTable; + +private: + const wxClassInfo** m_parents ; + const wxPropertyInfo * m_firstProperty ; + const wxHandlerInfo * m_firstHandler ; + const wxChar* m_unitName; + + wxConstructorBridge* m_constructor ; + const wxChar ** m_constructorProperties ; + const int m_constructorPropertiesCount ; + wxVariantToObjectConverter m_variantToObjectConverter ; + wxObjectToVariantConverter m_objectToVariantConverter ; + + const wxPropertyAccessor *FindAccessor (const char *propertyName); + + // registers the class + static void Register(const wxChar *name, wxClassInfo *info); + + static void Unregister(const wxChar *name); + + // InitializeClasses() helper + static wxClassInfo *GetBaseByName(const wxChar *name); + + DECLARE_NO_COPY_CLASS(wxClassInfo) +}; + +WXDLLIMPEXP_BASE wxObject *wxCreateDynamicObject(const wxChar *name); + +// ---------------------------------------------------------------------------- +// Dynamic class macros +// ---------------------------------------------------------------------------- + +#define _DECLARE_DYNAMIC_CLASS(name) \ + public: \ + static wxClassInfo sm_class##name; \ + static const wxClassInfo* sm_classParents##name[] ; \ + static const wxPropertyInfo* GetPropertiesStatic() ; \ + static const wxHandlerInfo* GetHandlersStatic() ; \ + virtual wxClassInfo *GetClassInfo() const \ + { return &name::sm_class##name; } + +#define DECLARE_DYNAMIC_CLASS(name) \ + _DECLARE_DYNAMIC_CLASS(name) \ + static wxConstructorBridge* sm_constructor##name ; \ + static const char * sm_constructorProperties##name[] ; \ + static const int sm_constructorPropertiesCount##name ; + +#define DECLARE_DYNAMIC_CLASS_NO_ASSIGN(name) \ + DECLARE_NO_ASSIGN_CLASS(name) \ + DECLARE_DYNAMIC_CLASS(name) + +#define DECLARE_DYNAMIC_CLASS_NO_COPY(name) \ + DECLARE_NO_COPY_CLASS(name) \ + DECLARE_DYNAMIC_CLASS(name) + +#define DECLARE_ABSTRACT_CLASS(name) _DECLARE_DYNAMIC_CLASS(name) +#define DECLARE_CLASS(name) DECLARE_DYNAMIC_CLASS(name) + +// ----------------------------------- +// for concrete classes +// ----------------------------------- + + // Single inheritance with one base class + +#define _IMPLEMENT_DYNAMIC_CLASS(name, basename, unit) \ + wxObject* wxConstructorFor##name() \ + { return new name; } \ + const wxClassInfo* name::sm_classParents##name[] = { &basename::sm_class##basename ,NULL } ; \ + wxObject* wxVariantToObjectConverter##name ( const wxxVariant &data ) { return data.Get() ; } \ + wxxVariant wxObjectToVariantConverter##name ( wxObject *data ) { return wxxVariant( dynamic_cast (data) ) ; } \ + wxClassInfo name::sm_class##name(sm_classParents##name , wxT(unit) , wxT(#name), \ + (int) sizeof(name), \ + (wxObjectConstructorFn) wxConstructorFor##name , \ + name::GetPropertiesStatic(),name::sm_constructor##name , name::sm_constructorProperties##name , \ + name::sm_constructorPropertiesCount##name , wxVariantToObjectConverter##name , wxObjectToVariantConverter##name); \ + template<> void wxStringReadValue(const wxString & , name * & ){assert(0) ;}\ + template<> void wxStringWriteValue(wxString & , name* const & ){assert(0) ;}\ + template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(&name::sm_class##name) ; return &s_typeInfo ; } + +#define IMPLEMENT_DYNAMIC_CLASS( name , basename ) \ +_IMPLEMENT_DYNAMIC_CLASS( name , basename , "" ) \ +const wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL ; } \ +WX_CONSTRUCTOR_DUMMY( name ) + +#define IMPLEMENT_DYNAMIC_CLASS_XTI( name , basename , unit ) \ +_IMPLEMENT_DYNAMIC_CLASS( name , basename , unit ) + +// this is for classes that do not derive from wxobject, there are no creators for these + +#define IMPLEMENT_DYNAMIC_CLASS_NO_WXOBJECT_NO_BASE_XTI( name , unit ) \ + const wxClassInfo* name::sm_classParents##name[] = { NULL } ; \ + wxClassInfo name::sm_class##name(sm_classParents##name , wxT("") , wxT(#name), \ + (int) sizeof(name), \ + (wxObjectConstructorFn) 0 , \ + name::GetPropertiesStatic(),0 , 0 , \ + 0 , 0 , 0 ); \ + template<> void wxStringReadValue(const wxString & , name * & ){assert(0) ;}\ + template<> void wxStringWriteValue(wxString & , name* const & ){assert(0) ;}\ + template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(&name::sm_class##name) ; return &s_typeInfo ; } + +// this is for subclasses that still do not derive from wxobject + +#define IMPLEMENT_DYNAMIC_CLASS_NO_WXOBJECT_XTI( name , basename, unit ) \ + const wxClassInfo* name::sm_classParents##name[] = { &basename::sm_class##basename ,NULL } ; \ + wxClassInfo name::sm_class##name(sm_classParents##name , wxT("") , wxT(#name), \ + (int) sizeof(name), \ + (wxObjectConstructorFn) 0 , \ + name::GetPropertiesStatic(),0 , 0 , \ + 0 , 0 , 0 ); \ + template<> void wxStringReadValue(const wxString & , name * & ){assert(0) ;}\ + template<> void wxStringWriteValue(wxString & , name* const & ){assert(0) ;}\ + template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(&name::sm_class##name) ; return &s_typeInfo ; } + + // Multiple inheritance with two base classes + +#define _IMPLEMENT_DYNAMIC_CLASS2(name, basename, basename2, unit) \ + wxObject* wxConstructorFor##name() \ + { return new name; } \ + const wxClassInfo* name::sm_classParents##name[] = { &basename::sm_class##basename ,&basename2::sm_class##basename2 , NULL } ; \ + wxObject* wxVariantToObjectConverter##name ( const wxxVariant &data ) { return data.Get() ; } \ + wxxVariant wxObjectToVariantConverter##name ( wxObject *data ) { return wxxVariant( dynamic_cast (data) ) ; } \ + wxClassInfo name::sm_class##name(sm_classParents##name , wxT(unit) , wxT(#name), \ + (int) sizeof(name), \ + (wxObjectConstructorFn) wxConstructorFor##name , \ + name::GetPropertiesStatic(),name::sm_constructor##name , name::sm_constructorProperties##name , \ + name::sm_constructorPropertiesCount##name , wxVariantToObjectConverter##name , wxObjectToVariantConverter##name); \ + template<> void wxStringReadValue(const wxString & , name * & ){assert(0) ;}\ + template<> void wxStringWriteValue(wxString & , name* const & ){assert(0) ;}\ + template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(&name::sm_class##name) ; return &s_typeInfo ; } + +#define IMPLEMENT_DYNAMIC_CLASS2( name , basename , basename2) \ +_IMPLEMENT_DYNAMIC_CLASS2( name , basename , basename2 , "") \ +const wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL ; } \ +WX_CONSTRUCTOR_DUMMY( name ) + +#define IMPLEMENT_DYNAMIC_CLASS2_XTI( name , basename , basename2, unit) \ + _IMPLEMENT_DYNAMIC_CLASS2( name , basename , basename2 , unit) + +// ----------------------------------- +// for abstract classes +// ----------------------------------- + + // Single inheritance with one base class + +#define _IMPLEMENT_ABSTRACT_CLASS(name, basename) \ + const wxClassInfo* name::sm_classParents##name[] = { &basename::sm_class##basename ,NULL } ; \ + wxObject* wxVariantToObjectConverter##name ( const wxxVariant &data ) { return data.Get() ; } \ + wxxVariant wxObjectToVariantConverter##name ( wxObject *data ) { return wxxVariant( dynamic_cast (data) ) ; } \ + wxClassInfo name::sm_class##name(sm_classParents##name , wxT("") , wxT(#name), \ + (int) sizeof(name), \ + (wxObjectConstructorFn) 0 , \ + name::GetPropertiesStatic(),0 , 0 , \ + 0 , wxVariantToObjectConverter##name , wxObjectToVariantConverter##name); \ + template<> void wxStringReadValue(const wxString & , name * & ){assert(0) ;}\ + template<> void wxStringWriteValue(wxString & , name* const & ){assert(0) ;}\ + template<> const wxTypeInfo* wxGetTypeInfo( name ** ){ static wxClassTypeInfo s_typeInfo(&name::sm_class##name) ; return &s_typeInfo ; } + +#define IMPLEMENT_ABSTRACT_CLASS( name , basename ) \ +_IMPLEMENT_ABSTRACT_CLASS( name , basename ) \ +const wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL ; } + + // Multiple inheritance with two base classes + +#define IMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2) \ + wxClassInfo name::sm_class##name(wxT(#name), wxT(#basename1), \ + wxT(#basename2), (int) sizeof(name), \ + (wxObjectConstructorFn) 0); + +#define IMPLEMENT_CLASS IMPLEMENT_ABSTRACT_CLASS +#define IMPLEMENT_CLASS2 IMPLEMENT_ABSTRACT_CLASS2 + +#endif \ No newline at end of file diff --git a/src/common/dynload.cpp b/src/common/dynload.cpp index 65bdd6ddb4..11f848e524 100644 --- a/src/common/dynload.cpp +++ b/src/common/dynload.cpp @@ -422,6 +422,7 @@ void wxPluginLibrary::UpdateClassInfo() } } +#if wxUSE_XTI == 0 for(info = m_after; info != m_before; info = info->m_next) { if( info->m_baseClassName1 ) @@ -429,6 +430,7 @@ void wxPluginLibrary::UpdateClassInfo() if( info->m_baseClassName2 ) info->m_baseInfo2 = (wxClassInfo *)t->Get(info->m_baseClassName2); } +#endif } void wxPluginLibrary::RestoreClassInfo() diff --git a/src/common/object.cpp b/src/common/object.cpp index f0ca00964c..d21eb76155 100644 --- a/src/common/object.cpp +++ b/src/common/object.cpp @@ -51,9 +51,26 @@ #pragma optimize("", off) #endif +#if wxUSE_XTI +const wxClassInfo* wxObject::sm_classParentswxObject[] = { NULL } ; + wxObject* wxVariantToObjectConverterwxObject ( const wxxVariant &data ) +{ return data.Get() ; } + wxxVariant wxObjectToVariantConverterwxObject ( wxObject *data ) + { return wxxVariant( dynamic_cast (data) ) ; } + wxClassInfo wxObject::sm_classwxObject(sm_classParentswxObject , wxT("") , wxT("wxObject"), + (int) sizeof(wxObject), \ + (wxObjectConstructorFn) 0 , + (wxPropertyInfo*) NULL,0 , 0 , + 0 , wxVariantToObjectConverterwxObject , wxObjectToVariantConverterwxObject); + template<> void wxStringReadValue(const wxString & , wxObject * & ){assert(0) ;} + template<> void wxStringWriteValue(wxString & , wxObject* const & ){assert(0) ;} + template<> const wxTypeInfo* wxGetTypeInfo( wxObject ** ) + { static wxClassTypeInfo s_typeInfo(&wxObject::sm_classwxObject) ; return &s_typeInfo ; } +#else wxClassInfo wxObject::sm_classwxObject( wxT("wxObject"), 0, 0, (int) sizeof(wxObject), (wxObjectConstructorFn) 0 ); +#endif // restore optimizations #if defined __VISUALC__ && __VISUALC__ >= 1300 @@ -171,6 +188,9 @@ wxClassInfo::~wxClassInfo() info = info->m_next; } } +#if wxUSE_XTI + Unregister( m_className ) ; +#endif } wxClassInfo *wxClassInfo::FindClass(const wxChar *className) @@ -244,6 +264,7 @@ void wxClassInfo::InitializeClasses() } } +#if wxUSE_XTI == 0 // Set base pointers for each wxClassInfo for(info = sm_first; info; info = info->m_next) @@ -251,6 +272,7 @@ void wxClassInfo::InitializeClasses() info->m_baseInfo1 = GetBaseByName(info->GetBaseClassName1()); info->m_baseInfo2 = GetBaseByName(info->GetBaseClassName2()); } +#endif } void wxClassInfo::CleanUpClasses() @@ -259,7 +281,6 @@ void wxClassInfo::CleanUpClasses() wxClassInfo::sm_classTable = NULL; } - wxObject *wxCreateDynamicObject(const wxChar *name) { #if defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT diff --git a/src/common/xti.cpp b/src/common/xti.cpp new file mode 100644 index 0000000000..13595aa27c --- /dev/null +++ b/src/common/xti.cpp @@ -0,0 +1,362 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/common/xti.cpp +// Purpose: runtime metadata information (extended class info +// Author: Stefan Csomor +// Modified by: +// Created: 27/07/03 +// RCS-ID: $Id$ +// Copyright: (c) 1997 Julian Smart +// (c) 2003 Stefan Csomor +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "xti.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/hash.h" + #include "wx/object.h" +#endif + +#include "wx/xml/xml.h" +#include "wx/tokenzr.h" + +#include + +#if wxUSE_XTI + +// ---------------------------------------------------------------------------- +// Enum Support +// ---------------------------------------------------------------------------- + +wxEnumData::wxEnumData( wxEnumMemberData* data ) +{ + m_members = data ; + for ( m_count = 0; m_members[m_count].m_name ; m_count++) + {} ; +} + +bool wxEnumData::HasEnumMemberValue(const wxChar *name, int *value) +{ + int i; + for (i = 0; m_members[i].m_name ; i++ ) + { + if (!strcmp(name, m_members[i].m_name)) + { + if ( value ) + *value = m_members[i].m_value; + return true ; + } + } + return false ; +} + +int wxEnumData::GetEnumMemberValue(const wxChar *name) +{ + int i; + for (i = 0; m_members[i].m_name ; i++ ) + { + if (!strcmp(name, m_members[i].m_name)) + { + return m_members[i].m_value; + } + } + return 0 ; +} + +const wxChar *wxEnumData::GetEnumMemberName(int value) +{ + int i; + for (i = 0; m_members[i].m_name ; i++) + if (value == m_members[i].m_value) + return m_members[i].m_name; + + return wxT("") ; +} + +int wxEnumData::GetEnumMemberValueByIndex( int idx ) +{ + // we should cache the count in order to avoid out-of-bounds errors + return m_members[idx].m_value ; +} + +const char * wxEnumData::GetEnumMemberNameByIndex( int idx ) +{ + // we should cache the count in order to avoid out-of-bounds errors + return m_members[idx].m_name ; +} + +// ---------------------------------------------------------------------------- +// Type Information +// ---------------------------------------------------------------------------- + +const wxTypeInfo* wxGetTypeInfo( void * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( bool * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_BOOL ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( char * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_CHAR ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( unsigned char * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_UCHAR ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( int * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_CHAR ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( unsigned int * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_UCHAR ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( long * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_CHAR ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( unsigned long * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_UCHAR ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( float * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_FLOAT ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( double * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_DOUBLE ) ; + return &s_typeInfo ; +} + +const wxTypeInfo* wxGetTypeInfo( wxString * ) +{ + static wxBuiltInTypeInfo s_typeInfo( wxT_STRING ) ; + return &s_typeInfo ; +} + +// this is a compiler induced specialization which is never used anywhere +// const char * should never be active + +const wxTypeInfo* wxGetTypeInfo( char const ** ) +{ + assert(0) ; + static wxBuiltInTypeInfo s_typeInfo( wxT_VOID ) ; + return &s_typeInfo ; +} + +void wxStringReadValue(const wxString & , const char* & ) +{ + assert(0) ; +} + +void wxStringWriteValue(wxString & , char const * const & ) +{ + assert(0) ; +} + + +// ---------------------------------------------------------------------------- +// value streaming +// ---------------------------------------------------------------------------- + +// convenience function (avoids including xml headers in users code) + +void wxXmlAddContentToNode( wxXmlNode* node , const wxString& data ) +{ + node->AddChild(new wxXmlNode(wxXML_TEXT_NODE, "value", data ) ); +} + +wxString wxXmlGetContentFromNode( wxXmlNode *node ) +{ + return node->GetChildren()->GetContent() ; +} + +// streamer specializations + +// TODO for all built-in types + +// long + +void wxStringReadValue(const wxString &s , long &data ) +{ + wxSscanf(s, _T("%ld"), &data ) ; +} + +void wxStringWriteValue(wxString &s , const long &data ) +{ + s = wxString::Format("%ld", data ) ; +} + +// long + +void wxStringReadValue(const wxString &s , int &data ) +{ + wxSscanf(s, _T("%d"), &data ) ; +} + +void wxStringWriteValue(wxString &s , const int &data ) +{ + s = wxString::Format("%d", data ) ; +} + +// wxString + +void wxStringReadValue(const wxString &s , wxString &data ) +{ + data = s ; +} + +void wxStringWriteValue(wxString &s , const wxString &data ) +{ + s = data ; +} + +/* + Custom Data Streaming / Type Infos + we will have to add this for all wx non object types, but it is also an example + for custom data structures +*/ + +// wxPoint + +void wxStringReadValue(const wxString &s , wxPoint &data ) +{ + wxSscanf(s, _T("%d,%d"), &data.x , &data.y ) ; +} + +void wxStringWriteValue(wxString &s , const wxPoint &data ) +{ + s = wxString::Format("%d,%d", data.x , data.y ) ; +} + +WX_CUSTOM_TYPE_INFO(wxPoint) + +// removing header dependancy on string tokenizer + +void wxSetStringToArray( const wxString &s , wxArrayString &array ) +{ + wxStringTokenizer tokenizer(s, wxT("| \t\n"), wxTOKEN_STRTOK); + wxString flag; + array.Clear() ; + while (tokenizer.HasMoreTokens()) + { + array.Add(tokenizer.GetNextToken()) ; + } +} + +// ---------------------------------------------------------------------------- +// wxClassInfo +// ---------------------------------------------------------------------------- + + +void wxClassInfo::Register(const char *WXUNUSED(name), wxClassInfo *WXUNUSED(info)) +{ + /* + if (!ExtendedTypeMap) + ExtendedTypeMap = new ClassMap; + (*ExtendedTypeMap)[string(Name)] = Info; + */ +} + +void wxClassInfo::Unregister(const char *WXUNUSED(name)) +{ + /* + assert(ExtendedTypeMap); + ExtendedTypeMap->erase(Name); + */ +} + +const wxPropertyAccessor *wxClassInfo::FindAccessor(const char *PropertyName) +{ + const wxPropertyInfo* info = FindPropInfo( PropertyName ) ; + + if ( info ) + return info->GetAccessor() ; + + return NULL ; +} + +const wxPropertyInfo *wxClassInfo::FindPropInfo (const char *PropertyName) const +{ + const wxPropertyInfo* info = GetFirstProperty() ; + + while( info ) + { + if ( strcmp( info->GetName() , PropertyName ) == 0 ) + return info ; + info = info->GetNext() ; + } + + const wxClassInfo** parents = GetParents() ; + for ( int i = 0 ; parents[i] ; ++ i ) + { + if ( ( info = parents[i]->FindPropInfo( PropertyName ) ) != NULL ) + return info ; + } + + return 0; +} + +void wxClassInfo::SetProperty(wxObject *object, const char *propertyName, const wxxVariant &value) +{ + const wxPropertyAccessor *accessor; + + accessor = FindAccessor(propertyName); + wxASSERT(accessor->HasSetter()); + accessor->SetProperty( object , value ) ; +} + +wxxVariant wxClassInfo::GetProperty(wxObject *object, const char *propertyName) +{ + const wxPropertyAccessor *accessor; + + accessor = FindAccessor(propertyName); + wxASSERT(accessor->HasGetter()); + return accessor->GetProperty(object); +} + +/* +VARIANT TO OBJECT +*/ + +wxObject* wxxVariant::GetAsObject() const +{ + const wxClassTypeInfo *ti = dynamic_cast( m_data->GetTypeInfo() ) ; + if ( ti ) + return ti->GetClassInfo()->VariantToInstance(*this) ; + else + return NULL ; +} + + +#endif