Big changes
This commit is contained in:
@@ -10,7 +10,6 @@ public:
|
||||
static void Error(const char* msg, ...);
|
||||
};
|
||||
|
||||
#define Msg Logger::LogPrint
|
||||
#define LogMsg Logger::LogPrint
|
||||
|
||||
#endif // !LOGGER_H
|
||||
|
||||
@@ -25,4 +25,15 @@ struct Point2
|
||||
int y;
|
||||
};
|
||||
|
||||
struct Vec3
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
|
||||
Vec3() { x = y = z = 0.f; }
|
||||
Vec3(float value) { x = y = z = value; }
|
||||
Vec3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; }
|
||||
};
|
||||
|
||||
#endif // !MATHS_H
|
||||
|
||||
@@ -1,141 +1,66 @@
|
||||
/*
|
||||
|
||||
The other day we tracked a bad bug where a base class was been cast to
|
||||
the wrong thing.
|
||||
The reason why it happed was because we didn't have any RTTI (Run Time
|
||||
Type Information) in place.
|
||||
We also didn't want to use the one that it comes with the compiler for
|
||||
fear that it will add "evil" code.
|
||||
So after hitting that bug I decided to do my on RTTI. I wanted to be
|
||||
simple and very fast.
|
||||
This is what we use now. It looks kind of neat so I thought to share it.
|
||||
Enjoy.
|
||||
|
||||
Tomas
|
||||
tarce@zen-x.net
|
||||
|
||||
*/
|
||||
#ifndef RTTI_H
|
||||
#define RTTI_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
//==============================================================================
|
||||
// RTTI
|
||||
//==============================================================================
|
||||
// Using the RTTI
|
||||
//------------------------------------------------------------------------------
|
||||
// struct base
|
||||
// {
|
||||
// CREATE_RTTI_BASE( base );
|
||||
// };
|
||||
//
|
||||
// struct pepe : public base
|
||||
// {
|
||||
// CREATE_RTTI( pepe, base, base )
|
||||
// void Normal( void ){}
|
||||
// };
|
||||
//
|
||||
// struct super_pepe : public pepe
|
||||
// {
|
||||
// CREATE_RTTI( super_pepe, pepe, base )
|
||||
// void Super( void ){}
|
||||
// };
|
||||
//
|
||||
// void main( void )
|
||||
// {
|
||||
// super_pepe SP; // The original class
|
||||
// base& B = SP; // Some generic base reference
|
||||
//
|
||||
// // We want to safely convert to pepe
|
||||
// pepe& P = pepe::GetSaveType( B );
|
||||
//
|
||||
// // cast the base class right
|
||||
// if( B.IsKindOf( super_pepe::GetRTTI() ) )
|
||||
// {
|
||||
// super_pepe& SP = super_pepe::GetSaveType( B );
|
||||
// SP.Super();
|
||||
// }
|
||||
// else if( B.IsKindOf( pepe::GetRTTI() ) )
|
||||
// {
|
||||
// pepe& P = pepe::GetSaveType( B );
|
||||
// P.Normal();
|
||||
// }
|
||||
// }
|
||||
//==============================================================================
|
||||
#define CREATE_RTTI( TYPE, BASE_CLASS )
|
||||
#define CREATE_RTTI_BASE( TYPE )
|
||||
|
||||
struct RTTI
|
||||
struct RuntimeClass
|
||||
{
|
||||
bool IsKindOf( const RTTI& RTTI ) const;
|
||||
RTTI ( const char* pTypeName );
|
||||
RTTI ( const char* pTypeName, const RTTI& RTTI );
|
||||
|
||||
const char* pType; // This is not really need it, just useful in debugger.
|
||||
const RTTI& Next;
|
||||
bool IsKindOf(const RuntimeClass* pRuntimeClass) const;
|
||||
RuntimeClass(const char* pClassName);
|
||||
RuntimeClass(const char* pClassName, const RuntimeClass* pBaseClass);
|
||||
|
||||
const char* m_pClassName;
|
||||
const RuntimeClass* m_pBaseClass;
|
||||
};
|
||||
|
||||
|
||||
#define DECLARE_RTTI \
|
||||
static RuntimeClass ms_RuntimeClass; \
|
||||
virtual RuntimeClass* GetRuntimeClass() \
|
||||
{ \
|
||||
return &ms_RuntimeClass; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_RTTI_BASE( Class ) \
|
||||
RuntimeClass Class::ms_RuntimeClass( #Class ) \
|
||||
|
||||
#define IMPLEMENT_RTTI( Class, BaseClass ) \
|
||||
RuntimeClass Class::ms_RuntimeClass( #Class, &BaseClass::ms_RuntimeClass ) \
|
||||
|
||||
//==============================================================================
|
||||
// IMPLEMENTATION
|
||||
//==============================================================================
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4355 ) // warning 'this' used in base member initializer list
|
||||
#undef CREATE_RTTI
|
||||
#undef CREATE_RTTI_BASE
|
||||
inline RuntimeClass::RuntimeClass( const char* pClassName) :
|
||||
m_pClassName(pClassName), m_pBaseClass( NULL ){}
|
||||
|
||||
inline RTTI::RTTI( const char* pTypeName ) :
|
||||
pType(pTypeName), Next( *this ){}
|
||||
inline RuntimeClass::RuntimeClass( const char* pClassName, const RuntimeClass* pBaseClass ) :
|
||||
m_pClassName(pClassName), m_pBaseClass( pBaseClass ){}
|
||||
|
||||
inline RTTI::RTTI( const char* pTypeName, const RTTI& RTTI ) :
|
||||
pType(pTypeName), Next( RTTI ){}
|
||||
|
||||
inline bool RTTI::IsKindOf( const RTTI& RTTI ) const
|
||||
inline bool RuntimeClass::IsKindOf( const RuntimeClass* pRuntimeClass ) const
|
||||
{
|
||||
const RTTI* p = this;
|
||||
do
|
||||
{
|
||||
if( p == &RTTI ) return true;
|
||||
if( p == &p->Next ) break;
|
||||
p = &p->Next;
|
||||
|
||||
} while(1);
|
||||
const RuntimeClass* p = this;
|
||||
while (p)
|
||||
{
|
||||
if ( p == pRuntimeClass )
|
||||
return true;
|
||||
|
||||
p = p->m_pBaseClass;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define PRIVATE_RTTI_FUNCTION_SET( TYPE, BASE_CLASS ) \
|
||||
virtual inline const RTTI& GetObjectRTTI( void ) const \
|
||||
{ \
|
||||
return TYPE::GetRTTI(); \
|
||||
} \
|
||||
inline const bool IsKindOf( const RTTI& RTTI ) const \
|
||||
{ \
|
||||
return GetObjectRTTI().IsKindOf( RTTI ); \
|
||||
} \
|
||||
static inline TYPE& GetSaveType( BASE_CLASS& Object ) \
|
||||
{ \
|
||||
assert( Object.IsKindOf(TYPE::GetRTTI()) ); \
|
||||
return *((TYPE*)&Object); \
|
||||
} \
|
||||
static inline const TYPE& GetSaveType( const BASE_CLASS& Object ) \
|
||||
{ \
|
||||
assert( Object.IsKindOf(TYPE::GetRTTI()) ); \
|
||||
return *((const TYPE*)&Object); \
|
||||
}
|
||||
|
||||
#define CREATE_RTTI( TYPE, TYPE_PARENT, BASE_CLASS ) \
|
||||
static inline const RTTI& GetRTTI( void ) \
|
||||
{ \
|
||||
static RTTI s_RTTI( #TYPE, TYPE_PARENT::GetRTTI() ); \
|
||||
return s_RTTI; \
|
||||
} \
|
||||
PRIVATE_RTTI_FUNCTION_SET(TYPE,BASE_CLASS)
|
||||
|
||||
#define CREATE_RTTI_BASE( TYPE ) \
|
||||
static inline const RTTI& GetRTTI( void ) \
|
||||
{ \
|
||||
static RTTI s_RTTI( #TYPE ); \
|
||||
return s_RTTI; \
|
||||
} \
|
||||
PRIVATE_RTTI_FUNCTION_SET(TYPE,TYPE)
|
||||
|
||||
#pragma warning( pop )
|
||||
|
||||
template <typename T, typename C>
|
||||
T* DynamicCast(C* pObj)
|
||||
{
|
||||
if ( pObj->GetRuntimeClass()->IsKindOf( &T::ms_RuntimeClass ) )
|
||||
return (T*)pObj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // !RTTI_H
|
||||
|
||||
139
engine/utils/str.h
Normal file
139
engine/utils/str.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#ifndef CSTR_H
|
||||
#define CSTR_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
class Str
|
||||
{
|
||||
public:
|
||||
Str()
|
||||
{
|
||||
m_Text = NULL;
|
||||
}
|
||||
|
||||
Str( const Str& source )
|
||||
{
|
||||
m_Text = NULL;
|
||||
if ( source.m_Text != NULL )
|
||||
Copy( source.m_Text );
|
||||
}
|
||||
|
||||
Str( const char* source )
|
||||
{
|
||||
m_Text = NULL;
|
||||
if ( source != NULL )
|
||||
Copy( source );
|
||||
}
|
||||
|
||||
~Str()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
void Free()
|
||||
{
|
||||
if ( m_Text != NULL )
|
||||
{
|
||||
free( m_Text );
|
||||
m_Text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Copy( const char* source )
|
||||
{
|
||||
Reserve( strlen( source ) + 1 );
|
||||
strcpy( m_Text, source );
|
||||
}
|
||||
|
||||
void Reserve( unsigned int size )
|
||||
{
|
||||
if (m_Text)
|
||||
{
|
||||
free( m_Text );
|
||||
}
|
||||
|
||||
m_Text = (char*)malloc( size );
|
||||
}
|
||||
|
||||
Str& operator=( const char* source )
|
||||
{
|
||||
Free();
|
||||
|
||||
if ( source != NULL )
|
||||
Copy( source );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int Compare( const Str& string ) const
|
||||
{
|
||||
if ( m_Text == NULL && string.m_Text == NULL )
|
||||
return 0;
|
||||
|
||||
if ( m_Text == NULL || string.m_Text == NULL )
|
||||
return -1;
|
||||
|
||||
return strcmp( m_Text, string.m_Text );
|
||||
}
|
||||
|
||||
int Compare( const char* string ) const
|
||||
{
|
||||
if ( m_Text == NULL && string == NULL )
|
||||
return 0;
|
||||
|
||||
if ( m_Text == NULL || string == NULL )
|
||||
return -1;
|
||||
|
||||
return strcmp( m_Text, string );
|
||||
}
|
||||
|
||||
friend bool operator==( const Str& stringA, const Str& stringB )
|
||||
{
|
||||
return stringA.Compare( stringB ) == 0;
|
||||
}
|
||||
|
||||
friend bool operator==( const Str& stringA, const char* stringB )
|
||||
{
|
||||
return stringA.Compare( stringB ) == 0;
|
||||
}
|
||||
|
||||
friend bool operator==( const char* stringA, const Str& stringB )
|
||||
{
|
||||
return stringB.Compare( stringA ) == 0;
|
||||
}
|
||||
|
||||
char& operator[]( const size_t idx )
|
||||
{
|
||||
return m_Text[idx];
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
bool IsEmpty()
|
||||
{
|
||||
return GetLength() == 0;
|
||||
}
|
||||
|
||||
unsigned int GetLength()
|
||||
{
|
||||
if ( m_Text == NULL )
|
||||
return 0;
|
||||
|
||||
return strlen( m_Text );
|
||||
}
|
||||
|
||||
const char* GetText()
|
||||
{
|
||||
return (const char*)m_Text;
|
||||
}
|
||||
|
||||
private:
|
||||
char* m_Text;
|
||||
};
|
||||
|
||||
#endif // !CSTR_H
|
||||
Reference in New Issue
Block a user