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

📄 dotype.h

📁 The library provides supports for run-time loaded plugin classes in C++
💻 H
字号:
// Copyright (c) 2007, Arne Steinarson// Licensing for DynObj project - see DynObj-license.txt in this folder#ifndef DOTYPE_H#define DOTYPE_H#include  <stddef.h>	// NULL defined// Three main classes (in base to derived order)class VObj;class DynI;class DynObj;class DoModuleC;#include "utils/StructHeader.h"struct MIBSideType;#define DOT_SIDE_TYPE  SH_FLAG1/** @ingroup Utils * Different cast algorithms.  * An object with several base classes can be searched in different ways.  * This makes a difference if the current object is a sub-object of a larger * compound object.  * The default algorithm is DoCastCross, which allows for going moving to a compound * type once. */enum doCastAlgo {    /**  Look along main base line and among side bases.      * This cannot go from a side base to the main base*/	doCastLocal = 1,     /** Allow one jump to the compound object.     * This can jump from a side base to a main base once.*/	doCastCross = 2,     /** Cast from outermost object.      * Go to the outermost object and do exhaustive cast     * This will find a subobject wherever it is hidden      * in a nested side base. */	doCastFull = 3,  };// Create instances during setuptypedef void* (*InstVObjFn)(int *pvts);// Destroy instances during setuptypedef void (*DeInstVObjFn)(void *pv);// A structure to identify the type of the DynObj (or another type not derived// from DynObj).// All objects of the same class returns the same DynObjType - a static instance.//// Both _type_id and _type identify the type of the object (they say the// same thing). It's purpose is to more strongly identify the implemented// interface (if someone else has implemented your 'vehicle' class and you// accidently open that library, then chances are they have not given their// 'vehicle' class the type_id==0x51b7de00).//// When an interface needs to be expanded, instead of changing to a new type// one ticks the _version member one step forward and derives a new interface// class from the old one./** @ingroup Utils * Internal representation of a type. * This keeps all data representing the internals of a registered DynObjType. * All data fields are generated by the source compiler, allowing for using  * the correct object offsets in the hos application. */struct DynObjType{public:	// The "flags_version" argument has flags in 16 upper bits and version in 16 lower bits	DynObjType( const char *type, int type_id, int flags_version, int size, const void *_this=NULL, const void *_base_ptr=NULL );    void Ctor( const char *type, int type_id, int flags_version, int size, const void *_this, const void *_base_ptr );	~DynObjType( );		StructHeader _sh;   // Verifies that this is a DynObjType data struct	const char* _type;	// Name of the class/interface. Base class names are not present here.	int    _type_id;	// same as ID in CreateFn 	int    _size;		// sizeof(DynObj) - size of an object of this type 	short  _version;	// Version of the implemented type 	short  _offset;     // Offset - for multiple and virtual inheritence 	short  _vtbl_size;  // Number of entries in VTable or -1 if not known 	short  _flags;      // See below 	//protected: 	DynObjType*   _base;	   // Base type (primary) 	void**        _vtbl;       // VTable for this type or NULL if unknown or an object with no virtual funcs 	MIBSideType*  _base_side;  // With multiple inheritence, first side base type	DoModuleC*    _module;     // The module that creates this type, allows for tracking back an object	                           // on destruction.    DynObjType*  _idc_prv;  // Previous DynObjType with same ID     DynObjType*  _idc_nxt;  // Next DynObjType with same ID    InstVObjFn   _cdofn;    // Used if instantiating objects during setup    DeInstVObjFn _dcdofn;   // Used if instantiating objects during setup 	 		bool operator == (const char *type) const;	bool operator == (void **vtbl) const { return vtbl && vtbl==_vtbl; }	bool operator == (int type_id) const { return type_id==_type_id; }	bool IsA( int type_id ) const;	bool CanBeA( int type_id ) const;	bool IsSideBase() const { return _sh.Flags()&DOT_SIDE_TYPE ? true : false; }    DynObjType *GetOuterMost() const;    DynObjType *GetTypeAtOffset( int off ) const;			// This is for hashing.	inline void** GetKey( ){ return (void**)_vtbl; }	protected:		// Exhaustive GetObj (tries all sub types recursively)	void *GetObjExh( void *pself, const char *type, DynObjType **found_type=NULL );	void *GetObjExh( void *pself, int type_id, DynObjType **found_type=NULL );	// Only tries main line and side line (direct bases and direct side bases)	void *GetObj( void *pself, const char *type, DynObjType **found_type=NULL );	void *GetObj( void *pself, int type_id, DynObjType **found_type=NULL );    	bool CanBeAInternal( int type_id ) const;        friend void* doGetObj( void *obj, const char *type, DynObjType *self_type, doCastAlgo algo, DynObjType **pdt_found );    friend void* doGetObj( void *obj, int type_id, DynObjType *self_type, doCastAlgo algo, DynObjType **pdt_found );    friend void* doGetObj( DynI *pdi, const char *type, doCastAlgo algo, DynObjType **pdt_found, bool internal_from_dyni );};#ifdef DO_IMPLEMENTING// For flags field#define DOT_DID_INIT 		1  // Type initialized & registered (after calling doConstruct & DORT.RegisterType)#define DOT_DESTROY_SOFT	2  // For DynObj type, in a sub object, set DoDostroy to harmless method #define DOT_USER_TYPE 		4  // A user type (not internal, abstract or side base). Can be instantiated.#define DOT_NO_VTABLE_CORR 	8  // Do not correct VTable for this type#define DOT_STATIC_TYPE 	16 // Instances of this type are static#if DO_ENABLE_VTABLE_CORR==1	#include "DoVTableInfo.hpp" #endif// Helper function to get instance of DynI/Vobj derived template<class T>void* VObjTempInstance( int *pvts ){#if DO_ENABLE_VTABLE_CORR==1    if( pvts )  *pvts = GetVTableSizeOf<T,void>();#endif    return new T;}template<class T>void VObjTempInstanceDelete( void *pv ){    ::delete (T*)pv;}// Helper to get temp instance of DynObj derivedclass DynI;template<class T>void* DynObjTempInstance( int *pvts ){#if DO_ENABLE_VTABLE_CORR==1    if( pvts ) *pvts = GetVTableSizeOf<T,DynI*>();#endif            return new T((DynI*)NULL);}// This is for the case when we instantiate a class to register it in the // global constructor. The condition for doing this is that it has a // constructor that takes no arguments (VObj/DynI derived) or that it has // a DynObj constructor (one argument of type DynI*).// This saves us from the trouple of calling doConstruct manually at a // later point.//#include <stdio.h>template<class MainCl, class BaseCl=void, bool is_dynobj=false>class DynObjTypeI2R;// Specialization for DynObj derivedtemplate<class MainCl, class BaseCl>class DynObjTypeI2R<MainCl,BaseCl,true> : public DynObjType {public:	DynObjTypeI2R( const char *type, int type_id, int flags_version ) 	: DynObjType( type, type_id, flags_version, sizeof(MainCl) ) {        _cdofn = (InstVObjFn)DynObjTempInstance<MainCl>;        _dcdofn = VObjTempInstanceDelete<MainCl>;        /*		MainCl mc;	// Local instance here		_offset = short((char*)static_cast<BaseCl*>(&mc) - (char*)&mc);#if DO_ENABLE_VTABLE_CORR==1		_vtbl_size = GetVTableSizeOf<MainCl>( );#endif		_vtbl = *(void***)&mc;        */	}};// Specialization for VObj & DynI derivedtemplate<class MainCl, class BaseCl>class DynObjTypeI2R<MainCl,BaseCl,false> : public DynObjType {public:	DynObjTypeI2R( const char *type, int type_id, int flags_version ) 	: DynObjType( type, type_id, flags_version, sizeof(MainCl) ) {        _cdofn = VObjTempInstance<MainCl>;        _dcdofn = VObjTempInstanceDelete<MainCl>;    }};// For multiple inheritence, this represents a side base type// It sets the _sh flag DOT_SIDE_TYPE in the constructor. // NOTE: Side base types are separate types in themselves (if it has virtual funcs)// For A : public B, public C { }  we have the distinct types A, B, C, C[A]// C[A] is generated automatically struct MIBSideType : public DynObjType {	MIBSideType( DynObjType *compound, short offset, const char *type, int type_id, int ver, int size, const void *_this, int vtbl_size );	DynObjType* _compound;	// The main type (where this type is always a side base)};// To get offset to side bases in a type safe way template <class Base, class SideBase>int sidebase_offset( const Base *pb=NULL ){	// It seems static_cast wants non-zero values to do its job of	// converting on known class type offsets, even though it doesn't	// use RTTI info. If NULL input, use arbitrary address	if( !pb ) pb = reinterpret_cast<const Base*>(&pb);	const SideBase *pcb = static_cast<const SideBase*>(pb);	return (int)(reinterpret_cast<const char*>(pcb) - reinterpret_cast<const char*>(pb));}// Used when declaring side base classesclass SideBaseDecl {public:	SideBaseDecl( const char *main_cl, const char *side_base_cl, int size, int off, const void *_this, int vtbl_size, void **vtbl_o )         { Ctor(main_cl, side_base_cl, size, off, _this, vtbl_size, vtbl_o); }    void Ctor( const char *main_cl, const char *side_base_cl, int size, int off, const void *_this, int vtbl_size, void **vtbl_o );};// Macro to add side base classes in a type safe way #define DO_ADD_SIDE_BASE(MainCl,SideBaseCl)\		SideBaseDecl g_sbd_##MainCl##SideBaseCl( #MainCl,#SideBaseCl,sizeof(SideBaseCl),sidebase_offset<MainCl,SideBaseCl>(),NULL,GetVTableSizeOf<SideBaseCl>(),GetVTableOf<SideBaseCl>() )// Macro to add side base classes in a type safe way inside doGetType (using this pointer)// Used inside doGetType. Does not detect size of VTables.// Forces doGetType on Side base class #define DO_ADD_SIDE_BASE_THIS(MainCl,SideBaseCl) { \		this->SideBaseCl::doGetType( const DynI **pself=0 ); \		static SideBaseDecl sbdt(#MainCl,#SideBaseCl,sizeof(SideBaseCl),sidebase_offset<MainCl,SideBaseCl>(this),this,-1,NULL); \	}// Macro to add side base classes in a type safe way inside doGetType (using this pointer)// Used inside doGetType. Detects size of VTables.// Forces doGetType on Side base class #define DO_ADD_SIDE_BASE_THIS_VTABLE_CORR(MainCl,SideBaseCl) { \		this->SideBaseCl::doGetType( const DynI **pself=0 ); \		static SideBaseDecl sbdt(#MainCl,#SideBaseCl,sizeof(SideBaseCl),sidebase_offset<MainCl,SideBaseCl>(this),this,GetVTableSizeOf<SideBaseCl>(),GetVTableOf<SideBaseCl>()); \	}#endif // DO_IMPLEMENTING #endif // DOTYPE_H 

⌨️ 快捷键说明

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