CIOWinManager implementation

This commit is contained in:
Jack Andersen 2015-08-25 15:34:56 -10:00
parent 3f1025abb3
commit a9cfd21ebc
12 changed files with 415 additions and 75 deletions

View File

@ -10,7 +10,7 @@ class CAudioStateWin : public CIOWin
{ {
public: public:
CAudioStateWin() : CIOWin("CAudioStateWin") {} CAudioStateWin() : CIOWin("CAudioStateWin") {}
virtual bool OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) virtual CIOWin::EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue)
{ {
} }
}; };

View File

@ -1,9 +1,9 @@
#ifndef __RETRO_CARCHITECTUREMESSAGE_HPP__ #ifndef __RETRO_CARCHITECTUREMESSAGE_HPP__
#define __RETRO_CARCHITECTUREMESSAGE_HPP__ #define __RETRO_CARCHITECTUREMESSAGE_HPP__
#include <memory>
#include "GCNTypes.hpp" #include "GCNTypes.hpp"
#include "Input/CFinalInput.hpp" #include "Input/CFinalInput.hpp"
#include "rstl.hpp"
namespace Retro namespace Retro
{ {
@ -11,14 +11,15 @@ class CIOWin;
enum EArchMsgTarget enum EArchMsgTarget
{ {
TargetMainFlow = 0 TargetIOWinManager = 0
}; };
enum EArchMsgType enum EArchMsgType
{ {
MsgDeleteIOWin = 0, MsgRemoveIOWin = 0,
MsgCreateIOWin = 1, MsgCreateIOWin = 1,
MsgChangeIOWinPriority = 2, MsgChangeIOWinPriority = 2,
MsgRemoveAllIOWins = 3,
MsgTimerTick = 4, MsgTimerTick = 4,
MsgUserInput = 5, MsgUserInput = 5,
MsgSetGameState = 6, MsgSetGameState = 6,
@ -35,17 +36,24 @@ struct IArchMsgParm
struct CArchMsgParmInt32 : IArchMsgParm struct CArchMsgParmInt32 : IArchMsgParm
{ {
u32 m_parm; u32 x4_parm;
CArchMsgParmInt32(u32 parm) : m_parm(parm) {} CArchMsgParmInt32(u32 parm) : x4_parm(parm) {}
};
struct CArchMsgParmVoidPtr : IArchMsgParm
{
void* x4_parm1;
CArchMsgParmVoidPtr(void* parm1)
: x4_parm1(parm1) {}
}; };
struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm struct CArchMsgParmInt32Int32VoidPtr : IArchMsgParm
{ {
u32 m_parm1; u32 x4_parm1;
u32 m_parm2; u32 x8_parm2;
const void* m_parm3; void* xc_parm3;
CArchMsgParmInt32Int32VoidPtr(u32 parm1, u32 parm2, const void* parm3) CArchMsgParmInt32Int32VoidPtr(u32 parm1, u32 parm2, void* parm3)
: m_parm1(parm1), m_parm2(parm2), m_parm3(parm3) {} : x4_parm1(parm1), x8_parm2(parm2), xc_parm3(parm3) {}
}; };
struct CArchMsgParmNull : IArchMsgParm struct CArchMsgParmNull : IArchMsgParm
@ -54,37 +62,37 @@ struct CArchMsgParmNull : IArchMsgParm
struct CArchMsgParmReal32 : IArchMsgParm struct CArchMsgParmReal32 : IArchMsgParm
{ {
float m_parm; float x4_parm;
CArchMsgParmReal32(float parm) : m_parm(parm) {} CArchMsgParmReal32(float parm) : x4_parm(parm) {}
}; };
struct CArchMsgParmUserInput : IArchMsgParm struct CArchMsgParmUserInput : IArchMsgParm
{ {
CFinalInput m_parm; CFinalInput x4_parm;
CArchMsgParmUserInput(const CFinalInput& parm) : m_parm(parm) {} CArchMsgParmUserInput(const CFinalInput& parm) : x4_parm(parm) {}
}; };
struct CArchMsgParmControllerStatus : IArchMsgParm struct CArchMsgParmControllerStatus : IArchMsgParm
{ {
u16 m_parm1; u16 x4_parm1;
bool m_parm2; bool x6_parm2;
CArchMsgParmControllerStatus(u16 a, bool b) CArchMsgParmControllerStatus(u16 a, bool b)
: m_parm1(a), m_parm2(b) {} : x4_parm1(a), x6_parm2(b) {}
}; };
class CArchitectureMessage class CArchitectureMessage
{ {
EArchMsgTarget m_target; EArchMsgTarget x0_target;
EArchMsgType m_type; EArchMsgType x4_type;
std::unique_ptr<IArchMsgParm> m_parm; rstl::rc_ptr<IArchMsgParm> x8_parm;
public: public:
CArchitectureMessage(EArchMsgTarget target, EArchMsgType type, IArchMsgParm* parm) CArchitectureMessage(EArchMsgTarget target, EArchMsgType type, IArchMsgParm* parm)
: m_target(target), m_type(type), m_parm(parm) {} : x0_target(target), x4_type(type), x8_parm(parm) {}
EArchMsgTarget GetTarget() const {return m_target;} EArchMsgTarget GetTarget() const {return x0_target;}
EArchMsgType GetType() const {return m_type;} EArchMsgType GetType() const {return x4_type;}
template <class T> template <class T>
const T* GetParm() const {return dynamic_cast<T*>(m_parm.get());} const T* GetParm() const {return dynamic_cast<T*>(x8_parm.get());}
}; };
class MakeMsg class MakeMsg
@ -126,13 +134,13 @@ public:
{ {
return *msg.GetParm<CArchMsgParmInt32Int32VoidPtr>(); return *msg.GetParm<CArchMsgParmInt32Int32VoidPtr>();
} }
static CArchitectureMessage CreateCreateIOWin(EArchMsgTarget target, int pmin, int pmax, const CIOWin* iowin) static CArchitectureMessage CreateCreateIOWin(EArchMsgTarget target, int pmin, int pmax, CIOWin* iowin)
{ {
return CArchitectureMessage(target, MsgCreateIOWin, new CArchMsgParmInt32Int32VoidPtr(pmin, pmax, iowin)); return CArchitectureMessage(target, MsgCreateIOWin, new CArchMsgParmInt32Int32VoidPtr(pmin, pmax, iowin));
} }
static const CArchMsgParmInt32Int32VoidPtr& GetParmDeleteIOWin(const CArchitectureMessage& msg) static const CArchMsgParmVoidPtr& GetParmDeleteIOWin(const CArchitectureMessage& msg)
{ {
return *msg.GetParm<CArchMsgParmInt32Int32VoidPtr>(); return *msg.GetParm<CArchMsgParmVoidPtr>();
} }
}; };

View File

@ -11,18 +11,18 @@ class CArchitectureQueue
{ {
std::list<CArchitectureMessage> m_list; std::list<CArchitectureMessage> m_list;
public: public:
void PushMessage(CArchitectureMessage&& msg) void Push(CArchitectureMessage&& msg)
{ {
m_list.push_back(std::move(msg)); m_list.push_back(std::move(msg));
} }
const CArchitectureMessage& PeekMessage() const CArchitectureMessage Pop()
{
return m_list.front();
}
void PopMessage()
{ {
CArchitectureMessage msg = std::move(m_list.front());
m_list.pop_front(); m_list.pop_front();
return msg;
} }
void Clear() {m_list.clear();}
operator bool() {return m_list.size() != 0;}
}; };
} }

