mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 02:26:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			96 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_MISC_GUARDED_H
 | 
						|
#define OPENMW_COMPONENTS_MISC_GUARDED_H
 | 
						|
 | 
						|
#include <mutex>
 | 
						|
#include <memory>
 | 
						|
#include <condition_variable>
 | 
						|
 | 
						|
namespace Misc
 | 
						|
{
 | 
						|
    template <class T>
 | 
						|
    class Locked
 | 
						|
    {
 | 
						|
        public:
 | 
						|
            Locked(std::mutex& mutex, T& value)
 | 
						|
                : mLock(mutex), mValue(value)
 | 
						|
            {}
 | 
						|
 | 
						|
            T& get() const
 | 
						|
            {
 | 
						|
                return mValue.get();
 | 
						|
            }
 | 
						|
 | 
						|
            T* operator ->() const
 | 
						|
            {
 | 
						|
                return std::addressof(get());
 | 
						|
            }
 | 
						|
 | 
						|
            T& operator *() const
 | 
						|
            {
 | 
						|
                return get();
 | 
						|
            }
 | 
						|
 | 
						|
        private:
 | 
						|
            std::unique_lock<std::mutex> mLock;
 | 
						|
            std::reference_wrapper<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()
 | 
						|
            {
 | 
						|
                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:
 | 
						|
            std::mutex mMutex;
 | 
						|
            T mValue;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |