From f81f99f45ea1d1ecde580b44fd4b35d21f9a2e41 Mon Sep 17 00:00:00 2001 From: Reece Wilson Date: Tue, 19 Jul 2022 15:21:35 +0100 Subject: [PATCH] [+] AU_SAFE_DESTROY utility for defining standard object destruction --- Include/auROXTL/Objects/Objects.hpp | 2 +- Include/auROXTL/Objects/SafeDestroy.hpp | 118 ++++++++++++++++++++++++ Include/auROXTLUtils.hpp | 1 + 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 Include/auROXTL/Objects/SafeDestroy.hpp diff --git a/Include/auROXTL/Objects/Objects.hpp b/Include/auROXTL/Objects/Objects.hpp index 7040c2f..6c68f95 100644 --- a/Include/auROXTL/Objects/Objects.hpp +++ b/Include/auROXTL/Objects/Objects.hpp @@ -8,4 +8,4 @@ #pragma once #include "ClassHelpers.hpp" -#include "ModuleApi.hpp" \ No newline at end of file +#include "ModuleApi.hpp" diff --git a/Include/auROXTL/Objects/SafeDestroy.hpp b/Include/auROXTL/Objects/SafeDestroy.hpp new file mode 100644 index 0000000..c6939a1 --- /dev/null +++ b/Include/auROXTL/Objects/SafeDestroy.hpp @@ -0,0 +1,118 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: SafeDestroy.hpp + Date: 2022-07-19 + Author: Reece +***/ +#pragma once + +namespace AuUtil +{ + namespace Detail + { + template + struct AuHasDestroy + { + template static constexpr AuTrueType Test(decltype(&C::DestroyPrivate)); + template static constexpr AuFalseType Test(...); + using type = decltype(Test(0)); + }; + + template + struct AuHasDeconstruct + { + template static constexpr AuTrueType Test(decltype(&C::DeconstructPrivate)); + template static constexpr AuFalseType Test(...); + using type = decltype(Test(0)); + }; + + template + struct AuHasPreDeconstruct + { + template static constexpr AuTrueType Test(decltype(&C::PreDeconstructPrivate)); + template static constexpr AuFalseType Test(...); + using type = decltype(Test(0)); + }; + + template + constexpr inline bool AuHasDestroy_v = AuHasDestroy::type::value; + + template + constexpr inline bool AuHasDesconstruct_v = AuHasDeconstruct::type::value; + + template + constexpr inline bool AuHasPreDesconstruct_v = AuHasPreDeconstruct::type::value; + } + +#define AU_SAFE_DESTROY(type) \ +public: \ + virtual ~type() \ + { \ + if (AuExchange(this->bDestroyCtrOnce_, true)) return; \ + \ + type :: _TryPreDeconstruct(this); \ + \ + this->Destroy(); \ + \ + type :: _TryDeconstruct(this); \ + \ + } \ + \ + inline void Destroy() \ + { \ + if (AuExchange(this->bDestroyDesOnce_, true)) return; \ + \ + type :: _TryDeconstructPrivate(this); \ + } \ + \ + friend AuUtil::Detail::AuHasDestroy; \ + friend AuUtil::Detail::AuHasDeconstruct; \ + friend AuUtil::Detail::AuHasPreDeconstruct; \ + \ +private: \ + bool bDestroyCtrOnce_ {}; \ + bool bDestroyDesOnce_ {}; \ + \ + template \ + static void _TryPreDeconstruct(T *that) \ + { \ + if constexpr (AuUtil::Detail::AuHasPreDesconstruct_v) \ + { \ + that->PreDeconstructPrivate(); \ + } \ + } \ + \ + template \ + static void _TryDeconstruct(T *that) \ + { \ + if constexpr (AuUtil::Detail::AuHasDesconstruct_v) \ + { \ + that->DeconstructPrivate(); \ + } \ + } \ + \ + template \ + static void _TryDeconstructPrivate(T *that) \ + { \ + if constexpr (AuUtil::Detail::AuHasDestroy_v) \ + { \ + that->DestroyPrivate(); \ + } \ + } \ + \ +public: +} + +/** + Defines #define AU_SAFE_DESTROY(type) + + Implements safe multiple-detor, and multiple ::Destroy() call, based destructible interfaces. + Simply add AU_SAFE_DESTROY to the types body add arbitrarily add the following callback methods as needed + + void DestroyPrivate(void) - Generic called once object destroy + void DeconstructPrivate(void) - Object destruction hook. Called once. Called After DestroyPrivate. + void PreDeconstructPrivate(void) - Object destruction hook. Called once. Called before DestroyPrivate. + + These user defined functions may be private and/or virtual, if implemented at all. +*/ \ No newline at end of file diff --git a/Include/auROXTLUtils.hpp b/Include/auROXTLUtils.hpp index ded3937..4a2864f 100644 --- a/Include/auROXTLUtils.hpp +++ b/Include/auROXTLUtils.hpp @@ -49,6 +49,7 @@ #include #include +#include struct IAuNullDelegate {