Skip to content

Commit

Permalink
Add Lockable/Locked to wrap data we want to move around threads
Browse files Browse the repository at this point in the history
  • Loading branch information
maximegmd committed Feb 16, 2021
1 parent e3f573a commit 5ecb5d2
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
68 changes: 68 additions & 0 deletions Code/core/include/Lockable.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

#include "Stl.hpp"

namespace TiltedPhoques
{
template<class T, class U>
struct Locked;

template<class T, class TLock = std::mutex>
struct Lockable
{
struct Data
{
template<class... Args>
Data(Args&& ... aArgs)
: Value(std::forward<Args>(aArgs)...)
{}

T Value;
TLock Lock;
};

struct Ref
{
Ref(typename SharedPtr<Data>::weak_type apData)
: m_pData(std::move(apData))
{}

[[nodiscard]] Locked<T, TLock> Lock() const
{
if (auto locked = m_pData.lock())
{
return { locked };
}

return { {} };
}

private:
typename SharedPtr<Data>::weak_type m_pData;
};


template<class... Args>
Lockable(Args&& ... aArgs)
: m_pData(MakeShared<Data>(std::forward<Args>(aArgs)...))
{}

Ref AsRef() const noexcept
{
return Ref(m_pData);
}

[[nodiscard]] Locked<T, TLock> Lock() const
{
return AsRef().Lock();
}

private:

friend struct Locked<T, TLock>;

SharedPtr<Data> m_pData;
};
}

#include "Locked.hpp"
52 changes: 52 additions & 0 deletions Code/core/include/Locked.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "Lockable.hpp"

namespace TiltedPhoques
{
template<class T, class TLock>
struct Locked
{
Locked(SharedPtr<typename Lockable<T, TLock>::Data> apData)
: m_pData(std::move(apData))
, m_handle(m_pData->Lock)
{
}

operator typename Lockable<T, TLock>::Ref() const
{
return { m_pData };
}

bool IsValid() const
{
return (bool)m_pData;
}

operator T& ()
{
return Get();
}

operator T&() const
{
return Get();
}

const T& Get() const noexcept
{
return m_pData->Value;
}

T& Get() noexcept
{
return m_pData->Value;
}

private:
friend struct Lockable<T, TLock>;

SharedPtr<typename Lockable<T, TLock>::Data> m_pData;
std::scoped_lock<TLock> m_handle;
};
}
25 changes: 25 additions & 0 deletions Code/tests/src/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "TaskQueue.hpp"
#include "Initializer.hpp"
#include "Serialization.hpp"
#include "Lockable.hpp"

#include <string>
#include <future>
Expand Down Expand Up @@ -167,6 +168,30 @@ TEST_CASE("Containers")
}
}

TEST_CASE("Lockable")
{
GIVEN("A lockable")
{
Lockable<String> test("test");
auto ref = test.AsRef();

{
auto locked = test.Lock();
String& data = locked;

REQUIRE(data == "test");
}

{
auto locked = ref.Lock();
String& data = locked;
data = "toto";

REQUIRE(data == "toto");
}
}
}

TEST_CASE("Making sure allocator stacks work corrently", "[core.allocator.stack]")
{
GIVEN("No allocator has been pushed")
Expand Down

0 comments on commit 5ecb5d2

Please sign in to comment.