From 9ebd3ad3786a5e630e638be42c3dce3298bbc12c Mon Sep 17 00:00:00 2001 From: Laura Andelare Date: Wed, 14 Aug 2024 23:15:23 +0000 Subject: [PATCH] 2.0 backports --- .../Source/UE5Coro/Private/Generator.cpp | 6 ++++- .../Source/UE5Coro/Private/Promise.cpp | 6 ++++- Plugins/UE5Coro/UE5Coro.uplugin | 2 +- .../Private/UE5CoroGameplayAbility.cpp | 23 ++++++++++++++++++- .../UE5CoroGAS/UE5CoroGameplayAbility.h | 5 +++- Plugins/UE5CoroGAS/UE5CoroGAS.uplugin | 2 +- 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/Generator.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/Generator.cpp index 7de780de..f4638321 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Private/Generator.cpp +++ b/Plugins/UE5Coro/Source/UE5Coro/Private/Generator.cpp @@ -36,7 +36,11 @@ using namespace UE5Coro::Private; void FGeneratorPromise::unhandled_exception() { #if PLATFORM_EXCEPTIONS_DISABLED - check(!"Exceptions are not supported"); + // Hitting this can be a result of the generator itself invoking undefined + // behavior, e.g., by using a bad pointer. + // On Windows, SEH exceptions can end up here if C++ exceptions are disabled. + // If this hinders debugging, feel free to remove it! + checkSlow(!"Unhandled exception from generator!"); #else throw; #endif diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/Promise.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/Promise.cpp index a4f14295..5bc72f7e 100644 --- a/Plugins/UE5Coro/Source/UE5Coro/Private/Promise.cpp +++ b/Plugins/UE5Coro/Source/UE5Coro/Private/Promise.cpp @@ -166,7 +166,11 @@ void FPromise::AddContinuation(std::function Fn) void FPromise::unhandled_exception() { #if PLATFORM_EXCEPTIONS_DISABLED - check(!"Exceptions are not supported"); + // Hitting this can be a result of the coroutine itself invoking undefined + // behavior, e.g., by using a bad pointer. + // On Windows, SEH exceptions can end up here if C++ exceptions are disabled. + // If this hinders debugging, feel free to remove it! + checkSlow(!"Unhandled exception from coroutine!"); #else bUnhandledException = true; throw; diff --git a/Plugins/UE5Coro/UE5Coro.uplugin b/Plugins/UE5Coro/UE5Coro.uplugin index 83e91829..2de23c53 100644 --- a/Plugins/UE5Coro/UE5Coro.uplugin +++ b/Plugins/UE5Coro/UE5Coro.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "1.10.2-ue4", + "VersionName": "1.10.3-ue4", "FriendlyName": "UE5Coro (UE4 edition)", "Description": "C++20 coroutine implementation for Unreal Engine 4", "Category": "Programming", diff --git a/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Private/UE5CoroGameplayAbility.cpp b/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Private/UE5CoroGameplayAbility.cpp index 9b0fb517..d3953fc8 100644 --- a/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Private/UE5CoroGameplayAbility.cpp +++ b/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Private/UE5CoroGameplayAbility.cpp @@ -37,6 +37,7 @@ using namespace UE5Coro; using namespace UE5Coro::Private; +using namespace UE5CoroGAS::Private; namespace { @@ -53,10 +54,30 @@ bool IsTemplate(UObject* Object) } } +namespace UE5CoroGAS::Private +{ +struct FStrictPredictionKey : FPredictionKey +{ + FStrictPredictionKey(const FPredictionKey& Key) noexcept + : FPredictionKey(Key) { } + + bool operator==(const FStrictPredictionKey& Other) const noexcept + { + return FPredictionKey::operator==(Other) && Base == Other.Base; + } +}; + +int32 GetTypeHash(const FStrictPredictionKey& Key) noexcept // ADL +{ + return GetTypeHash(static_cast(Key)) ^ + Key.Base << 16; +} +} + UUE5CoroGameplayAbility::UUE5CoroGameplayAbility() { if (::IsTemplate(this)) - Activations = new TMap*>; + Activations = new TMap*>; else Activations = GetDefault(GetClass())->Activations; checkf(Activations, TEXT("Internal error: non-template object before CDO")); diff --git a/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Public/UE5CoroGAS/UE5CoroGameplayAbility.h b/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Public/UE5CoroGAS/UE5CoroGameplayAbility.h index a1aaf461..2b082a96 100644 --- a/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Public/UE5CoroGAS/UE5CoroGameplayAbility.h +++ b/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Public/UE5CoroGAS/UE5CoroGameplayAbility.h @@ -37,6 +37,8 @@ #include "UE5CoroGAS/AbilityPromises.h" #include "UE5CoroGameplayAbility.generated.h" +namespace UE5CoroGAS::Private { struct FStrictPredictionKey; } + /** * Usage summary: * - Override ExecuteAbility instead of ActivateAbility @@ -52,7 +54,8 @@ class UE5COROGAS_API UUE5CoroGameplayAbility : public UGameplayAbility // One shared per class to support every instancing policy including derived // classes changing their minds at runtime. The real one is on the CDO. - TMap*>* Activations; + TMap*>* Activations; public: UUE5CoroGameplayAbility(); diff --git a/Plugins/UE5CoroGAS/UE5CoroGAS.uplugin b/Plugins/UE5CoroGAS/UE5CoroGAS.uplugin index 231d6ad8..b2dde3c3 100644 --- a/Plugins/UE5CoroGAS/UE5CoroGAS.uplugin +++ b/Plugins/UE5CoroGAS/UE5CoroGAS.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "1.10.2-ue4", + "VersionName": "1.10.3-ue4", "FriendlyName": "UE5Coro – Gameplay Ability System (UE4 edition)", "Description": "C++20 coroutines for GAS", "Category": "Programming",