// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using FlaxEngine;
namespace FlaxEditor.SceneGraph
{
///
/// Set of tools for processing.
///
[HideInEditor]
public static class SceneGraphTools
{
///
/// Delegate for scene graph action execution callback.
///
/// The node.
/// True if call deeper, otherwise skip calling node children.
public delegate bool GraphExecuteCallbackDelegate(SceneGraphNode node);
///
/// Executes the custom action on the graph nodes.
///
/// The node
/// The callback.
public static void ExecuteOnGraph(this SceneGraphNode node, GraphExecuteCallbackDelegate callback)
{
for (int i = 0; i < node.ChildNodes.Count; i++)
{
if (callback(node.ChildNodes[i]))
{
ExecuteOnGraph(node.ChildNodes[i], callback);
}
}
}
///
/// Builds the array made of input nodes that are at the top level. The result collection contains only nodes that don't have parent nodes in the given collection.
///
/// The scene graph node type.
/// The nodes.
/// The result.
public static List BuildNodesParents(this List nodes)
where T : SceneGraphNode
{
var list = new List();
BuildNodesParents(nodes, list);
return list;
}
///
/// Builds the list made of input nodes that are at the top level. The result collection contains only nodes that don't have parent nodes in the given collection.
///
/// The scene graph node type.
/// The nodes.
/// The result.
public static void BuildNodesParents(this List nodes, List result)
where T : SceneGraphNode
{
if (nodes == null || result == null)
throw new ArgumentNullException();
result.Clear();
// Build solid part of the tree
var fullTree = BuildAllNodes(nodes);
for (var i = 0; i < nodes.Count; i++)
{
var target = nodes[i];
// If there is no target node parent in the solid tree list,
// then it means it's a local root node and can be added to the results.
if (!fullTree.Contains(target.ParentNode))
result.Add(target);
}
}
///
/// Builds the array made of all nodes in the input list and child tree. The result collection contains all nodes in the tree.
///
/// The nodes.
/// The result.
public static List BuildAllNodes(this List nodes)
where T : SceneGraphNode
{
var list = new List();
BuildAllNodes(nodes, list);
return list;
}
private static void FillTree(SceneGraphNode node, List result)
{
result.AddRange(node.ChildNodes);
for (int i = 0; i < node.ChildNodes.Count; i++)
{
FillTree(node.ChildNodes[i], result);
}
}
///
/// Builds the list made of all nodes in the input list and child tree. The result collection contains all nodes in the tree.
///
/// The nodes.
/// The result.
public static void BuildAllNodes(this List nodes, List result)
where T : SceneGraphNode
{
if (nodes == null || result == null)
throw new ArgumentNullException();
result.Clear();
for (var i = 0; i < nodes.Count; i++)
{
var target = nodes[i];
// Check if has been already added
if (result.Contains(target))
continue;
// Add whole child tree to the results
result.Add(target);
FillTree(target, result);
}
}
}
}