diff --git a/cpp/Platform.Disposables/Disposable.h b/cpp/Platform.Disposables/Disposable.h index 7d0e907..e813850 100644 --- a/cpp/Platform.Disposables/Disposable.h +++ b/cpp/Platform.Disposables/Disposable.h @@ -1,4 +1,12 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_DISPOSABLE_H +#define DISPOSABLES_DISPOSABLE_H + +#include + +#include "DisposableBase.h" +#include "Disposal.h" + +namespace Platform::Disposables { template class Disposable; template<> class Disposable<> : public DisposableBase @@ -22,9 +30,6 @@ public: Disposable() { OnDispose = _emptyDelegate; } - public: Disposable(std::function action) : Disposable(action) { } - - public: Disposable(std::function disposal) : Disposable(disposal) { } protected: void Dispose(bool manual, bool wasDisposed) override { this->RaiseOnDisposeEvent(manual, wasDisposed); } @@ -32,7 +37,7 @@ public: template static bool TryDisposeAndResetToDefault(T* object) { - auto result = object.TryDispose(); + auto result = object->TryDispose(); if (result) { object = 0; @@ -40,4 +45,7 @@ return result; } }; -} \ No newline at end of file +} + + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/DisposableBase.h b/cpp/Platform.Disposables/DisposableBase.h index 9e651eb..d78d2d8 100644 --- a/cpp/Platform.Disposables/DisposableBase.h +++ b/cpp/Platform.Disposables/DisposableBase.h @@ -1,10 +1,25 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_DISPOSABLE_BASE_H +#define DISPOSABLES_DISPOSABLE_BASE_H + +#include + + + + +#include "IDisposable.h" +#include "EnsureExtensions.h" +#include "../../../Exceptions/cpp/Platform.Exceptions/IgnoredExceptions.h" +#include "../../../Exceptions/cpp/Platform.Exceptions/ExceptionExtensions.h" +#include "../../../Exceptions/cpp/Platform.Exceptions/Ensure.h" + + +namespace Platform::Disposables { class DisposableBase : public IDisposable { - private: static readonly ConcurrentStack> _disposablesWeekReferencesStack = ConcurrentStack>(); + private: static std::stack> _disposablesWeekReferencesStack; - private: volatile std::int32_t _disposed; + private: volatile std::atomic _disposed; public: bool IsDisposed() { @@ -26,12 +41,12 @@ return false; } - static DisposableBase() { std::atexit(OnProcessExit); } protected: DisposableBase() { _disposed = 0; - _disposablesWeekReferencesStack.Push(WeakReference(this, false)); + _disposablesWeekReferencesStack.push(std::weak_ptr(std::shared_ptr(this))); + std::atexit(OnProcessExit); } ~DisposableBase() { Destruct(); } @@ -41,14 +56,13 @@ public: void Dispose() { this->Dispose(true); - GC.SuppressFinalize(this); } public: void Destruct() { try { - if (!IsDisposed) + if (!IsDisposed()) { this->Dispose(false); } @@ -61,13 +75,14 @@ protected: virtual void Dispose(bool manual) { - auto originalDisposedValue = Interlocked.CompareExchange(ref _disposed, 1, 0); + int compare_value = 1; + bool originalDisposedValue = _disposed.compare_exchange_weak(compare_value, 0); auto wasDisposed = originalDisposedValue > 0; - if (wasDisposed && !AllowMultipleDisposeCalls && manual) + if (wasDisposed && !AllowMultipleDisposeCalls() && manual) { - Platform::Disposables::EnsureExtensions::NotDisposed(Platform::Exceptions::Ensure::Always, this, ObjectName, "Multiple dispose calls are not allowed. Override AllowMultipleDisposeCalls property to modify behavior."); + Platform::Disposables::EnsureExtensions::NotDisposed(Platform::Exceptions::Ensure::Always, *this, ObjectName(), "Multiple dispose calls are not allowed. Override AllowMultipleDisposeCalls property to modify behavior."); } - if (AllowMultipleDisposeAttempts || !wasDisposed) + if (AllowMultipleDisposeAttempts() || !wasDisposed) { this->Dispose(manual, wasDisposed); } @@ -75,14 +90,18 @@ private: static void OnProcessExit() { - while (_disposablesWeekReferencesStack.TryPop(out WeakReference weakReference)) + while (!_disposablesWeekReferencesStack.empty()) { - if (weakReference.TryGetTarget(out DisposableBase disposable)) + auto weakReference = _disposablesWeekReferencesStack.top(); + _disposablesWeekReferencesStack.pop(); + + if (auto disposable = weakReference.lock()) { - GC.SuppressFinalize(disposable); - disposable.Destruct(); + disposable->Destruct(); } } } }; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/Disposable[TPrimary, TAuxiliary].h b/cpp/Platform.Disposables/Disposable[TPrimary, TAuxiliary].h index a8cb670..ab70099 100644 --- a/cpp/Platform.Disposables/Disposable[TPrimary, TAuxiliary].h +++ b/cpp/Platform.Disposables/Disposable[TPrimary, TAuxiliary].h @@ -1,9 +1,17 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_DISPOSABLE_T1_T2_H +#define DISPOSABLES_DISPOSABLE_T1_T2_H + +#include "Disposal.h" +#include "Disposable[T].h" + +namespace Platform::Disposables { - template class Disposable; + template class Disposable : public Disposable { public: const TAuxiliary AuxiliaryObject; + public: Platform::Delegates::MulticastDelegate OnDispose; + public: const TPrimary Object; public: Disposable(TPrimary object, TAuxiliary auxiliaryObject, std::function action) : Disposable(object) @@ -18,11 +26,11 @@ }; } - public: Disposable(TPrimary object, TAuxiliary auxiliaryObject, std::function action) : Disposable(object, action) { return AuxiliaryObject = auxiliaryObject; } + public: Disposable(TPrimary object, TAuxiliary auxiliaryObject, std::function action) : Disposable(object, action) { AuxiliaryObject = auxiliaryObject; } - public: Disposable(TPrimary object, TAuxiliary auxiliaryObject, Disposal disposal) : Disposable(object, disposal) { return AuxiliaryObject = auxiliaryObject; } + public: Disposable(TPrimary object, TAuxiliary auxiliaryObject, Disposal disposal) : Disposable(object, disposal) { AuxiliaryObject = auxiliaryObject; } - public: Disposable(TPrimary object, TAuxiliary auxiliaryObject) : Disposable(object) { return AuxiliaryObject = auxiliaryObject; } + public: Disposable(TPrimary object, TAuxiliary auxiliaryObject) : Disposable(object) { AuxiliaryObject = auxiliaryObject; } public: Disposable(TPrimary object) : Disposable(object) { } @@ -44,5 +52,9 @@ AuxiliaryObject.TryDispose(); Object.TryDispose(); } + + }; } + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/Disposable[T].h b/cpp/Platform.Disposables/Disposable[T].h index 246d557..db8430b 100644 --- a/cpp/Platform.Disposables/Disposable[T].h +++ b/cpp/Platform.Disposables/Disposable[T].h @@ -1,6 +1,14 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_DISPOSABLE_T_H +#define DISPOSABLES_DISPOSABLE_T_H + + +#include "Disposal.h" +#include "Disposable.h" + + +namespace Platform::Disposables { - template class Disposable; + template class Disposable : public Disposable<> { public: const T Object; @@ -17,9 +25,9 @@ }; } - public: Disposable(T object, std::function action) : Disposable<>(action) { return Object = object; } + public: Disposable(T object, std::function action) : Disposable<>(action) { Object = object; } - public: Disposable(T object, Disposal disposal) : Disposable<>(disposal) { return Object = object; } + public: Disposable(T object, Disposal disposal) : Disposable<>(disposal) { Object = object; } public: Disposable(T object) { Object = object; } @@ -33,8 +41,15 @@ protected: void Dispose(bool manual, bool wasDisposed) override { - base.Dispose(manual, wasDisposed); + // о нет так можно делать только в visual c++ + // __super::Dispose(manual, wasDisposed) + // ---------------------------------- + // base.Dispose(manual, wasDisposed); + + RaiseOnDisposeEvent(manual, wasDisposed); Object.TryDispose(); } }; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/Disposal.h b/cpp/Platform.Disposables/Disposal.h index c305842..62a8fc3 100644 --- a/cpp/Platform.Disposables/Disposal.h +++ b/cpp/Platform.Disposables/Disposal.h @@ -1,4 +1,9 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_DISPOSAl_H +#define DISPOSABLES_DISPOSAl_H + +namespace Platform::Disposables { using Disposal = void(bool, bool); } + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/EnsureExtensions.h b/cpp/Platform.Disposables/EnsureExtensions.h index 1126638..90fb695 100644 --- a/cpp/Platform.Disposables/EnsureExtensions.h +++ b/cpp/Platform.Disposables/EnsureExtensions.h @@ -1,10 +1,19 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_ENSURE_EXTENSION_H +#define DISPOSABLES_ENSURE_EXTENSION_H + +//TODO: this test includes +#include "../../../Exceptions/cpp/Platform.Exceptions/ExtensionRoots/EnsureAlwaysExtensionRoot.h" +#include "../../../Exceptions/cpp/Platform.Exceptions/ExtensionRoots/EnsureOnDebugExtensionRoot.h" +#include "../../../Exceptions/cpp/Platform.Exceptions/Ensure.h" + + +namespace Platform::Disposables { class EnsureExtensions { public: static void NotDisposed(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, IDisposable &disposable, std::string objectName, std::string message) { - if (disposable.IsDisposed) + if (disposable.IsDisposed()) { throw std::runtime_error(std::string("Attempt to access disposed object [").append(objectName).append("]: ").append(message).append(1, '.')); } @@ -21,3 +30,5 @@ public: static void NotDisposed(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, IDisposable &disposable) { Platform::Disposables::EnsureExtensions::NotDisposed(Platform::Exceptions::Ensure::Always, disposable, {}, {}); } }; } + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/GenericObjectExtensions.h b/cpp/Platform.Disposables/GenericObjectExtensions.h index cfb7680..38e1e35 100644 --- a/cpp/Platform.Disposables/GenericObjectExtensions.h +++ b/cpp/Platform.Disposables/GenericObjectExtensions.h @@ -1,4 +1,7 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_GENERIC_DISPOSABLE_H +#define DISPOSABLES_GENERIC_DISPOSABLE_H + +namespace Platform::Disposables { class GenericObjectExtensions { @@ -6,13 +9,14 @@ { try { - if (object is DisposableBase disposableBase) + if (DisposableBase* disposableBase = (DisposableBase*)object) { - disposableBase.DisposeIfNotDisposed(); + //TODO: add this method + //disposableBase->DisposeIfNotDisposed(); } - else if (object is System::IDisposable &disposable) + else if (System::IDisposable* disposable = (System::IDisposable*)object) { - disposable.Dispose(); + disposable->Dispose(); } return true; } @@ -26,3 +30,5 @@ public: template static void DisposeIfPossible(T object) { TryDispose(object); } }; } + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/IDisposable.h b/cpp/Platform.Disposables/IDisposable.h index 5f4315e..534697b 100644 --- a/cpp/Platform.Disposables/IDisposable.h +++ b/cpp/Platform.Disposables/IDisposable.h @@ -1,4 +1,10 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_IDISPOSABLE_H +#define DISPOSABLES_IDISPOSABLE_H + +#include "System.IDisposable.h" + + +namespace Platform::Disposables { class IDisposable : public System::IDisposable { @@ -7,4 +13,6 @@ virtual void Destruct() = 0; }; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/IDisposableExtensions.h b/cpp/Platform.Disposables/IDisposableExtensions.h index 98c50cf..f5ae656 100644 --- a/cpp/Platform.Disposables/IDisposableExtensions.h +++ b/cpp/Platform.Disposables/IDisposableExtensions.h @@ -1,13 +1,20 @@ -namespace Platform::Disposables +#ifndef DISPOSABLES_IDISPOSABLE_EXTENSIONS_H +#define DISPOSABLES_IDISPOSABLE_EXTENSIONS_H + + + +namespace Platform::Disposables { class IDisposableExtensions { public: static void DisposeIfNotDisposed(IDisposable &disposable) { - if (!disposable.IsDisposed) + if (!disposable.IsDisposed()) { disposable.Dispose(); } } }; } + +#endif \ No newline at end of file diff --git a/cpp/Platform.Disposables/Platform.Disposables.h b/cpp/Platform.Disposables/Platform.Disposables.h index 2d77860..b6ae950 100644 --- a/cpp/Platform.Disposables/Platform.Disposables.h +++ b/cpp/Platform.Disposables/Platform.Disposables.h @@ -3,11 +3,16 @@ #ifndef PLATFORM_DISPOSABLES #define PLATFORM_DISPOSABLES -//#include -//#include -#include -#include +//TODO: this real includes + //#include + //#include +// + +//TODO: this test includes + #include "../../../Delegates/cpp/Platform.Delegates/Platform.Delegates.h" + #include "../../../Exceptions/cpp/Platform.Exceptions/Platform.Exceptions.h" +// #include "System.IDisposable.h"