#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