From e0de6744e2aebd74ae133292ed9813c0afb545f3 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 14 Nov 2023 11:22:41 +0100 Subject: [PATCH] Add better errors logging to BT nodes in case of issues --- Source/Engine/AI/BehaviorTree.cs | 16 +++++++++++----- Source/Engine/AI/BehaviorTreeNodes.cpp | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/Engine/AI/BehaviorTree.cs b/Source/Engine/AI/BehaviorTree.cs index 699c72976..a1c863e6b 100644 --- a/Source/Engine/AI/BehaviorTree.cs +++ b/Source/Engine/AI/BehaviorTree.cs @@ -95,12 +95,16 @@ namespace FlaxEngine [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T GetState(IntPtr memory) where T : struct { - var ptr = IntPtr.Add(memory, _memoryOffset).ToPointer(); - var handle = GCHandle.FromIntPtr(Unsafe.Read(ptr)); + var ptr = Unsafe.Read(IntPtr.Add(memory, _memoryOffset).ToPointer()); +#if !BUILD_RELEASE + if (ptr == IntPtr.Zero) + throw new Exception($"Missing state '{typeof(T).FullName}' for node '{GetType().FullName}'"); +#endif + var handle = GCHandle.FromIntPtr(ptr); var state = handle.Target; #if !BUILD_RELEASE if (state == null) - throw new NullReferenceException(); + throw new Exception($"Missing state '{typeof(T).FullName}' for node '{GetType().FullName}'"); #endif return ref Unsafe.Unbox(state); } @@ -111,8 +115,10 @@ namespace FlaxEngine [MethodImpl(MethodImplOptions.AggressiveInlining)] public void FreeState(IntPtr memory) { - var ptr = IntPtr.Add(memory, _memoryOffset).ToPointer(); - var handle = GCHandle.FromIntPtr(Unsafe.Read(ptr)); + var ptr = Unsafe.Read(IntPtr.Add(memory, _memoryOffset).ToPointer()); + if (ptr == IntPtr.Zero) + return; + var handle = GCHandle.FromIntPtr(ptr); handle.Free(); } } diff --git a/Source/Engine/AI/BehaviorTreeNodes.cpp b/Source/Engine/AI/BehaviorTreeNodes.cpp index 4be336b35..fb49a007e 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.cpp +++ b/Source/Engine/AI/BehaviorTreeNodes.cpp @@ -85,6 +85,8 @@ BehaviorUpdateResult BehaviorTreeNode::InvokeUpdate(const BehaviorUpdateContext& result = BehaviorUpdateResult::Failed; else result = Update(context); + if ((int32)result < 0 || (int32)result > (int32)BehaviorUpdateResult::Failed) + result = BehaviorUpdateResult::Failed; // Invalid value is a failure // Post-process result from decorators for (BehaviorTreeDecorator* decorator : _decorators)