View File

@ -2,6 +2,7 @@
#define __RETRO_CIOWIN_HPP__ #define __RETRO_CIOWIN_HPP__
#include <string> #include <string>
#include "rstl.hpp"
namespace Retro namespace Retro
{ {
@ -10,16 +11,31 @@ class CArchitectureQueue;
class CIOWin class CIOWin
{ {
const char* m_name; std::string m_name;
size_t m_nameHash;
public: public:
enum EMessageReturn
{
MsgRetNormal = 0,
MsgRetExit = 1,
MsgRetRemoveIOWinAndExit = 2,
MsgRetRemoveIOWin = 3
};
virtual ~CIOWin() {} virtual ~CIOWin() {}
CIOWin(const char* name) : m_name(name) {} CIOWin(const std::string& name) : m_name(name) {m_nameHash = std::hash<std::string>()(name);}
virtual bool OnMessage(const CArchitectureMessage&, CArchitectureQueue&)=0; virtual EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&)=0;
virtual bool GetIsContinueDraw() const {return true;} virtual bool GetIsContinueDraw() const {return true;}
virtual void Draw() const {} virtual void Draw() const {}
virtual void PreDraw() const {} virtual void PreDraw() const {}
const std::string& GetName() const {return m_name;}
size_t GetNameHash() const {return m_nameHash;}
}; };
static bool operator==(rstl::rc_ptr<CIOWin> a, rstl::rc_ptr<CIOWin> b)
{
return a.get() == b.get();
}
} }
#endif // __RETRO_CIOWIN_HPP__ #endif // __RETRO_CIOWIN_HPP__

