diff --git a/Source/Engine/AI/BehaviorTreeNode.h b/Source/Engine/AI/BehaviorTreeNode.h index 80126902d..1d435dc6c 100644 --- a/Source/Engine/AI/BehaviorTreeNode.h +++ b/Source/Engine/AI/BehaviorTreeNode.h @@ -14,6 +14,7 @@ API_CLASS(Abstract) class FLAXENGINE_API BehaviorTreeNode : public SerializableS friend class BehaviorTreeGraph; friend class BehaviorKnowledge; friend class BehaviorTreeSubTreeNode; + friend class BehaviorTreeCompoundNode; protected: // Raw memory byte offset from the start of the behavior memory block. @@ -86,4 +87,8 @@ public: ASSERT((int32)sizeof(T) <= GetStateSize()); return reinterpret_cast((byte*)memory + _memoryOffset); } + +protected: + virtual void InvokeReleaseState(const BehaviorUpdateContext& context); +}; }; diff --git a/Source/Engine/AI/BehaviorTreeNodes.cpp b/Source/Engine/AI/BehaviorTreeNodes.cpp index f7d03fdda..97b63a05b 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.cpp +++ b/Source/Engine/AI/BehaviorTreeNodes.cpp @@ -56,8 +56,7 @@ BehaviorUpdateResult BehaviorTreeNode::InvokeUpdate(const BehaviorUpdateContext& // Check if node is not relevant anymore if (result != BehaviorUpdateResult::Running) { - relevantNodes.Set(_executionIndex, false); - ReleaseState(context.Behavior, context.Memory); + InvokeReleaseState(context); } return result; @@ -79,6 +78,13 @@ void BehaviorTreeNode::Deserialize(DeserializeStream& stream, ISerializeModifier DESERIALIZE(Name); } +void BehaviorTreeNode::InvokeReleaseState(const BehaviorUpdateContext& context) +{ + BitArray<>& relevantNodes = *(BitArray<>*)context.RelevantNodes; + relevantNodes.Set(_executionIndex, false); + ReleaseState(context.Behavior, context.Memory); +} + void BehaviorTreeCompoundNode::Init(BehaviorTree* tree) { for (BehaviorTreeNode* child : Children) @@ -96,6 +102,20 @@ BehaviorUpdateResult BehaviorTreeCompoundNode::Update(BehaviorUpdateContext cont return result; } +void BehaviorTreeCompoundNode::InvokeReleaseState(const BehaviorUpdateContext& context) +{ + const BitArray<>& relevantNodes = *(const BitArray<>*)context.RelevantNodes; + for (BehaviorTreeNode* child : Children) + { + if (relevantNodes.Get(child->_executionIndex) == true) + { + child->InvokeReleaseState(context); + } + } + + BehaviorTreeNode::InvokeReleaseState(context); +} + int32 BehaviorTreeSequenceNode::GetStateSize() const { return sizeof(State); diff --git a/Source/Engine/AI/BehaviorTreeNodes.h b/Source/Engine/AI/BehaviorTreeNodes.h index 347aa2b49..723db818c 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.h +++ b/Source/Engine/AI/BehaviorTreeNodes.h @@ -6,6 +6,7 @@ #include "BehaviorTreeNode.h" #include "BehaviorKnowledgeSelector.h" #include "Engine/Core/Collections/Array.h" +#include "Engine/Core/Collections/BitArray.h" #include "Engine/Content/AssetReference.h" /// @@ -24,6 +25,10 @@ public: // [BehaviorTreeNode] void Init(BehaviorTree* tree) override; BehaviorUpdateResult Update(BehaviorUpdateContext context) override; + +protected: + // [BehaviorTreeNode] + void InvokeReleaseState(const BehaviorUpdateContext& context) override; }; ///