xti.h

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C头文件 代码 · 共 1,688 行 · 第 1/5 页

H
1,688
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        wx/xti.h
// Purpose:     runtime metadata information (extended class info)
// Author:      Stefan Csomor
// Modified by:
// Created:     27/07/03
// RCS-ID:      $Id: xti.h,v 1.57 2005/03/08 09:51:20 ABX Exp $
// Copyright:   (c) 1997 Julian Smart
//              (c) 2003 Stefan Csomor
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_XTIH__
#define _WX_XTIH__

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#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/flags.h"
#include "wx/string.h"
#include "wx/arrstr.h"
#include "wx/hashmap.h"
#include "wx/log.h"
#include  "wx/intl.h"

#include <typeinfo>

// we will move this later to defs.h

#if defined(__GNUC__) && !wxCHECK_GCC_VERSION( 3 , 4 )
#  define wxUSE_MEMBER_TEMPLATES 0
#endif

#if defined(_MSC_VER) && _MSC_VER <= 1200
#  define wxUSE_MEMBER_TEMPLATES 0
#  define wxUSE_FUNC_TEMPLATE_POINTER 0
#endif

#ifndef wxUSE_MEMBER_TEMPLATES
#  define wxUSE_MEMBER_TEMPLATES 1
#endif

#ifndef wxUSE_FUNC_TEMPLATE_POINTER
#  define wxUSE_FUNC_TEMPLATE_POINTER 1
#endif

#if wxUSE_MEMBER_TEMPLATES
#  define wxTEMPLATED_MEMBER_CALL( method , type ) method<type>()
#  define wxTEMPLATED_MEMBER_FIX( type )
#else
#  define wxTEMPLATED_MEMBER_CALL( method , type ) method((type*)NULL)
#  define wxTEMPLATED_MEMBER_FIX( type ) type* =NULL
#endif

#if defined(_MSC_VER) && _MSC_VER <= 1200
#  define wxTEMPLATED_FUNCTION_FIX( type ) , wxTEMPLATED_MEMBER_FIX(type)
#  define wxINFUNC_CLASS_TYPE_FIX( type ) typedef type type;
#else
#  define wxTEMPLATED_FUNCTION_FIX( type )
#  define wxINFUNC_CLASS_TYPE_FIX( type )
#endif

#define EMPTY_MACROVALUE /**/

class WXDLLIMPEXP_BASE wxObject;
class WXDLLIMPEXP_BASE wxClassInfo;
class WXDLLIMPEXP_BASE wxDynamicClassInfo;
class WXDLLIMPEXP_BASE wxHashTable;
class WXDLLIMPEXP_BASE wxObjectRefData;
class WXDLLIMPEXP_BASE wxEvent;
class WXDLLIMPEXP_BASE wxEvtHandler;

typedef void (wxObject::*wxObjectEventFunction)(wxEvent&);

#if wxUSE_FUNC_TEMPLATE_POINTER
#  define wxTO_STRING(type) wxToStringConverter<type>
#  define wxTO_STRING_IMP(type)
#  define wxFROM_STRING(type) wxFromStringConverter<type>
#  define wxFROM_STRING_IMP(type)
#else
#  define wxTO_STRING(type) ToString##type
#  define wxTO_STRING_IMP(type) inline void ToString##type( const wxxVariant& data , wxString &result ) { wxToStringConverter<type>(data, result); }
#  define wxFROM_STRING(type) FromString##type
#  define wxFROM_STRING_IMP(type) inline void FromString##type( const wxString& data , wxxVariant &result ) { wxFromStringConverter<type>(data, result); }
#endif

// ----------------------------------------------------------------------------
// 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 :
//
// wxBEGIN_ENUM( wxFlavor )
//   wxENUM_MEMBER( Vanilla )
//   wxENUM_MEMBER( Chocolate )
//   wxENUM_MEMBER( Strawberry )
// wxEND_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 ) const ;

    // 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 ) const ;

    // returns the name of the enum member having the passed in value
    // returns an emtpy string if not found
    const wxChar *GetEnumMemberName(int value) const ;

    // returns the number of members in this enum
    int GetEnumCount() const { return m_count ; }

    // returns the value of the nth member
    int GetEnumMemberValueByIndex( int n ) const ;

    // returns the value of the nth member
    const wxChar *GetEnumMemberNameByIndex( int n ) const ;
private :
    wxEnumMemberData *m_members;
    int m_count ;
};

#define wxBEGIN_ENUM( e ) \
    wxEnumMemberData s_enumDataMembers##e[] = {

#define wxENUM_MEMBER( v ) { wxT(#v), v } ,

#define wxEND_ENUM( e ) { NULL , 0 } } ; \
    wxEnumData s_enumData##e( s_enumDataMembers##e ) ; \
    wxEnumData *wxGetEnumData(e) { return &s_enumData##e ; } \
    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) ; \
} \
    void FromLong##e( long data , wxxVariant& result ) { result = wxxVariant((e)data) ;} \
    void ToLong##e( const wxxVariant& data , long &result ) { result = (long) data.wxTEMPLATED_MEMBER_CALL(Get , e) ;} \
    wxTO_STRING_IMP( e ) \
    wxFROM_STRING_IMP( e ) \
    wxEnumTypeInfo s_typeInfo##e(wxT_ENUM , &s_enumData##e , &wxTO_STRING( e ) , &wxFROM_STRING( e ) , &ToLong##e , &FromLong##e , typeid(e).name() ) ;

