You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.5 KiB
201 lines
6.5 KiB
#ifndef SCHEMA_H_
|
|
#define SCHEMA_H_
|
|
|
|
#include "basetypes.h" // for 'schema' define
|
|
|
|
#include "resourcefile/resourcestream.h"
|
|
#include "resourcefile/resourcefile.h"
|
|
#include "resourcefile/resourcetype.h"
|
|
|
|
class CResourceStructIntrospection;
|
|
|
|
#ifdef COMPILING_SCHEMA
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_DATA `__schema_class_marker_data__`
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_VIRTUAL `__schema_class_marker_virtual__`
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_ABSTRACT `__schema_class_marker_abstract__`
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_SIMPLE `__schema_class_marker_simple__`
|
|
#else
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_DATA
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_VIRTUAL
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_ABSTRACT
|
|
#define INTERNAL_SCHEMA_CLASS_MARKER_SIMPLE
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Pay no attention to the code behind the curtain
|
|
|
|
#define DECLARE_SCHEMA_CLASS_HELPER( _className, _bindingType ) \
|
|
friend class _bindingType < _className >; \
|
|
friend class CSchemaVerificationFor##_className; \
|
|
public: \
|
|
static _bindingType < _className > s_##_className##SchemaBinding; \
|
|
static const CResourceStructIntrospection *Schema_StaticBinding( ) { return (s_##_className##SchemaBinding).GetIntrospection(); }
|
|
|
|
#define DECLARE_SCHEMA_VIRTUAL_CLASS_HELPER( _className, _bindingType ) \
|
|
DECLARE_SCHEMA_CLASS_HELPER( _className, _bindingType ); \
|
|
public: \
|
|
virtual const CSchemaClassBindingBase *Schema_GetBinding( ) const { return &s_##_className##SchemaBinding; } \
|
|
const CResourceStructIntrospection *Schema_GetIntrospection( ) const { return Schema_GetBinding()->GetIntrospection(); }
|
|
|
|
#define DECLARE_SCHEMA_PLAIN_CLASS_HELPER( _className, _bindingType ) \
|
|
DECLARE_SCHEMA_CLASS_HELPER( _className, _bindingType ); \
|
|
public: \
|
|
const CSchemaClassBindingBase *Schema_GetBinding( ) const { return &s_##_className##SchemaBinding; } \
|
|
const CResourceStructIntrospection *Schema_GetIntrospection( ) const { return Schema_GetBinding()->GetIntrospection(); }
|
|
|
|
#define DEFINE_SCHEMA_CLASS_HELPER( _className, _bindingType ) \
|
|
_bindingType < _className > _className :: s_##_className##SchemaBinding( #_className );
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Data Classes (no vtable)
|
|
|
|
#define DECLARE_SCHEMA_DATA_CLASS( _className ) \
|
|
INTERNAL_SCHEMA_CLASS_MARKER_DATA \
|
|
DECLARE_SCHEMA_PLAIN_CLASS_HELPER( _className, CSchemaClassBinding )
|
|
|
|
#define DEFINE_SCHEMA_DATA_CLASS( _className ) DEFINE_SCHEMA_CLASS_HELPER( _className, CSchemaClassBinding )
|
|
|
|
///////////////////////////////////////
|
|
|
|
// Virtual Classes
|
|
|
|
#define DECLARE_SCHEMA_VIRTUAL_CLASS( _className ) \
|
|
INTERNAL_SCHEMA_CLASS_MARKER_VIRTUAL \
|
|
DECLARE_SCHEMA_VIRTUAL_CLASS_HELPER( _className, CSchemaClassBinding )
|
|
|
|
#define DEFINE_SCHEMA_VIRTUAL_CLASS( _className ) DEFINE_SCHEMA_CLASS_HELPER( _className, CSchemaClassBinding )
|
|
|
|
///////////////////////////////////////
|
|
|
|
// Abstract Classes
|
|
|
|
#define DECLARE_SCHEMA_ABSTRACT_CLASS( _className ) \
|
|
INTERNAL_SCHEMA_CLASS_MARKER_ABSTRACT \
|
|
DECLARE_SCHEMA_VIRTUAL_CLASS_HELPER( _className, CSchemaAbstractClassBinding )
|
|
|
|
#define DEFINE_SCHEMA_ABSTRACT_CLASS( _className ) DEFINE_SCHEMA_CLASS_HELPER( _className, CSchemaAbstractClassBinding )
|
|
|
|
///////////////////////////////////////
|
|
|
|
// Simple Classes
|
|
|
|
// For classes where you don't want to use a DEFINE_ macro
|
|
// - Only works for classes with no vtable.
|
|
// - If unserialized, it will be memzeroed rather than constructed
|
|
|
|
#define DECLARE_SCHEMA_SIMPLE_CLASS( _name ) \
|
|
INTERNAL_SCHEMA_CLASS_MARKER_SIMPLE \
|
|
const CResourceStructIntrospection *Schema_GetIntrospection( ) const { return g_pResourceSystem->FindStructIntrospection( #_name ); }
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
/*
|
|
template<class T> void Serialize( const T* pObj )
|
|
{
|
|
const CResourceStructIntrospection *pIntrospection = pObj ? pObj->Schema_GetIntrospection() : NULL;
|
|
SerializeGeneric( (const void*)pObj, pIntrospection );
|
|
}
|
|
|
|
template<class T> void Print( const T* pObj )
|
|
{
|
|
const CResourceStructIntrospection *pIntrospection = pObj ? pObj->Schema_GetIntrospection() : NULL;
|
|
PrintGeneric( (const void*)pObj, pIntrospection );
|
|
}
|
|
|
|
void SerializeGeneric( const void *pData, const CResourceStructIntrospection *pIntrospection );
|
|
void PrintGeneric( const void *pData, const CResourceStructIntrospection *pIntrospection );
|
|
*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class CSchemaClassBindingBase
|
|
{
|
|
public:
|
|
CSchemaClassBindingBase( const char* pClassName ):
|
|
m_pClassName(pClassName),
|
|
m_pIntrospection(NULL)
|
|
{
|
|
// Hook into the local class binding list
|
|
m_pNextBinding = sm_pClassBindingList;
|
|
sm_pClassBindingList = this;
|
|
}
|
|
|
|
inline const char* GetName() const
|
|
{
|
|
return m_pClassName;
|
|
}
|
|
|
|
virtual void ConstructInPlace( void* pMemory ) const = 0;
|
|
virtual void DestructInPlace( void* pMemory ) const = 0;
|
|
virtual int GetSize() const = 0;
|
|
|
|
const CResourceStructIntrospection *GetIntrospection() const;
|
|
static void Install();
|
|
|
|
protected:
|
|
const char *m_pClassName;
|
|
mutable const CResourceStructIntrospection *m_pIntrospection;
|
|
CSchemaClassBindingBase *m_pNextBinding;
|
|
|
|
static CSchemaClassBindingBase *sm_pClassBindingList;
|
|
};
|
|
|
|
template<class TSchemaClass> class CSchemaClassBinding: public CSchemaClassBindingBase
|
|
{
|
|
public:
|
|
CSchemaClassBinding( const char* pClassName ):
|
|
CSchemaClassBindingBase( pClassName )
|
|
{
|
|
// nop
|
|
}
|
|
|
|
virtual void ConstructInPlace( void* pMemory ) const
|
|
{
|
|
new(pMemory) TSchemaClass;
|
|
}
|
|
|
|
virtual void DestructInPlace( void* pMemory ) const
|
|
{
|
|
((TSchemaClass*)(pMemory))->~TSchemaClass();
|
|
}
|
|
|
|
virtual int GetSize() const
|
|
{
|
|
return sizeof(TSchemaClass);
|
|
}
|
|
};
|
|
|
|
template<class TSchemaClass> class CSchemaAbstractClassBinding: public CSchemaClassBindingBase
|
|
{
|
|
public:
|
|
CSchemaAbstractClassBinding( const char* pClassName ):
|
|
CSchemaClassBindingBase(pClassName)
|
|
{
|
|
// nop
|
|
}
|
|
|
|
virtual void ConstructInPlace( void* pMemory ) const
|
|
{
|
|
Error( "Cannot construct abstract class %s\n", m_pClassName );
|
|
}
|
|
|
|
virtual void DestructInPlace( void* pMemory ) const
|
|
{
|
|
Error( "Cannot destruct abstract class %s\n", m_pClassName );
|
|
}
|
|
|
|
virtual int GetSize() const
|
|
{
|
|
return sizeof(TSchemaClass);
|
|
}
|
|
};
|
|
|
|
#endif
|