diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiter.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiter.cpp index 7642828..640cd5c 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiter.cpp +++ b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiter.cpp @@ -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(); diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiters_Wait.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiters_Wait.cpp index e689fc6..ef6d063 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiters_Wait.cpp +++ b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentAwaiters_Wait.cpp @@ -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(State); + checkf(GWorld, TEXT("Internal error: Latent poll outside of a world")); return (GWorld->*GetTime)() >= TargetTime; } @@ -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)(); diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentChain.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentChain.cpp index f154592..34513ba 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentChain.cpp +++ b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentChain.cpp @@ -37,6 +37,7 @@ using namespace UE5Coro::Private; std::tuple Private::MakeLatentInfo() { + checkf(GWorld, TEXT("Internal error: Unguarded world access")); auto* Sys = GWorld->GetSubsystem(); // Will be Released by the FLatentAwaiter from the caller // and UUE5CoroSubsystem on the latent action's completion. diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentTimeline.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentTimeline.cpp index e619e49..368630b 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Private/LatentTimeline.cpp +++ b/Plugins/UE5Coro/Source/UE5Coro/Private/LatentTimeline.cpp @@ -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 (;;) { diff --git a/Plugins/UE5Coro/Source/UE5Coro/Public/UE5Coro/LatentChain.inl b/Plugins/UE5Coro/Source/UE5Coro/Public/UE5Coro/LatentChain.inl index e3d21ab..a29ea4e 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Public/UE5Coro/LatentChain.inl +++ b/Plugins/UE5Coro/Source/UE5Coro/Public/UE5Coro/LatentChain.inl @@ -90,6 +90,7 @@ struct FLatentChain { static void Call(auto&& Fn, FLatentActionInfo LatentInfo, auto&&... Args) { + checkf(GWorld, TEXT("Could not chain latent action: no world found")); FLatentChain::Call( std::bind_front(std::move(Fn), &*GWorld), LatentInfo, @@ -150,6 +151,8 @@ template 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::Call( Function, @@ -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::Call( std::bind_front(Function, Object), @@ -178,6 +183,11 @@ Private::FLatentChainAwaiter Chain(auto (Class::*Function)(FnParams...), template 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> == 1))) + checkf(GWorld, + TEXT("Could not chain latent action: no world found for _1")); static_assert((... || (std::is_placeholder_v> == 2)), "The _2 parameter for LatentInfo is mandatory");