// ----------------------------------------------------------------------------
// Set Support
//
// in the header :
//
// enum wxFlavor
// {
//  Vanilla,
//  Chocolate,
//  Strawberry,
// };
//
// typedef wxBitset<wxFlavor> wxCoupe ;
//
// in the implementation file :
//
// wxBEGIN_ENUM( wxFlavor )
//  wxENUM_MEMBER( Vanilla )
//  wxENUM_MEMBER( Chocolate )
//  wxENUM_MEMBER( Strawberry )
// wxEND_ENUM( wxFlavor )
//
// wxIMPLEMENT_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 WXDLLIMPEXP_BASE wxSetStringToArray( const wxString &s , wxArrayString &array ) ;

template<typename e>
void wxSetFromString(const wxString &s , wxBitset<e> &data )
{
    wxEnumData* edata = wxGetEnumData((e) 0) ;
    data.reset() ;

    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<typename e>
void wxSetToString( wxString &s , const wxBitset<e> &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.test( value ) )
        {
            // this could also be done by the templated calls
            if ( !s.empty() )
                s +=wxT("|") ;
            s += edata->GetEnumMemberNameByIndex(i) ;
        }
    }
}

#define wxIMPLEMENT_SET_STREAMING(SetName,e) \
    template<>  void wxStringReadValue(const wxString &s , wxBitset<e> &data ) \
{ \
    wxSetFromString( s , data ) ; \
} \
    template<>  void wxStringWriteValue( wxString &s , const wxBitset<e> &data ) \
{ \
    wxSetToString( s , data ) ; \
} \
    void FromLong##SetName( long data , wxxVariant& result ) { result = wxxVariant(SetName((unsigned long)data)) ;} \
    void ToLong##SetName( const wxxVariant& data , long &result ) { result = (long) data.wxTEMPLATED_MEMBER_CALL(Get , SetName).to_ulong() ;} \
    wxTO_STRING_IMP( SetName ) \
    wxFROM_STRING_IMP( SetName ) \
    wxEnumTypeInfo s_typeInfo##SetName(wxT_SET , &s_enumData##e , &wxTO_STRING( SetName ) , &wxFROM_STRING( SetName ) , &ToLong##SetName , &FromLong##SetName, typeid(SetName).name() ) ;  \
}

template<typename e>
void wxFlagsFromString(const wxString &s , e &data )
{
    wxEnumData* edata = wxGetEnumData((e*) 0) ;
    data.m_data = 0 ;

    wxArrayString array ;
    wxSetStringToArray( s , array ) ;
    wxString flag;
    for ( size_t i = 0 ; i < array.Count() ; ++i )
    {
        flag = array[i] ;
        int ivalue ;
        if ( edata->HasEnumMemberValue( flag , &ivalue ) )
        {
            data.m_data |= ivalue ;
        }
    }
}

template<typename e>
void wxFlagsToString( wxString &s , const e& data )
{
    wxEnumData* edata = wxGetEnumData((e*) 0) ;
    int count = edata->GetEnumCount() ;
    int i ;
    s.Clear() ;
    long dataValue = data.m_data ;
    for ( i = 0 ; i < count ; i++ )
    {
        int value = edata->GetEnumMemberValueByIndex(i) ;
        // make this to allow for multi-bit constants to work
        if ( value && ( dataValue & value ) == value )
        {
            // clear the flags we just set
            dataValue &= ~value ;
            // this could also be done by the templated calls
            if ( !s.empty() )
                s +=wxT("|") ;
            s += edata->GetEnumMemberNameByIndex(i) ;
        }
    }
}

#define wxBEGIN_FLAGS( e ) \
    wxEnumMemberData s_enumDataMembers##e[] = {

#define wxFLAGS_MEMBER( v ) { wxT(#v), v } ,

#define wxEND_FLAGS( e ) { NULL , 0 } } ; \
    wxEnumData s_enumData##e( s_enumDataMembers##e ) ; \
    wxEnumData *wxGetEnumData(e*) { return &s_enumData##e ; } \
    template<>  void wxStringReadValue(const wxString &s , e &data ) \
{ \
    wxFlagsFromString<e>( s , data ) ; \
} \
    template<>  void wxStringWriteValue( wxString &s , const e& data ) \
{ \
    wxFlagsToString<e>( s , data ) ; \
} \
    void FromLong##e( long data , wxxVariant& result ) { result = wxxVariant(e(data)) ;} \
    void ToLong##e( const wxxVariant& data , long &result ) { result = (long) data.wxTEMPLATED_MEMBER_CALL(Get , e).m_data ;} \
    wxTO_STRING_IMP( e ) \
    wxFROM_STRING_IMP( e ) \
    wxEnumTypeInfo s_typeInfo##e(wxT_SET , &s_enumData##e , &wxTO_STRING( e ) , &wxFROM_STRING( e ) , &ToLong##e , &FromLong##e, typeid(e).name()  ) ;
// ----------------------------------------------------------------------------
// Type Information
// ----------------------------------------------------------------------------
//

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?