mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 09:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			90 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_MISC_GUARDED_H
 | 
						|
#define OPENMW_COMPONENTS_MISC_GUARDED_H
 | 
						|
 | 
						|
#include <condition_variable>
 | 
						|
#include <memory>
 | 
						|
#include <mutex>
 | 
						|
#include <type_traits>
 | 
						|
 | 
						|
namespace Misc
 | 
						|
{
 | 
						|
    template <class T>
 | 
						|
    class Locked
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        Locked(std::mutex& mutex, std::remove_reference_t<T>& value)
 | 
						|
            : mLock(mutex)
 | 
						|
            , mValue(value)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        std::remove_reference_t<T>& get() const { return mValue.get(); }
 | 
						|
 | 
						|
        std::remove_reference_t<T>* operator->() const { return &get(); }
 | 
						|
 | 
						|
        std::remove_reference_t<T>& operator*() const { return get(); }
 | 
						|
 | 
						|
    private:
 | 
						|
        std::unique_lock<std::mutex> mLock;
 | 
						|
        std::reference_wrapper<std::remove_reference_t<T>> mValue;
 | 
						|
    };
 | 
						|
 | 
						|
    template <class T>
 | 
						|
    class ScopeGuarded
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        ScopeGuarded()
 | 
						|
            : mMutex()
 | 
						|
            , mValue()
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        ScopeGuarded(const T& value)
 | 
						|
            : mMutex()
 | 
						|
            , mValue(value)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        ScopeGuarded(T&& value)
 | 
						|
            : mMutex()
 | 
						|
            , mValue(std::move(value))
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        template <class... Args>
 | 
						|
        ScopeGuarded(Args&&... args)
 | 
						|
            : mMutex()
 | 
						|
            , mValue(std::forward<Args>(args)...)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        ScopeGuarded(const ScopeGuarded& other)
 | 
						|
            : mMutex()
 | 
						|
            , mValue(other.lock().get())
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        ScopeGuarded(ScopeGuarded&& other)
 | 
						|
            : mMutex()
 | 
						|
            , mValue(std::move(other.lock().get()))
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        Locked<T> lock() { return Locked<T>(mMutex, mValue); }
 | 
						|
 | 
						|
        Locked<const T> lockConst() const { return Locked<const T>(mMutex, mValue); }
 | 
						|
 | 
						|
        template <class Predicate>
 | 
						|
        void wait(std::condition_variable& cv, Predicate&& predicate)
 | 
						|
        {
 | 
						|
            std::unique_lock<std::mutex> lock(mMutex);
 | 
						|
            cv.wait(lock, [&] { return predicate(mValue); });
 | 
						|
        }
 | 
						|
 | 
						|
    private:
 | 
						|
        mutable std::mutex mMutex;
 | 
						|
        T mValue;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |