/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "Spintex.hpp" #include #include namespace OpenVulkano { template class MutexProtectedObject { protected: T object; MUTEX mutex; public: class Accessor { std::unique_lock lock; T& ref; public: Accessor(MUTEX& m, T& obj) : lock(m), ref(obj) {} T* operator->() { return &ref; } T& Get() { return ref; } }; MutexProtectedObject() = default; MutexProtectedObject(const T& initValue) : object(initValue) {} template MutexProtectedObject(Args&&... args) : object(std::forward(args)...) {} MutexProtectedObject(const MutexProtectedObject&) = delete; Accessor Access() { return Accessor(mutex, object); } MutexProtectedObject& operator =(const T& value) { Accessor accessor = Access(); object = value; return *this; } operator T() { Accessor accessor = Access(); return accessor.Get(); } const T& UnsafeAccess() const { return object; } }; template using SpintexProtectedObject = MutexProtectedObject; template class SharedMutexProtectedObject : public MutexProtectedObject { public: class SharedAccessor { std::shared_lock lock; T& ref; public: SharedAccessor(MUTEX& m, T& obj) : lock(m), ref(obj) {} const T* operator->() const { return &ref; } const T& Get() const { return ref; } T* operator->() { return &ref; } T& Get() { return ref; } }; SharedMutexProtectedObject() = default; SharedMutexProtectedObject(const T& initValue) : MutexProtectedObject(initValue) {} template SharedMutexProtectedObject(Args&&... args) : MutexProtectedObject(std::forward(args)...) {} SharedMutexProtectedObject(const SharedMutexProtectedObject&) = delete; SharedAccessor SharedAccess() { return SharedAccessor(MutexProtectedObject::mutex, MutexProtectedObject::object); } }; }