// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/Variant.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Collections/BitArray.h" #include "Engine/Scripting/ScriptingObject.h" class Behavior; class BehaviorTree; enum class BehaviorValueComparison; /// /// Behavior logic component knowledge data container. Contains blackboard values, sensors data and goals storage for Behavior Tree execution. /// API_CLASS() class FLAXENGINE_API BehaviorKnowledge : public ScriptingObject { DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(BehaviorKnowledge, ScriptingObject); ~BehaviorKnowledge(); /// /// Owning Behavior instance (constant). /// API_FIELD(ReadOnly) Behavior* Behavior = nullptr; /// /// Used Behavior Tree asset (defines blackboard and memory constraints). /// API_FIELD(ReadOnly) BehaviorTree* Tree = nullptr; /// /// Raw memory chunk with all Behavior Tree nodes state. /// void* Memory = nullptr; /// /// Array with per-node bit indicating whether node is relevant (active in graph with state created). /// BitArray<> RelevantNodes; /// /// Instance of the behaviour blackboard (structure or class). /// API_FIELD() Variant Blackboard; /// /// List of all active goals of the behaviour (structure or class). /// API_FIELD() Array Goals; public: /// /// Initializes the knowledge for a certain tree. /// void InitMemory(BehaviorTree* tree); /// /// Releases the memory of the knowledge. /// void FreeMemory(); /// /// Gets the knowledge item value via selector path. /// /// /// Selector path. /// Result value (valid only when returned true). /// True if got value, otherwise false. API_FUNCTION() bool Get(const StringAnsiView& path, API_PARAM(Out) Variant& value) const; /// /// Sets the knowledge item value via selector path. /// /// /// Selector path. /// Value to set. /// True if set value, otherwise false. API_FUNCTION() bool Set(const StringAnsiView& path, const Variant& value); public: /// /// Checks if knowledge has a given goal (exact type match without base class check). /// /// The goal type. /// True if has a given goal, otherwise false. API_FUNCTION() bool HasGoal(ScriptingTypeHandle type) const; /// /// Checks if knowledge has a given goal (exact type match without base class check). /// /// True if has a given goal, otherwise false. template FORCE_INLINE bool HasGoal() { return HasGoal(T::TypeInitializer); } /// /// Gets the goal from the knowledge. /// /// The goal type. /// The goal value or null if not found. API_FUNCTION() Variant GetGoal(ScriptingTypeHandle type); /// /// Adds the goal to the knowledge. If goal of that type already exists then it's value is updated. /// /// The goal value to add/set. API_FUNCTION() void AddGoal(Variant&& goal); /// /// Removes the goal from the knowledge. Does nothing if goal of the given type doesn't exist in the knowledge. /// /// The goal type. API_FUNCTION() void RemoveGoal(ScriptingTypeHandle type); /// /// Removes the goal from the knowledge. Does nothing if goal of the given type doesn't exist in the knowledge. /// template FORCE_INLINE void RemoveGoal() { RemoveGoal(T::TypeInitializer); } public: /// /// Compares two values and returns the comparision result. /// /// The left operand. /// The right operand. /// The comparison function. /// True if comparision passed, otherwise false. API_FUNCTION() static bool CompareValues(float a, float b, BehaviorValueComparison comparison); };