#if GRAPH_DESIGNER /// --------------------------------------------- /// Behavior Designer /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.BehaviorDesigner.Runtime.Utility { using Opsive.BehaviorDesigner.Runtime.Components; using Unity.Burst; using Unity.Entities; /// /// Utility functions that are used throughout the behavior tree execution. /// [BurstCompile] public static class TraversalUtility { /// /// Returns true if the specified index is a child of the parent index. /// /// The index to determine if it is a child. /// The index of the parent. /// The array of nodes. /// True if the specified index is a child of the parent index. [BurstCompile] public static bool IsParent(ushort index, ushort parentIndex, ref DynamicBuffer taskComponents) { if (parentIndex == ushort.MaxValue || index == ushort.MaxValue) { return false; } // The child can be considered a parent of itself. if (parentIndex == index) { return true; } // Return true as soon as there is a parent. while (index != ushort.MaxValue) { if (index == parentIndex) { return true; } index = taskComponents[index].ParentIndex; } return false; } /// /// Returns the total number of children belonging to the specified node. /// /// The index of the task to retrieve the child count of. /// The array of nodes. /// The total number of children belonging to the specified node. public static int GetChildCount(int index, ref DynamicBuffer taskComponents) { var taskComponent = taskComponents[index]; if (taskComponent.SiblingIndex != ushort.MaxValue) { return taskComponent.SiblingIndex - taskComponent.Index - 1; } if (taskComponent.Index + 1 == taskComponents.Length) { return 0; } var childTaskComponent = taskComponents[taskComponent.Index + 1]; if (childTaskComponent.ParentIndex != taskComponent.Index) { return 0; } // Determine the child count based off of the sibling index. var lastChildTaskComponent = childTaskComponent; while (childTaskComponent.ParentIndex == taskComponent.Index) { lastChildTaskComponent = childTaskComponent; if (childTaskComponent.SiblingIndex == ushort.MaxValue) { break; } childTaskComponent = taskComponents[childTaskComponent.SiblingIndex]; } return lastChildTaskComponent.Index - taskComponent.Index + GetChildCount(lastChildTaskComponent.Index, ref taskComponents); } /// /// Returns the immediate number of children belonging to the specified task. /// /// The task to retrieve the children of. /// The list of tasks. /// The number of immediate children belonging to the specified task. [BurstCompile] public static int GetImmediateChildCount(ref TaskComponent task, ref DynamicBuffer taskComponents) { var count = 0; var siblingIndex = task.Index + 1; while (siblingIndex < taskComponents.Length && taskComponents[siblingIndex].ParentIndex == task.Index) { count++; siblingIndex = taskComponents[siblingIndex].SiblingIndex; } return count; } } } #endif