diff --git a/Plugins/UE5Coro/Source/UE5Coro/Private/Generator.cpp b/Plugins/UE5Coro/Source/UE5Coro/Private/Generator.cpp index 7de780d..f463832 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 a4f1429..5bc72f7 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 cb63337..14409aa 100644 --- a/Plugins/UE5Coro/UE5Coro.uplugin +++ b/Plugins/UE5Coro/UE5Coro.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "1.10.2", + "VersionName": "1.10.3", "FriendlyName": "UE5Coro", "Description": "C++17/20 coroutine implementation for Unreal Engine", "Category": "Programming", diff --git a/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Private/UE5CoroGameplayAbility.cpp b/Plugins/UE5CoroGAS/Source/UE5CoroGAS/Private/UE5CoroGameplayAbility.cpp index 9b0fb51..d3953fc 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 a1aaf46..2b082a9 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 b396e01..80dc55c 100644 --- a/Plugins/UE5CoroGAS/UE5CoroGAS.uplugin +++ b/Plugins/UE5CoroGAS/UE5CoroGAS.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "1.10.1", + "VersionName": "1.10.3", "FriendlyName": "UE5Coro – Gameplay Ability System", "Description": "C++17/20 coroutines for GAS", "Category": "Programming",