Skip to content

Commit

Permalink
Add a few extra guards for GT/GWorld access
Browse files Browse the repository at this point in the history
  • Loading branch information
landelare committed Jan 3, 2024
1 parent d959a62 commit 0cf2485
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ void FLatentAwaiter::Suspend(FAsyncPromise& Promise)
{
checkf(IsInGameThread(),
TEXT("Latent awaiters may only be used on the game thread"));
checkf(GWorld,
TEXT("Awaiting this can only be done in the context of a world"));

// Prepare a latent action on the subsystem and transfer ownership to that
auto* Sys = GWorld->GetSubsystem<UUE5CoroSubsystem>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ bool WaitUntilTime(void* State, bool bCleanup)
static_assert(sizeof(void*) >= sizeof(double),
"32-bit platforms are not supported");
auto& TargetTime = reinterpret_cast<double&>(State);
checkf(GWorld, TEXT("Internal error: Latent poll outside of a world"));
return (GWorld->*GetTime)() >= TargetTime;
}

Expand All @@ -77,6 +78,10 @@ FLatentAwaiter GenericUntil(double Time)
logOrEnsureNanError(TEXT("Latent wait started with NaN time"));
}
#endif
checkf(IsInGameThread(),
TEXT("Latent awaiters may only be used on the game thread"));
checkf(GWorld,
TEXT("This function may only be used in the context of a world"));

if constexpr (bTimeIsOffset)
Time += (GWorld->*GetTime)();
Expand Down
1 change: 1 addition & 0 deletions Plugins/UE5Coro/Source/UE5Coro/Private/LatentChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using namespace UE5Coro::Private;

std::tuple<FLatentActionInfo, FTwoLives*> Private::MakeLatentInfo()
{
checkf(GWorld, TEXT("Internal error: Unguarded world access"));
auto* Sys = GWorld->GetSubsystem<UUE5CoroSubsystem>();
// Will be Released by the FLatentAwaiter from the caller
// and UUE5CoroSubsystem on the latent action's completion.
Expand Down
3 changes: 3 additions & 0 deletions Plugins/UE5Coro/Source/UE5Coro/Private/LatentTimeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ TCoroutine<> CommonTimeline(double From, double To, double Length,

checkf(IsInGameThread(),
TEXT("Latent coroutines may only be started on the game thread"));
checkf(GWorld,
TEXT("This function may only be used in the context of a world"));

double Start = (GWorld->*GetTime)();
for (;;)
{
Expand Down
10 changes: 10 additions & 0 deletions Plugins/UE5Coro/Source/UE5Coro/Public/UE5Coro/LatentChain.inl
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ struct FLatentChain<true, bInfo, Type, Types...>
{
static void Call(auto&& Fn, FLatentActionInfo LatentInfo, auto&&... Args)
{
checkf(GWorld, TEXT("Could not chain latent action: no world found"));
FLatentChain<false, bInfo, Types...>::Call(
std::bind_front(std::move(Fn), &*GWorld),
LatentInfo,
Expand Down Expand Up @@ -150,6 +151,8 @@ template<typename... FnParams>
UE5CORO_PRIVATE_LATENT_CHAIN_BUG_MSG
Private::FLatentChainAwaiter Chain(auto (*Function)(FnParams...), auto&&... Args)
{
checkf(IsInGameThread(),
TEXT("Latent awaiters may only be used on the game thread"));
auto [LatentInfo, Done] = Private::MakeLatentInfo();
Private::FLatentChain<true, true, FnParams...>::Call(
Function,
Expand All @@ -163,6 +166,8 @@ UE5CORO_PRIVATE_LATENT_CHAIN_BUG_MSG
Private::FLatentChainAwaiter Chain(auto (Class::*Function)(FnParams...),
Class* Object, auto&&... Args)
{
checkf(IsInGameThread(),
TEXT("Latent awaiters may only be used on the game thread"));
auto [LatentInfo, Done] = Private::MakeLatentInfo();
Private::FLatentChain<true, true, FnParams...>::Call(
std::bind_front(Function, Object),
Expand All @@ -178,6 +183,11 @@ Private::FLatentChainAwaiter Chain(auto (Class::*Function)(FnParams...),
template<typename F, typename... A>
Private::FLatentChainAwaiter ChainEx(F&& Function, A&&... Args)
{
checkf(IsInGameThread(),
TEXT("Latent awaiters may only be used on the game thread"));
if constexpr ((... || (std::is_placeholder_v<std::decay_t<A>> == 1)))
checkf(GWorld,
TEXT("Could not chain latent action: no world found for _1"));
static_assert((... || (std::is_placeholder_v<std::decay_t<A>> == 2)),
"The _2 parameter for LatentInfo is mandatory");

Expand Down

0 comments on commit 0cf2485

Please sign in to comment.