View File

@ -8,14 +8,276 @@ bool CIOWinManager::OnIOWinMessage(const CArchitectureMessage& msg)
{ {
switch (msg.GetType()) switch (msg.GetType())
{ {
case MsgRemoveIOWin:
{
const CArchMsgParmVoidPtr& parm = MakeMsg::GetParmDeleteIOWin(msg);
rstl::rc_ptr<CIOWin> iow = FindIOWin(*static_cast<const std::string*>(parm.x4_parm1));
if (iow)
RemoveIOWin(iow);
return false;
}
case MsgCreateIOWin:
{
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmCreateIOWin(msg);
rstl::rc_ptr<CIOWin> iow(static_cast<CIOWin*>(parm.xc_parm3));
AddIOWin(iow, parm.x4_parm1, parm.x8_parm2);
return false;
}
case MsgChangeIOWinPriority: case MsgChangeIOWinPriority:
{ {
const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmChangeIOWinPriority(msg); const CArchMsgParmInt32Int32VoidPtr& parm = MakeMsg::GetParmChangeIOWinPriority(msg);
rstl::rc_ptr<CIOWin> iow = FindIOWin(*static_cast<const std::string*>(parm.xc_parm3));
if (iow)
ChangeIOWinPriority(iow, parm.x4_parm1, parm.x8_parm2);
return false;
}
case MsgRemoveAllIOWins:
{
RemoveAllIOWins();
return true;
} }
default: break; default: break;
} }
return false; return false;
} }
void CIOWinManager::Draw() const
{
IOWinPQNode* node = x0_rootDraw;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
iow->PreDraw();
if (!iow->GetIsContinueDraw())
break;
node = node->x8_next;
}
node = x0_rootDraw;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
iow->Draw();
if (!iow->GetIsContinueDraw())
break;
node = node->x8_next;
}
}
bool CIOWinManager::DistributeOneMessage(const CArchitectureMessage& msg,
CArchitectureQueue& queue)
{
CIOWinManager::IOWinPQNode* node = x4_rootPump;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
CIOWin::EMessageReturn mret = iow->OnMessage(msg, x8_internalQueue);
while (x8_internalQueue)
{
CArchitectureMessage msg = x8_internalQueue.Pop();
if (msg.GetTarget() == TargetIOWinManager)
{
if (OnIOWinMessage(msg))
{
x8_internalQueue.Clear();
queue.Clear();
return true;
}
}
else
queue.Push(std::move(msg));
}
switch (mret)
{
case CIOWin::MsgRetRemoveIOWinAndExit:
case CIOWin::MsgRetRemoveIOWin:
RemoveIOWin(iow);
default: break;
}
switch (mret)
{
case CIOWin::MsgRetExit:
case CIOWin::MsgRetRemoveIOWinAndExit:
return false;
default: break;
}
node = node->x8_next;
}
return false;
}
void CIOWinManager::PumpMessages(CArchitectureQueue& queue)
{
while (queue)
{
CArchitectureMessage msg = queue.Pop();
if (DistributeOneMessage(msg, queue))
break;
}
}
rstl::rc_ptr<CIOWin> CIOWinManager::FindIOWin(const std::string& name)
{
size_t findHash = std::hash<std::string>()(name);
CIOWinManager::IOWinPQNode* node = x4_rootPump;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
if (iow->GetNameHash() == findHash)
return iow;
node = node->x8_next;
}
node = x0_rootDraw;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
if (iow->GetNameHash() == findHash)
return iow;
node = node->x8_next;
}
return rstl::rc_ptr<CIOWin>();
}
void CIOWinManager::ChangeIOWinPriority(rstl::ncrc_ptr<CIOWin> chIow, int pumpPrio, int drawPrio)
{
CIOWinManager::IOWinPQNode* node = x4_rootPump;
CIOWinManager::IOWinPQNode* prevNode = nullptr;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
if (iow == chIow)
{
if (prevNode)
prevNode->x8_next = node->x8_next;
node->x4_prio = pumpPrio;
CIOWinManager::IOWinPQNode* testNode = x4_rootPump;
CIOWinManager::IOWinPQNode* testPrevNode = nullptr;
while (testNode->x4_prio > pumpPrio)
{
testPrevNode = testNode;
testNode = testNode->x8_next;
}
node->x8_next = testNode;
if (testPrevNode)
testPrevNode->x8_next = node;
else
x4_rootPump = node;
break;
}
prevNode = node;
node = node->x8_next;
}
node = x0_rootDraw;
prevNode = nullptr;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
if (iow == chIow)
{
if (prevNode)
prevNode->x8_next = node->x8_next;
node->x4_prio = drawPrio;
CIOWinManager::IOWinPQNode* testNode = x0_rootDraw;
CIOWinManager::IOWinPQNode* testPrevNode = nullptr;
while (testNode->x4_prio > drawPrio)
{
testPrevNode = testNode;
testNode = testNode->x8_next;
}
node->x8_next = testNode;
if (testPrevNode)
testPrevNode->x8_next = node;
else
x0_rootDraw = node;
break;
}
prevNode = node;
node = node->x8_next;
}
}
void CIOWinManager::RemoveAllIOWins()
{
while (x0_rootDraw)
RemoveIOWin(x0_rootDraw->GetIOWin());
while (x4_rootPump)
RemoveIOWin(x4_rootPump->GetIOWin());
}
void CIOWinManager::RemoveIOWin(rstl::ncrc_ptr<CIOWin> chIow)
{
CIOWinManager::IOWinPQNode* node = x4_rootPump;
CIOWinManager::IOWinPQNode* prevNode = nullptr;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
if (iow == chIow)
{
if (prevNode)
prevNode->x8_next = node->x8_next;
else
x4_rootPump = node->x8_next;
delete node;
break;
}
prevNode = node;
node = node->x8_next;
}
node = x0_rootDraw;
prevNode = nullptr;
while (node)
{
rstl::rc_ptr<CIOWin> iow = node->GetIOWin();
if (iow == chIow)
{
if (prevNode)
prevNode->x8_next = node->x8_next;
else
x0_rootDraw = node->x8_next;
delete node;
break;
}
prevNode = node;
node = node->x8_next;
}
}
void CIOWinManager::AddIOWin(rstl::ncrc_ptr<CIOWin> chIow, int pumpPrio, int drawPrio)
{
CIOWinManager::IOWinPQNode* node = x4_rootPump;
CIOWinManager::IOWinPQNode* prevNode = nullptr;
while (node && pumpPrio > node->x4_prio)
{
prevNode = node;
node = node->x8_next;
}
CIOWinManager::IOWinPQNode* newNode = new CIOWinManager::IOWinPQNode(chIow, pumpPrio, node);
if (prevNode)
prevNode->x8_next = newNode;
else
x4_rootPump = newNode;
node = x0_rootDraw;
prevNode = nullptr;
while (node && drawPrio > node->x4_prio)
{
prevNode = node;
node = node->x8_next;
}
newNode = new CIOWinManager::IOWinPQNode(chIow, drawPrio, node);
if (prevNode)
prevNode->x8_next = newNode;
else
x0_rootDraw = newNode;
}
} }

