⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynobj.h

📁 The library provides supports for run-time loaded plugin classes in C++
💻 H
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 2007, Arne Steinarson// Licensing for DynObj project - see DynObj-license.txt in this folder#ifndef DYNOBJ_H#define DYNOBJ_H// These are directives to preprocessing tool that auto-generates some of the required code	// %%DYNOBJ	options generate(implement)	// Defines and config options are in here#include "DoSetup.h"// Type system#include "DoType.h"// Error logging#include "DoError.h"// Preprocessor symbols controlling how DynObj.h and related files://// DO_IMPLEMENTING    - from a C++ source file that implements a DynObj// DO_MAIN            - from the main program (that loads other DynObjs and has the DoRunTimeI instance)// DO_MODULE          - Set when compiling a library/loadable module (that does not own DoRunTimeI)// DO_IMPLEMENTED_TYPES - Define before compiling DynObj.cpp to set to a list of implemented//                        type names /type IDs. This how types are made 'public'. Example////                            "string,0xB314DA4,Car:VehicleI,0xBA618F23"////                        Another method is to use doAddImplemented or global instances of//                        class DoImplDecl (later this file).//                        #ifdef DO_MODULE	#ifdef DO_MAIN 		#error Both DO_MODULE and DO_MAIN are defined (only one should be)	#endif#elif defined(DO_MAIN)	// Fine, do nothing#else	// Proceed until the defs are needed, give warning there#endif// Doxygen stuff/** @defgroup DynI DynI derived classes *//** @defgroup VObj VObj interfaces and base classes (not derived from DynI) *//** @defgroup ImplClass Other classes *//** @defgroup DynI derived classes *//** @defgroup Utils Global functions, enums *//** @defgroup Library Library interface and setup *//** @defgroup DynTemplate Central DynI templates *//** @defgroup DynDefs DynObj defines */// Object IDs: // They can be generated automatically from the "pdoh" tool (Parse DynObj Header). // Layout of ID:// Bit 0..7   - Set to 0 for now// Bit 8..30  - Custom type ID// Bit 31     - Set for user-type without VTable // Custom IDs start at BASE_CUSTOM_TYPE_ID (0x10000)// The next one is 0x10100, 0x10200, and so on#define TYPE_ID_MASK          0xFFFFF000        // Bits 12..31// Base type IDs: - They should probably be positive#define SIDEBASE_TYPE_ID	  0xFFFFF000		// All side bas classes have this type ID (cannot be addressed individually from outside)#define OUTERMOST_TYPE_ID	  0xFFFFD000		// When casting to the outermost object (the container object) (string OUTERMOST)#define COMPOUND_TYPE_ID	  0xFFFFE000		// When casting to a compound object (the container object) (string COMPOUND)#define INVALID_TYPE_ID       0xFFFFF000        // Just same as unknown for now#define UNKNOWN_TYPE_ID	      0					// Hmmm...#define VOBJ_TYPE_ID          0x00001000#define DYNI_TYPE_ID          0x00002000#define DYNOBJ_TYPE_ID        0x00003000#define DYNSHAREDI_TYPE_ID    0x00004000#define DYNDATA_TYPE_ID       0x00006000#define RTDYNSHARED_TYPE_ID   0x00008000#define DORUNTIMEI_TYPE_ID    0x00010000#define DORTINTERNALI_TYPE_ID 0x00011000#define DOMODULEC_TYPE_ID     0x00012000#define DORT_TYPE_ID          DORUNTIMEI_TYPE_ID#define DYNSTR_TYPE_ID        0x00013000#define DYNARRCHAR_TYPE_ID      0x00020000#define DYNARRSHORT_TYPE_ID     0x00021000#define DYNARRINT_TYPE_ID       0x00022000#define DYNARRINT64_TYPE_ID     0x00023000#define DYNARRPTR_TYPE_ID       0x00024000#define DYNARRPTR_VOBJ_TYPE_ID  0x00025000#define DYNARRPTR_DYNI_TYPE_ID  0x00026000#define NOTIFIERI_TYPE_ID     0x00030000#define NOTIFIABLEI_TYPE_ID   0x00031000#define NOTDATAI_TYPE_ID      0x00032000#define BASE_CUSTOM_TYPE_ID   0x00100000#define STEP_TYPE_ID          0x00001000    // How much to increment for each type#if DO_NO_TYPEINFO!=1/** Translate C++ type to type string and type ID. * This provides a way to get type ID and type name for any known (registered) class.  * Implement for each class that is exposed. See DO_DECL_TYPE_INFO further down.*/template<class T>struct doTypeInfo {	static int Id( ){ return UNKNOWN_TYPE_ID; }	static const char* Name( ){ return NULL; }	//enum { TypeId=INVALID_TYPE_ID };};/// @cond internal//  Peels off pointertemplate<class T>struct doTypeInfo<T*> {public:	static int Id( ){ return doTypeInfo<T>::Id(); }	static const char* Name( ){ return doTypeInfo<T>::Name(); }	//enum { TypeId=doTypeInfo<T>::TypeId };};//  Peels off reftemplate<class T>struct doTypeInfo<T&> {public:	static int Id( ){ return doTypeInfo<T>::Id(); }	static const char* Name( ){ return doTypeInfo<T>::Name(); }	//enum { TypeId=doTypeInfo<T>::TypeId };};// Peels off consttemplate<class T>struct doTypeInfo<const T> {public:	static int Id( ){ return doTypeInfo<T>::Id(); }	static const char* Name( ){ return doTypeInfo<T>::Name(); }	//enum { TypeId=doTypeInfo<T>::TypeId };};#endif //DO_NO_TYPEINFO/// @endcond internal        //squRegisterMemberFn( sd.v, sd.newClass.GetObjectHandle(), sqbVObj_GetObj, _T("GetObj") );#if DO_FAT_VOBJ==1// Need this proto belowvoid* doGetObj( void* pobj, const char *type, DynObjType *self_type, doCastAlgo algo=doCastCross, DynObjType **found_type=NULL );void* doGetObj( void* pobj, int type_id, DynObjType *self_type, doCastAlgo algo=doCastCross, DynObjType **found_type=NULL );void* doGetObj( DynI* pdi, const char *type, doCastAlgo algo=doCastCross, DynObjType **found_type=NULL );void* doGetObj( DynI* pdi, int type_id, doCastAlgo algo=doCastCross, DynObjType **found_type=NULL );DynObjType* doGetType( const void* pobj );DynObjType* doGetType( const DynI* pdi );#endif/** @ingroup VObj  * This is the 'stipulated' base class for objects with virtual functions. *  * In this class the virtual functions (number of them, signatures) are not known. * It only promises that it has a VTable, and we can do type lookups from that. * VObjs can be used when we have C++ classes that don't derive from DynI. * Objects of type VObj are not created, but one can get pointers to them through * casts/queries (doGetVObj).  */// %%DYNOBJ class(vobj)                <- Tag for header file preprocessing  class VObj {public:    // With fat VObj we get a lot of non-virtual convenience functions for the base class.     // NOTE: Requires static linking (to DynObj.cpp)    #if DO_FAT_VOBJ==1    /** @name Non-virtuals      *  Functions included with DO_FAT_VOBJ define */    //@{        /** Returns type structure for this object.     * Does a global lookup using object VPTR.    */	DynObjType* GetType( ) const;	    /** Test if object is of a certain type ID      * IsA returns true if the requested type can be returned without      * adjusting the 'this' pointer (must be main base class).     */	bool IsA( int type_id ) const       { return IsA(type_id,NULL); }        /** Test if object 'can be' of a certain type ID      * CanBeA returns true if the requested type is available as any base     * class of the object (main base or side base).     */	bool CanBeA( int type_id ) const    { return CanBeA(type_id,NULL); }        /** Same as IsA but using type string */     // Lookup is not done on custom addon types.	bool IsA( const char *type ) const  { return IsA(type,NULL); }	//bool CanBeA( const char *type )     { return CanBeA(type,NULL); }    /** Raw cast, lookup internal type by type ID. */    void* GetObj( int type_id, doCastAlgo algo=doCastCross ) { return ::doGetObj(this,type_id,NULL,algo); }    /** Raw cast, lookup internal type by type string. */    void* GetObj( const char *type, doCastAlgo algo=doCastCross ) { return ::doGetObj(this,type,NULL,algo); }    /** Returns current error string for object or NULL if no error     * @param perr_code a location to store the error code, default is NULL     * @return The error string or NULL if no error.      */    const char* GetError( int* perr_code=NULL ) const;        /** This will clear the error state for the object if set */    void ClearError( );        /** Set the internal error state for the object */    bool SetError( const char *err_str, int err_code=-1 ) const;	bool IsA( int type_id, DynObjType *ptype ) const;	bool CanBeA( int type_id, DynObjType *ptype ) const;	bool IsA( const char *type, DynObjType *ptype ) const;	//bool CanBeA( const char *type, DynObjType *ptype  );	const char *GetTypeName( ) const { 		DynObjType *pdt = ::doGetType(this);		return pdt ? pdt->_type : NULL; 	}    /** Check if object exists and has no errors      * Check if 'this' is non-NULL and that object has no error      */	bool IsOk( ) const { return this && !GetError(); }     //@}    #endif // DO_FAT_VOBJ};/** @ingroup DynI  * The effective root class of the DynObj library. * * This is the base type representing objects, interfaces and sub-objects  * created by the DynObj package. In itself it is an interface. It knows its * own type and can be queried for custom owned objects. * * For compatibility with MSVC++, the member function calling convention 'docall'  * must be put between the return type and the function name: *   virtual int ->docall<- MyFunc( int i ); */// %%DYNOBJ class(dyni)             <- Tag for header file preprocessing class DynI : public VObj {public:    /** @name Virtuals     *  Interface members */    //@{        /** Returns type of this object.    * Each type that wants to make itself known should override this method.    * DynI knows its own type so we get the type without any lookup.     * It is faster and works without registration.     *    * @param pself allows fetching the actual 'this' used inside doGetType    * (from a side base, this will be different to the 'this' of the caller).    * @return A DynObjType pointer    */	virtual DynObjType* docall doGetType( const DynI **pself=NULL ) const;	   /** 'Smart cast' (parallel to QueryInterface) used to retrieve another     * interface or sub-object that the object supports.      * The default implementation of doGetObj traverses the registered main and side     * base classes for the object and returns any match found there. This is the same     * search as done when querying for types using type IDs.     *     * A derived version can also check the argument type string and return a pointer     * to an owned object that is not a base class (custom types). The rule is that the      * returned object should have the same life span as this one, they are part of the      * same compound object.      * 	 * When overriding this method, and not returning a custom object directly, one should      * call the immediate base class version. Then, after traversing the inheritance chain,      * the call will end up in the base version DynI::doGetObj. There, the call will be      * made to check for any registered base class types.     *     * For versions with type safety, use do_cast or do_cast_str.     *      * @return A pointer to the found interface/internal object.    */	virtual void* docall doGetObj( const char *type );		// Works for all objects, even data structures    /** Returns current error string for object or NULL if no error.     * Object errors are used to handle errors that are not detected through return      * codes, i.e. exceptions. The default implementation uses DoRunTime for this. Errors      * are unique to the object but stored outside of it. No memory is used for this until      * an error is set.     * @param perr_code a location to store the error code, default is NULL     * @return The error string or NULL if no error.      */    virtual const char* docall doGetError( int* perr_code=NULL ) const;    /** This will clear the error state for the object if set */    virtual void docall docall doClearError( );    //@}    #if DO_FAT_VOBJ==1    /** @name Inlines     *  Inline convenience functions */    //@{     	// Convenience functions for accesing DynI type info	// Non virtual, inline, generated on both sides, therefore OK 	DynObjType *GetType()         const { return ::doGetType(this); }	bool        IsOk( )       	  const { return this && !doGetError(); } 	const char *GetTypeName( )    const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_type : NULL; }	int         GetTypeId( )      const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_type_id : -1; }	int         GetTypeVersion( ) const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_version : -1; }	int         GetObjectSize( )  const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_size : -1; }	bool IsA( int type_id )            const { return VObj::IsA( type_id, DI_GET_TYPE(this) ); }	bool CanBeA( int type_id )         const { return VObj::CanBeA( type_id, DI_GET_TYPE(this) ); }	bool IsA( const char *type )       const { return VObj::IsA( type, DI_GET_TYPE(this) ); }	//bool CanBeA( const char *type )     { return VObj::CanBeA( type, DI_GET_TYPE(this) ); }        /** Raw cast, lookup internal type by type ID. */    void* GetObj( int type_id, doCastAlgo algo=doCastCross ) { return ::doGetObj(this,type_id,algo); }    /** Raw cast, lookup internal type by type string. */    void* GetObj( const char *type, doCastAlgo algo=doCastCross ) { return ::doGetObj(this,type,algo); }    //@}	    /** @name Others     *  Other member functions */    //@{ 	// This is only intended for user of a DynObj to be able to use ordinary	// delete on the object and route the call back to the creator. 	// NOTE: When an application defines its own operator new and/or redefines	// the new/delete keywords (to support memory tracking), this may not work.	// To be safe its best to call doDestroy directly from the app.    #if DO_ENABLE_OPERATOR_DELETE==1 	void operator delete( void *pv ){         SetError( "DynObj::operator delete on a DynI", DOERR_DELETE_ON_DYNI );	}    #endif // DO_ENABLE_OPERATOR_DELETE    //@}    #endif // DO_FAT_VOBJ};// Used as a NULL object #define DynINull (*(DynI*)(0))/** @ingroup DynI  * This class represents objects that can be created and destroyed. It is the  * type of new objects created (from type names/type IDs). To destroy a DynObj,  * the function doDestroy is used.  */// %%DYNOBJ class(dyni)                   <- Tag for header file preprocessing class DynObj : public DynI {public:    /** @name Virtuals     *  Interface members */    //@{     	// All DynI derived types overrides this	virtual DynObjType* docall doGetType( const DynI **pself=0 ) const;	   /** doDestroy is invoked by the owner to delete it.     * An implementation should both call its own most derived C++ destructor and     * the object memory. A typical implementation would be:	*   MyClass::doDestroy(){ ::delete this; }    */	virtual void    docall doDestroy( ) { };

⌨️ 快捷键说明

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