Files
2022-10-26 12:25:11 +08:00

534 lines
18 KiB
C++

#pragma once
// 모든 프로젝트 및 공유 폴더 위치가 고정이라는 전제하에 설정되는 상대 위치를 통한 Include
#include "../include/Global.Define.h"
#ifndef INOUT
# define INOUT
#endif //
#define __DISABLE_COPY(className) \
private : \
className(const className&); \
void operator = (const className&)
#define __UNUSED(variable) variable
// NOTE: to remove meanless warnings, this macro same as __UNUSED
#define __TOUCHED(variable) variable
#define __INFINITE_LOOP(name) BOOL b##name##Loop = TRUE; while (b##name##Loop)
// NOTE: use this tag to disable warning LNK4221 when a code file has no public symbols
#define __EMPTY_FILE_TAG() namespace { char __EmptyFile_DisableWarning_LNK4221_##__LINE__; }
#define COMPILE_ASSERTION_CHECK_METHOD_IMPL() namespace { void __ComplieAssertionChecker_##__LINE__()
#define COMPILE_ASSERTION_CHECK_METHOD_END() }
//=============================================================================================================================
// SafeDeleter
//=============================================================================================================================
#ifdef SAFE_DELETE
#undef SAFE_DELETE
#endif
#ifdef SAFE_DELETE_ARRAY
#undef SAFE_DELETE_ARRAY
#endif
#define SAFE_DELETE( p) { if ( p) { delete ( p); ( p) = NULL; } }
#define SAFE_DELETE_ARRAY( p) { if ( p) { delete[] ( p); ( p) = NULL; } }
#define SAFE_RELEASE( p) { if ( p) { ( p)->Release(); ( p) = NULL; } }
#define SAFE_RELEASENDELETE(p) if (p) { (p)->Release(); delete (p); (p) = NULL; }
class SafeDeleter
{
public :
template <class T>
void operator () (T*& ptr) const
{
SAFE_DELETE( ptr );
}
};
class PairDeleter
{
public :
template < class pair_type >
void operator () ( pair_type & pair ) const
{
SAFE_DELETE( pair.second );
}
};
template <class T>
struct Param2Class
{
typedef T ClassType;
};
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// <PROPERTIES>
// @author : waverix
// @remark :
// PROPERTY<_TYPE>
// = 단일 멤버 IO 처리용, complex타입 지원
// PROPERTY_ARRAY<_TYPE, _INITVAL, _ARRAYCNT>
// = 배열 멤버 IO 처리용, complex타입 미지원 (complex타입을 사용하기 위해서는 포인터와 같은 타입으로 사용할 것
// @notes :
// - 07/10/09 - 기존보다 형식 검사를 강화하고, 프로퍼티로서의 성격을 강화시켰다.
// 무수한 인터페이스와 필드들로 점철되는 매머드 객체로 사용하기 보다는
// 이런식으로 분리시켜 나가는 편이 이후 유지보수, 모듈화에 더 도움이 될 것이다.
// - 07/10/09 - <주의> PROPERTY에서 GetRef, operator _TYPE& 는 complex타입 지원을 위해 const성질이 없다.
// <주의> PROPERTY_ARRAY에서 GetPtr는 const로서의 성질을 지키는 것이 안전하다. <읽기 전용>
// - 07/10/09 - <주의> operator = 계열은 구현하지 않았습니다.
// 할당에 관련해서는 순수 타입 연산과 거의 동일해지는 문제 때문에 중대한 오류를 범할 수 있습니다.
// <주의> 다음의 연산은 허용됩니다. 반대의 연산은 허용되지 않습니다.
// PROPERTY<DWORD> autovariable;
// DWORD tVal = autovariable;
// DWORD& rVal = autovariable;
// @history :
// 07/10/09 : designed by waverix
// @sample :
// class TestObject
// {
// public: PROPERTY<DWORD> OBJECT_KEY;
// PROPERTY_ARRAY<BYTE, 0, 16> STATES;
// };
//
// {
// TestObject* pTestObject;
// pTestObject->OBJECT_KEY.Set( 10 );
// pTestObject->OBJECT_KEY.Get();
//
// // STATES는 미리 선언한 대로 0으로 초기화 되어 있음.
// pTestObject->STATES.SetValue( 10, 100 );
// BYTE byResultIs_100 = pTestObject->STATES.Get( 10 );
// pTestObject->STATES.SetValue( 16, 100 ); // overflow, no-action
// BYTE byResultIs_0 = pTestObject->STATES.Get( 16 );
// }
//
class PROPERTY_BASE
{
public: PROPERTY_BASE() {}
~PROPERTY_BASE() {}
};
template<typename _TYPE>
class PROPERTY : public PROPERTY_BASE
{
private: typedef _TYPE node_type;
typedef PROPERTY<node_type> this_type;
public: PROPERTY() {}
explicit PROPERTY( const node_type& t ) : m_FIELD(t) {}
~PROPERTY() {}
public: inline operator const node_type& () const { return m_FIELD; }
inline node_type Get() const { return m_FIELD; }
inline VOID Set( node_type IN field ) { m_FIELD = field; }
private: node_type m_FIELD;
private: this_type& operator = ( const node_type& );
//this_type operator = ( const this_type& );
};
template<typename _TYPE>
class PROPERTY<typename _TYPE*> : public PROPERTY_BASE
{
private: typedef _TYPE node_type;
typedef node_type* pointer;
typedef node_type* const pointer_r;
typedef PROPERTY<pointer> this_type;
public: PROPERTY() {}
explicit PROPERTY( const node_type& t ) : m_FIELD(t) {}
~PROPERTY() {}
public: inline operator const pointer_r () const { return m_FIELD; }
inline pointer Get() const { return m_FIELD; }
inline VOID Set( pointer IN field ) { m_FIELD = field; }
inline pointer_r operator-> () { return m_FIELD; }
inline operator bool() const { return !!m_FIELD; }
inline bool operator == ( const this_type& rhs ) const { return m_FIELD == rhs.m_FIELD; }
inline bool operator == ( const pointer& rhs ) const { return m_FIELD == rhs; }
inline bool operator != ( const this_type& rhs ) const { return m_FIELD != rhs.m_FIELD; }
inline bool operator != ( const pointer& rhs ) const { return m_FIELD != rhs; }
private: pointer m_FIELD;
private: this_type& operator = ( const node_type& );
this_type& operator = ( const pointer& );
};
template<typename _TYPE, typename _TYPE _INITVAL, typename DWORD _ARRAYCNT=1>
class PROPERTY_ARRAY : public PROPERTY_BASE
{
private: typedef _TYPE node_type;
typedef PROPERTY_ARRAY<node_type, _INITVAL, _ARRAYCNT> this_type;
public: PROPERTY_ARRAY() { Clear(); }
~PROPERTY_ARRAY() {}
private: PROPERTY_ARRAY( const this_type& t );
this_type& operator = ( const this_type& );
public: inline const _TYPE* GetPtr() const { return m_pFIELD; }
inline _TYPE Get( DWORD dwIDX ) const
{
if( _ARRAYCNT > dwIDX )
return m_pFIELD[dwIDX];
#ifdef _DEBUG
__debugbreak();
#endif
return _INITVAL;
}
inline BOOL Set( DWORD dwIDX, _TYPE IN field )
{
if( _ARRAYCNT > dwIDX )
{
m_pFIELD[dwIDX] = field;
return TRUE;
}
#ifdef _DEBUG
__debugbreak();
#endif
return FALSE;
}
inline VOID Clear()
{
// (f100527.5L) change clear function
_TYPE* it = m_pFIELD;
for (DWORD loop = _ARRAYCNT; loop; --loop) {
*it++ = _INITVAL;
}
}
private: _TYPE m_pFIELD[_ARRAYCNT];
};
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// <PROPERTIES><OLD VERSION>
#define __PROPERTY( DataType, name ) \
public : \
void Set##name( DataType value ) { m_##name = value; } \
DataType Get##name() const { return m_##name; } \
protected : \
DataType m_##name;
#define __REF_PROPERTY( DataType, name ) \
public : \
void Set##name( DataType value ) { m_##name = value; } \
DataType Get##name() const { return m_##name; } \
const DataType & Get##name##Ref() const { return m_##name; } \
const DataType * Get##name##Ptr() const { return &m_##name; } \
DataType & _Get##name##Ref() { return m_##name; } \
DataType * _Get##name##Ptr() { return &m_##name; } \
void Set##name##Ref( const DataType & value ) { m_##name = value; } \
void Set##name##Ptr( const DataType * value ) { m_##name = *value; } \
protected : \
DataType m_##name;
#define __BOOL_PROPERTY( name ) \
public : \
void Set##name( bool bValue = true ) { m_##name = bValue; } \
bool Is##name() const { return m_##name; } \
protected : \
bool m_##name;
#define __PTR_PROPERTY( DataType, name ) \
public : \
void Set##name( DataType* value ) { m_p##name = value; } \
const DataType* Get##name() const { return m_p##name; } \
DataType* Get##name() { return m_p##name; } \
protected : \
DataType* m_p##name;
// (CHANGES) (100220) (WAVERIX) changes index type, WORD to DWORD,\
// expected that invalid index has can't access fault
// (CHANGES) (100220) (WAVERIX) add boundary checker
#define __ARRAY_PROPERTY(DataType, num, name) \
public: \
void Set##name(const DWORD idx, DataType value) { \
if (FlowControl::FCAssert(idx < _countof(m_p##name))) { \
m_p##name[idx] = value; \
} \
} \
DataType Get##name(const DWORD idx) { \
if (FlowControl::FCAssert(idx < _countof(m_p##name))) { \
return m_p##name[idx]; \
} \
return DataType(); \
} \
DataType* Get##name##Ptr() { return m_p##name; } \
protected: \
DataType m_p##name[num];
#if defined( _UNICODE ) || defined( UNICODE )
/*
/////////////////////////////////////////////////////////////////////////////////////
// 유니코드용 함수들
/////////////////////////////////////////////////////////////////////////////////////
#define TSTRCPY wcscpy
#define TSTRNCPY wcsncpy
#define TATOL _wtol
#define TSPRINTF swprintf
#define TSTRLEN wcslen
#else
#if defined( _MBCS )
/////////////////////////////////////////////////////////////////////////////////////
// MBCS
/////////////////////////////////////////////////////////////////////////////////////
#define TSTRCPY _mbscpy
#define TSTRNCPY _mbsncpy
#define TATOL atol
#define TSPRINTF sprintf
#define TSTRLEN _mbslen
#else
/////////////////////////////////////////////////////////////////////////////////////
// SBCS
/////////////////////////////////////////////////////////////////////////////////////
#define TSTRCPY strcpy
#define TSTRNCPY strncpy
#define TATOL atol
#define TSPRINTF sprintf
#define TSTRLEN strlen
#endif
*/
#endif
// CHANGES: f101110.1L, changes the '_countof' macro.
// _countof helper : this macro brought from over vs2005 version
#if !defined(_countof)
#if !defined(__cplusplus)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#else
extern "C++"
{
template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(_CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
#define _countof(_Array) sizeof(*__countof_helper(_Array))
}
#endif
#endif
// <Description>
// 타입 캐스팅시 발생 가능한 타입 오버플로를 검사하기 위한 로직
// 검사 가능한 타입 최대치 = 64bit 자료형 (__int64) --or-- (long long)
// <Arguments>
// F_TYPE: 변수의 원래 타입
// F_VALUE: 타입 오버플로를 검사하고자 하는 변수
// T_TYPE: 변환시키고자 하는 타입
// <Returns>
// BOOL
// TRUE: 타입 오버플로가 발생하기 않았다
// FALSE: 타입 오버플로가 발생했다
// <Ex>
// <기존1> DWORD dwValue;
// <기존2> WORD wValue = (WORD)dwValue;
//
// <변경1> DWORD dwValue;
// <변경2> if( TRUE == SAFE_NUMERIC_TYPECAST(DWORD, dwValue, WORD) )
// <변경3> WORD wValue = (WORD)dwValue;
// <변경4> else // ERROR HANDLING
//
#define SAFE_NUMERIC_TYPECAST( F_TYPE, F_VALUE, T_TYPE ) \
( (F_TYPE)(((T_TYPE)(0xFFFFFFFFFFFFFFFFLL))&F_VALUE) == F_VALUE )
#define MAKEDWORD(a, b) ((DWORD)(((WORD)((DWORD_PTR)(a) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(b) & 0xffff))) << 16))
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> {};
#define STATIC_ASSERT( expr ) STATIC_ASSERTMSG( expr, CompileTime )
#define STATIC_ASSERTMSG( expr, msg ) \
{ \
class Assertion_For_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr)!=0>((Assertion_For_##msg()))); \
}
//(void)sizeof(CompileTimeChecker<(expr)!=0>((Assertion_For_##msg())));
//==================================================================================================
// Logic Level calculator
namespace util {
;
// (NOTE) (WAVERIX) (080912)
// - 반올림과 관련해서 H/W 환경, compile option 또는 debug|release의 차이와 무관하게
// 항상 동일한 결과를 보인다.
inline int LL_Round(const double val)
{
const int integral = (int)val;
const double mantissa = val - integral;
return mantissa < .5f ? integral
: integral + 1;
}
inline int LL_Ceil(const double val)
{
const INT integral = (INT)val;
const double matissa = val - integral;
return matissa > .0f ? integral + 1
: integral;
}
}; //end of namespace
//==================================================================================================
#if defined(_DEBUG)
#ifdef _SUNGAME_VER //client side에서 사용하는 매크로 (유저배포용)
#error "disabled configuration"
#endif
#include <crtdbg.h>
#if _MSC_VER >= 1500
//#include <vld.h>
#endif
#define _CRTDBG_MAP_ALLOC
inline void StartMemoryLeakCheck(void) { _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); }
#define BreakPointOnMemoryLeak( iMemory) _CrtSetBreakAlloc( iMemory)
#include <assert.h>
#define BREAK(expr) _ASSERTE(##expr)
// ASSERT 걸고싶으면 개인 디파인으로 거세요 제발
#define ASSERT(expr) __noop
//#define ASSERT(expr) FlowControl::FCAssert(##expr)
//#define ASSERTMSG(expr,m) if(!(FlowControl::FCAssert(expr))) { printf(m); }
// 릴리즈시에도 Assert가 걸릴 수 있게 break
// 스크립트 오류시에
#define FASSERT(expr) _ASSERTE(expr)
#define DISPMSG printf
#define DEBUG_CODE(c) c
#elif defined(_SERVER)
#define StartMemoryLeakCheck() __noop
#define BreakPointOnMemoryLeak __noop
#define BREAK(expr) __noop
#define ASSERT(expr) FlowControl::FCAssert(##expr)
#define DISPMSG printf
#define DEBUG_CODE(c) c
// 릴리즈시에도 Assert가 걸릴 수 있게 break
// 스크립트 오류시에
#define FASSERT(expr) { if (FlowControl::FCAssert(##expr) == false) { __debugbreak(); }; }
#else //!defined(_SERVER) || !defined(_DEBUG)
#define StartMemoryLeakCheck() __noop
#define BreakPointOnMemoryLeak __noop
#define BREAK(expr) __noop
#ifdef _SUNGAME_VER //client side에서 사용하는 매크로 (유저배포용)
#define ASSERT(expr) __noop
#define ASSERTMSG(expr,m) __noop
#define FASSERT(expr) { if (!(expr)) { __debugbreak(); }; }
#else
#define ASSERT(expr) FlowControl::FCAssert(##expr)
// 릴리즈시에도 Assert가 걸릴 수 있게 break
// 스크립트 오류시에
#define FASSERT(expr) { if (FlowControl::FCAssert(##expr) == false) { __debugbreak(); }; }
#endif
#define DISPMSG __noop
#define DEBUG_CODE(c) __noop
#endif
//==================================================================================================
// @history
// - |~10/02/22|지완 추가
// - |10/02/22|waverix|add types which are extracted from chrominum 'basictypes.h'
// |Comments="to support coding style since 2010"|]
// - |10/08/13|waverix|moved this point from the 'define.h'
//
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
// start reference : chrominum/basictypes.h, SkUserConfig.h
//typedef signed char schar;
typedef signed char int8;
typedef signed char int8_t;
typedef short int16;
typedef short int16_t;
typedef int int32;
typedef int int32_t;
typedef long long int64;
typedef long long int64_t;
// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
// places. Use the signed types unless your variable represents a bit
// pattern (eg a hash value) or you really need the extra bit. Do NOT
// use 'unsigned' to express "this value should always be positive";
// use assertions for this.
typedef unsigned char uint8;
typedef unsigned char uint8_t;
typedef unsigned short uint16;
typedef unsigned short uint16_t;
typedef unsigned int uint32;
typedef unsigned int uint32_t;
typedef unsigned long long uint64;
typedef unsigned long long uint64_t;
// end reference : chrominum/basictypes.h, SkUserConfig.h
//==================================================================================================
// configuration for default compiler level 4 warnings to disable
//
// C4201 : unnamed union/struct/class
// to allow like a WzVector
// union {
// struct { float x, y, z; };
// float elements[3];
// };
#pragma warning(disable:4201)
// C4127 : conditional expression is constant
// to allow like a 'ASSERT(!"can't entered")'
#pragma warning(disable:4127)
//
//==================================================================================================
// NOTE: f110512.6L
enum eSUN_LOG_LEVEL
{
eCRITICAL_LOG = 1,
eMIDDLE_LOG = 2,
eFULL_LOG = 3,
eDEV_LOG = 4
};
#ifdef _SERVER
extern bool MessageOut(eSUN_LOG_LEVEL log_level, const TCHAR* format, ...);
extern bool ConsoleOut(eSUN_LOG_LEVEL log_level, const TCHAR* format, ...);
#else
#include <GeneralFunction.h>
inline void MessageOut(eSUN_LOG_LEVEL, const TCHAR*, ...) {}
inline void ConsoleOut(eSUN_LOG_LEVEL, const TCHAR*, ...) {}
#endif
// NOTE: f110512.6L
#ifdef _SUNGAME_VER //client side에서 사용하는 매크로 (유저배포용)
#define SUNLOG __noop
#define CONSOLELOG __noop
#define _TRACE __noop
#else
#define SUNLOG MessageOut
#define CONSOLELOG ConsoleOut
#define _TRACE DebugOut
#endif
//==================================================================================================