View File

@ -2,7 +2,10 @@
#define __RETRO_CIOWINMANAGER_HPP__ #define __RETRO_CIOWINMANAGER_HPP__
#include <memory> #include <memory>
#include <list>
#include "CIOWin.hpp" #include "CIOWin.hpp"
#include "rstl.hpp"
#include "CArchitectureQueue.hpp"
namespace Retro namespace Retro
{ {
@ -11,17 +14,31 @@ class CIOWinManager
{ {
struct IOWinPQNode struct IOWinPQNode
{ {
std::shared_ptr<CIOWin> m_iowin; rstl::rc_ptr<CIOWin> x0_iowin;
int m_prio; int x4_prio;
CIOWinManager::IOWinPQNode* m_prev; CIOWinManager::IOWinPQNode* x8_next;
IOWinPQNode(std::weak_ptr<CIOWin> iowin, int prio, IOWinPQNode(rstl::ncrc_ptr<CIOWin> iowin, int prio,
CIOWinManager::IOWinPQNode* prev) CIOWinManager::IOWinPQNode* next)
: m_iowin(iowin), m_prio(prio), m_prev(prev) {} : x0_iowin(iowin), x4_prio(prio), x8_next(next) {}
std::shared_ptr<CIOWin> GetIOWin() const {return m_iowin;} rstl::rc_ptr<CIOWin> GetIOWin() const {return rstl::rc_ptr<CIOWin>(x0_iowin);}
}; };
IOWinPQNode* x0_rootDraw = nullptr;
IOWinPQNode* x4_rootPump = nullptr;
CArchitectureQueue x8_internalQueue;
public:
bool OnIOWinMessage(const CArchitectureMessage& msg); bool OnIOWinMessage(const CArchitectureMessage& msg);
void Draw() const;
bool DistributeOneMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
void PumpMessages(CArchitectureQueue& queue);
rstl::rc_ptr<CIOWin> FindIOWin(const std::string& name);
void ChangeIOWinPriority(rstl::ncrc_ptr<CIOWin>, int pumpPrio, int drawPrio);
void RemoveAllIOWins();
void RemoveIOWin(rstl::ncrc_ptr<CIOWin>);
void AddIOWin(rstl::ncrc_ptr<CIOWin>, int pumpPrio, int drawPrio);
}; };
} }
#endif // __RETRO_CIOWINMANAGER_HPP__ #endif // __RETRO_CIOWINMANAGER_HPP__

