/*** 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 #include #include #if defined(AURORA_USR_DATA_USE_SLOW_PTR) #define AURT_PRIVATE_DATA_PTR AuSPtr #else #define AURT_PRIVATE_DATA_PTR std::shared_ptr #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\ inline AuSPtr PrivateUserDataNewData()\ {\ auto pCurrent = this->_auReservedUserData.pData;\ if (pCurrent) return {};\ auto pMaybeTemp = AuMakeShared();\ if (!pMaybeTemp) return {};\ return (this->PrivateUserDataExchange(pCurrent, pMaybeTemp)) ? pMaybeTemp : AURT_PRIVATE_DATA_PTR {};\ }\ template\ inline AuSPtr PrivateUserDataGetSharedData()\ {\ auto pCurrent = this->_auReservedUserData.pData;\ if (pCurrent) return AuReinterpretCast(pCurrent);\ auto pMaybeTemp = AuMakeShared();\ if (!pMaybeTemp) return {};\ return (this->PrivateUserDataExchange(pCurrent, pMaybeTemp)) ? pMaybeTemp : AuReinterpretCast(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