106 lines
3.4 KiB
C++
106 lines
3.4 KiB
C++
/***
|
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: PrivData.hpp
|
|
Date: 2023-6-3
|
|
Author: Reece
|
|
Note: This header is included very early on!
|
|
***/
|
|
#pragma once
|
|
|
|
// We're very early...
|
|
#include <Aurora\Threading\IWaitable.hpp>
|
|
#include <Aurora\Threading\Primitives\Primitives.hpp>
|
|
#include <Aurora\Threading\LockGuard.hpp>
|
|
|
|
#if defined(AURORA_USR_DATA_USE_SLOW_PTR)
|
|
#define AURT_PRIVATE_DATA_PTR AuSPtr<void>
|
|
#else
|
|
#define AURT_PRIVATE_DATA_PTR std::shared_ptr<void>
|
|
#endif
|
|
|
|
namespace Aurora::Utility
|
|
{
|
|
// ! Optional Interface: !
|
|
struct IHasPrivateData
|
|
{
|
|
virtual AURT_PRIVATE_DATA_PTR PrivateUserDataGet() = 0;
|
|
virtual AURT_PRIVATE_DATA_PTR PrivateUserDataExchange(AURT_PRIVATE_DATA_PTR, AURT_PRIVATE_DATA_PTR) = 0;
|
|
};
|
|
|
|
namespace Detail
|
|
{
|
|
struct GetPrivateDataImpl
|
|
{
|
|
inline virtual AURT_PRIVATE_DATA_PTR GetData()
|
|
{
|
|
AU_LOCK_GUARD(this->quickMutex);
|
|
return this->pData;
|
|
}
|
|
|
|
inline virtual bool ExchangeData(AURT_PRIVATE_DATA_PTR pExpect, AURT_PRIVATE_DATA_PTR pReplace)
|
|
{
|
|
AU_LOCK_GUARD(this->quickMutex);
|
|
auto pData = this->pData;
|
|
if (pData != pExpect)
|
|
{
|
|
return false;
|
|
}
|
|
this->pData = pExpect;
|
|
return true;
|
|
}
|
|
|
|
Aurora::Threading::Primitives::Mutex quickMutex;
|
|
AURT_PRIVATE_DATA_PTR pData {};
|
|
};
|
|
}
|
|
}
|
|
|
|
#define AURT_ADD_USR_DATA \
|
|
private: \
|
|
Aurora::Utility::Detail::GetPrivateDataImpl _auReservedUserData; \
|
|
public:\
|
|
inline virtual AURT_PRIVATE_DATA_PTR PrivateUserDataGet()\
|
|
{\
|
|
return this->_auReservedUserData.GetData();\
|
|
}\
|
|
inline virtual bool PrivateUserDataExchange(AURT_PRIVATE_DATA_PTR pExpect, AURT_PRIVATE_DATA_PTR pReplace)\
|
|
{\
|
|
return this->_auReservedUserData.ExchangeData(pExpect, pReplace);\
|
|
}\
|
|
template<typename T>\
|
|
inline AuSPtr<T> PrivateUserDataNewData()\
|
|
{\
|
|
auto pCurrent = this->_auReservedUserData.pData;\
|
|
if (pCurrent) return {};\
|
|
auto pMaybeTemp = AuMakeShared<T>();\
|
|
if (!pMaybeTemp) return {};\
|
|
return (this->PrivateUserDataExchange(pCurrent, pMaybeTemp)) ? pMaybeTemp : AURT_PRIVATE_DATA_PTR {};\
|
|
}\
|
|
template<typename T>\
|
|
inline AuSPtr<T> PrivateUserDataGetSharedData()\
|
|
{\
|
|
auto pCurrent = this->_auReservedUserData.pData;\
|
|
if (pCurrent) return AuReinterpretCast<T>(pCurrent);\
|
|
auto pMaybeTemp = AuMakeShared<T>();\
|
|
if (!pMaybeTemp) return {};\
|
|
return (this->PrivateUserDataExchange(pCurrent, pMaybeTemp)) ? pMaybeTemp : AuReinterpretCast<T>(this->_auReservedUserData.pData);\
|
|
}\
|
|
inline Aurora::Threading::Primitives::IHyperWaitable *PrivateUserDataToUtilityMutex()\
|
|
{\
|
|
return this->_auReservedUserData.quickMutex.AsPointer();\
|
|
}\
|
|
protected:\
|
|
inline void PrivateUserDataClear()\
|
|
{\
|
|
AuResetMember(this->_auReservedUserData.pData);\
|
|
}
|
|
|
|
#if defined(AURORA_USR_DATA_DISABLED)
|
|
#undef AURT_ADD_USR_DATA
|
|
#define AURT_ADD_USR_DATA
|
|
#define AURT_ADD_USR_DATA_ON_SHIP
|
|
#else
|
|
#define AURT_ADD_USR_DATA_ON_SHIP AURT_ADD_USR_DATA
|
|
#endif
|