View File

@ -6,7 +6,7 @@
namespace Retro namespace Retro
{ {
bool CMFGameLoader::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) CIOWin::EMessageReturn CMFGameLoader::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue)
{ {
switch (msg.GetType()) switch (msg.GetType())
{ {
@ -17,7 +17,7 @@ bool CMFGameLoader::OnMessage(const CArchitectureMessage& msg, CArchitectureQueu
} }
default: break; default: break;
} }
return true; return MsgRetExit;
} }
void CMFGameLoader::Draw() const void CMFGameLoader::Draw() const

View File

@ -10,7 +10,7 @@ class CMFGameLoader : public CIOWin
{ {
public: public:
CMFGameLoader() : CIOWin("CMFGameLoader") {} CMFGameLoader() : CIOWin("CMFGameLoader") {}
bool OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue); EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
void Draw() const; void Draw() const;
}; };

View File

@ -13,12 +13,12 @@ void CMainFlow::SetGameState(EClientFlowStates state, CArchitectureQueue& queue)
switch (state) switch (state)
{ {
case StateGameLoad: case StateGameLoad:
queue.PushMessage(std::move(MakeMsg::CreateCreateIOWin(TargetMainFlow, 10, 1000, new CMFGameLoader()))); queue.Push(std::move(MakeMsg::CreateCreateIOWin(TargetIOWinManager, 10, 1000, new CMFGameLoader())));
break; break;
default: break; default: break;
} }
} }
bool CMainFlow::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) CIOWin::EMessageReturn CMainFlow::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue)
{ {
switch (msg.GetType()) switch (msg.GetType())
{ {
@ -28,12 +28,12 @@ bool CMainFlow::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& q
case MsgSetGameState: case MsgSetGameState:
{ {
CArchMsgParmInt32 state = MakeMsg::GetParmNewGameflowState(msg); CArchMsgParmInt32 state = MakeMsg::GetParmNewGameflowState(msg);
SetGameState(EClientFlowStates(state.m_parm), queue); SetGameState(EClientFlowStates(state.x4_parm), queue);
return true; return MsgRetExit;
} }
default: break; default: break;
} }
return false; return MsgRetNormal;
} }
} }

View File

@ -19,7 +19,7 @@ public:
CMainFlow() : CIOWin("CMainFlow") {} CMainFlow() : CIOWin("CMainFlow") {}
void AdvanceGameState(CArchitectureQueue& queue); void AdvanceGameState(CArchitectureQueue& queue);
void SetGameState(EClientFlowStates state, CArchitectureQueue& queue); void SetGameState(EClientFlowStates state, CArchitectureQueue& queue);
bool OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue); EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
bool GetIsContinueDraw() const {return false;} bool GetIsContinueDraw() const {return false;}
void Draw() const {} void Draw() const {}
}; };

