OpenBarnyard
 
Loading...
Searching...
No Matches
T2SharedPtr.h
Go to the documentation of this file.
1#pragma once
2
4
5//-----------------------------------------------------------------------------
6// Purpose: custom shared pointer class that manages object's lifecycle
7// by monitoring for number of existing references.
8// Note: this wasn't in the original engine.
9//-----------------------------------------------------------------------------
10template <typename T>
12{
13private:
14 struct SharedPtrData_t
15 {
16#ifdef TOSHI2_ENABLE_SHARED_PTR_VALIDATION
17 TUINT32 uiMagic;
18 void* pObjectRaw;
19#endif // TOSHI2_ENABLE_SHARED_PTR_VALIDATION
20
21 TUINT uiNumRefs;
22 };
23
24#ifdef TOSHI2_ENABLE_SHARED_PTR_VALIDATION
25 static constexpr TUINT32 VALIDATION_MAGIC = 'T2SP';
26#endif // TOSHI2_ENABLE_SHARED_PTR_VALIDATION
27
28public:
29 // Constructor
31 : m_pRawPtr( TNULL )
32 {}
33
34 // Copy constructor
35 T2SharedPtr( const T2SharedPtr& a_rOther )
36 {
37 m_pRawPtr = a_rOther.m_pRawPtr;
38
39 if ( m_pRawPtr )
40 IncrementNumRefs();
41 }
42
43 // Move constructor
45 {
46 m_pRawPtr = a_rOther.m_pRawPtr;
47 a_rOther.m_pRawPtr = TNULL;
48 }
49
50 // Destructor
52 {
53 if ( m_pRawPtr )
54 DecrementNumRefs();
55 }
56
57 // Returns TTRUE if not TNULL
58 TBOOL IsValid() const
59 {
60 return m_pRawPtr;
61 }
62
63 T* Get() { return TREINTERPRETCAST( T*, m_pRawPtr ); }
64 const T* Get() const { return TREINTERPRETCAST( const T*, m_pRawPtr ); }
65
66 operator T*() { return Get(); }
67 operator const T*() const { return Get(); }
68
69 T* operator->() { return Get(); }
70 const T* operator->() const { return Get(); }
71
72 T2SharedPtr& operator=( const T2SharedPtr& a_rOther )
73 {
74 DebugValidate();
75
76 if ( m_pRawPtr )
77 DecrementNumRefs();
78
79 m_pRawPtr = a_rOther.m_pRawPtr;
80
81 if ( m_pRawPtr )
82 IncrementNumRefs();
83 }
84
85 // Use this to create shared pointer objects
86 template <class... Args>
87 static T2SharedPtr New( Args&&... args )
88 {
89 // Allocate memory
90 TCHAR* pMem = (TCHAR*)TMalloc( sizeof( T ) + sizeof( SharedPtrData_t ) );
91 T* pObject = new ( pMem + sizeof( SharedPtrData_t ) ) T( std::forward<Args>( args )... );
92
93 // Create shared pointer object
94 T2SharedPtr sharedPointer;
95 sharedPointer.m_pRawPtr = TREINTERPRETCAST( TCHAR*, pObject );
96
97 // Set shared pointer data data
98 SharedPtrData_t* pPtrData = sharedPointer.AccessPtrData();
99
100 pPtrData->uiNumRefs = 1;
101
102#ifdef TOSHI2_ENABLE_SHARED_PTR_VALIDATION
103 // This can be used to make sure the object was actually created with T2SharedPtr::New
104 pPtrData->uiMagic = VALIDATION_MAGIC;
105 pPtrData->pObjectRaw = pObject;
106#endif // TOSHI2_ENABLE_SHARED_PTR_VALIDATION
107
108 return sharedPointer;
109 }
110
111private:
112 // Returns pointer to an internal structure containing info about the object
113 SharedPtrData_t* AccessPtrData() const
114 {
115 TVALIDPTR( m_pRawPtr );
116 return TREINTERPRETCAST( SharedPtrData_t*, m_pRawPtr - sizeof( SharedPtrData_t ) );
117 }
118
119 void DebugValidate()
120 {
121#ifdef TOSHI2_ENABLE_SHARED_PTR_VALIDATION
122 if ( m_pRawPtr )
123 {
124 SharedPtrData_t* pPtrData = AccessPtrData();
125 TASSERT( pPtrData->uiMagic == VALIDATION_MAGIC && pPtrData->pObjectRaw == m_pRawPtr );
126 }
127#endif
128 }
129
130 void IncrementNumRefs()
131 {
132 TASSERT( TTRUE == IsValid() );
133 DebugValidate();
134
135 AccessPtrData()->uiNumRefs++;
136 }
137
138 void DecrementNumRefs()
139 {
140 TASSERT( TTRUE == IsValid() );
141 DebugValidate();
142
143 SharedPtrData_t* pPtrData = AccessPtrData();
144 TUINT uiOldNumRefs = pPtrData->uiNumRefs--;
145
146 if ( uiOldNumRefs == 1 )
147 {
148 // This was the only reference left, destroy the object and free memory
149 Get()->~T();
150 TFree( pPtrData );
151 }
152 }
153
154private:
155 TCHAR* m_pRawPtr;
156};
157
void * TMalloc(TSIZE a_uiSize, Toshi::TMemory::MemBlock *a_pMemBlock, const TCHAR *a_szFileName, TINT a_iLineNum)
Allocates memory from a specific memory block.
Definition TMemory.cpp:973
void TFree(void *a_pMem)
Frees previously allocated memory.
Definition TMemory.cpp:1054
#define TASSERT(X,...)
Definition Defines.h:138
#define TREINTERPRETCAST(TYPE, VALUE)
Definition Defines.h:68
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
#define TVALIDPTR(PTR)
Definition Defines.h:139
unsigned int TUINT
Definition Typedefs.h:8
char TCHAR
Definition Typedefs.h:20
#define TNULL
Definition Typedefs.h:23
uint32_t TUINT32
Definition Typedefs.h:13
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
T2SharedPtr(const T2SharedPtr &a_rOther)
Definition T2SharedPtr.h:35
const T * operator->() const
Definition T2SharedPtr.h:70
static T2SharedPtr New(Args &&... args)
Definition T2SharedPtr.h:87
T2SharedPtr & operator=(const T2SharedPtr &a_rOther)
Definition T2SharedPtr.h:72
TBOOL IsValid() const
Definition T2SharedPtr.h:58
T2SharedPtr(T2SharedPtr &&a_rOther)
Definition T2SharedPtr.h:44
T * operator->()
Definition T2SharedPtr.h:69
const T * Get() const
Definition T2SharedPtr.h:64