cloudformation-plus-plus: cfn template preprocessor
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

212 lines
3.5 KiB

<?php
declare(strict_types=1);
namespace App\Util;
/**
* Represents a node in a tree.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class GraphNode
{
/**
* Parent of this node.
* @var GraphNode
*/
protected $parent;
/**
* Value of this node.
* @var mixed
*/
protected $value;
/**
* Children of this node.
* @var GraphNode[]
*/
protected $children;
/**
* Create a new graph node.
*
* @param mixed $value
*/
public function __construct($value = null)
{
$this->value = $value;
$this->children = [];
}
/**
* Set the value of this node.
*
* @param mixed $value
* @return void
*/
public function setValue($value): void
{
$this->value = $value;
}
/**
* Get the value of this node.
*
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* Set the parent node of this node.
*
* @param GraphNode $node
* @return void
*/
public function setParent(GraphNode $node): void
{
$this->parent = $node;
}
/**
* Determine whether this node has a parent.
*
* @return bool
*/
public function hasParent(): bool
{
return isset($this->parent);
}
/**
* Get this node's parent node.
*
* @return GraphNode
*/
public function getParent(): GraphNode
{
return $this->parent;
}
/**
* Count how many child nodes this node has.
*
* @return int
*/
public function countChildren(): int
{
return sizeof($this->children);
}
/**
* Determine whether this node has any children.
*
* @return bool
*/
public function hasChildren(): bool
{
return sizeof($this->children) > 0;
}
/**
* Fetch all of this node's children.
*
* @return GraphNode[]
*/
public function getChildren(): array
{
return $this->children;
}
/**
* Add a node to this child's list of children.
*
* @param GraphNode $child
* @return void
*/
public function appendChild(GraphNode $child): void
{
$this->children[] = $child;
$child->setParent($this);
}
/**
* Replace a child node with another node.
*
* @param GraphNode $original
* @param GraphNode $new
* @return void
*/
public function replaceChild(GraphNode $original, GraphNode $new): void
{
for ($i = 0; $i < sizeof($this->children); $i++)
{
if ($this->children[$i] === $original)
{
$this->children[$i] = $new;
$new->setParent($this);
return;
}
}
}
/**
* Remove all children of this node.
*
* @return void
*/
public function clearChildren(): void
{
$this->children = [];
}
/**
* Add a child node by value.
*
* @param mixed $value value to add as a child
* @return GraphNode the node created as a child
*/
public function add($value): GraphNode
{
$this->children[] = new GraphNode($value);
end($this->children)->setParent($this);
return end($this->children);
}
/**
* Walk through this node and all children, calling callback on each node.
*
* Callback is called on a node's children before a node
*
* @param callable $callback callback(GraphNode $node): void
* @return void
*/
public function walk(callable $callback)
{
static::walkNodes([$this], $callback);
}
/**
* Internal function for recursively visiting all nodes.
*
* @param GraphNode[] $nodes
* @param callable $callback
* @return void
*/
protected static function walkNodes(array $nodes, callable $callback)
{
foreach ($nodes as $node)
{
if ($node->hasChildren())
{
static::walkNodes($node->getChildren(), $callback);
}
$callback($node);
}
}
}