View File

@ -15,21 +15,15 @@ public:
class CVParamTransfer class CVParamTransfer
{ {
rstl::CRefData* m_refData; rstl::rc_ptr<IVParamObj> m_ref;
public: public:
CVParamTransfer(rstl::CRefData* rd) : m_refData(rd) {m_refData->AddRef();} CVParamTransfer();
~CVParamTransfer() CVParamTransfer(IVParamObj* obj) : m_ref(obj) {}
{ CVParamTransfer(const CVParamTransfer& other) : m_ref(other.m_ref) {}
if (m_refData->DelRef() <= 0) IVParamObj* GetObj() const {return m_ref.get();}
{ CVParamTransfer ShareTransferRef() {return CVParamTransfer(*this);}
delete static_cast<IVParamObj*>(m_refData->GetPtr());
delete m_refData;
}
}
IVParamObj* GetObj() const {return static_cast<IVParamObj*>(m_refData->GetPtr());}
CVParamTransfer ShareTransferRef() {return CVParamTransfer(m_refData);}
static CVParamTransfer Null() {return CVParamTransfer(&rstl::CRefData::sNull);} static CVParamTransfer Null() {return CVParamTransfer();}
}; };
template<class T> template<class T>
@ -40,7 +34,6 @@ protected:
~TObjOwnerParam() {} ~TObjOwnerParam() {}
public: public:
TObjOwnerParam(T&& obj) : m_param(std::move(obj)) {} TObjOwnerParam(T&& obj) : m_param(std::move(obj)) {}
CVParamTransfer NewTransferRef() {return CVParamTransfer(new rstl::CRefData(this));}
}; };
} }

View File

@ -22,19 +22,63 @@ public:
*/ */
class CRefData class CRefData
{ {
void* m_ptr; void* x0_ptr;
int m_refCount; int x4_refCount;
public: public:
CRefData() : m_ptr(nullptr), m_refCount(0xffffff) {} CRefData() : x0_ptr(nullptr), x4_refCount(0xffffff) {}
CRefData(void* ptr) : m_ptr(ptr), m_refCount(0) {} CRefData(void* ptr) : x0_ptr(ptr), x4_refCount(0) {}
void* GetPtr() const {return m_ptr;} void* GetPtr() const {return x0_ptr;}
int AddRef() {return ++m_refCount;} int AddRef() {return ++x4_refCount;}
int DelRef() {return --m_refCount;} int DelRef() {return --x4_refCount;}
static CRefData sNull; static CRefData sNull;
}; };
template<class T>
class ncrc_ptr;
/**
* @brief Reference-counted shared smart pointer
*/
template<class T>
class rc_ptr
{
CRefData* m_aux;
friend class ncrc_ptr<T>;
public:
rc_ptr() : m_aux(&CRefData::sNull) {m_aux->AddRef();}
rc_ptr(void* ptr) : m_aux(new CRefData(ptr)) {m_aux->AddRef();}
rc_ptr(const rc_ptr<T>& other) : m_aux(other.m_aux) {m_aux->AddRef();}
rc_ptr(rc_ptr<T>&& other) : m_aux(other.m_aux) {other.m_aux = nullptr;}
rc_ptr(const ncrc_ptr<T>& other) : m_aux(other.m_aux) {m_aux->AddRef();}
~rc_ptr()
{
if (m_aux && !m_aux->DelRef())
{
delete static_cast<T*>(m_aux->GetPtr());
delete m_aux;
}
}
T* operator->() const {return static_cast<T*>(m_aux->GetPtr());}
T& operator*() const {return *static_cast<T*>(m_aux->GetPtr());}
T* get() const {return static_cast<T*>(m_aux->GetPtr());}
operator bool() {return m_aux->GetPtr() != nullptr;}
};
/**
* @brief Non-reference-counted shared smart pointer
*/
template<class T>
class ncrc_ptr
{
CRefData* m_aux;
friend class rc_ptr<T>;
public:
ncrc_ptr(const rc_ptr<T>& other) : m_aux(other.m_aux) {}
};
} }
#endif // __RSTL_HPP__ #endif // __RSTL_HPP__