Skip to content

Instantly share code, notes, and snippets.

@me2beats
Last active September 24, 2021 00:37
Show Gist options
  • Save me2beats/3a49e5e58ccfc2e41c11bd85fb48e71f to your computer and use it in GitHub Desktop.
Save me2beats/3a49e5e58ccfc2e41c11bd85fb48e71f to your computer and use it in GitHub Desktop.
NodeUtils
class_name NodeU
static func get_nodes(node:Node)->Array:
var nodes = []
var stack = [node]
while stack:
var n = stack.pop_back()
nodes.push_back(n)
stack.append_array(n.get_children())
return nodes
static func find_node_by_class(node:Node, cls:String):
var stack = [node]
while stack:
var n:Node = stack.pop_back()
if n.get_class() == cls:return n
stack.append_array(n.get_children())
# ??? should return Node
static func find_node_by_type(node:Node, type):
var stack = [node]
while stack:
var n:Node = stack.pop_back()
if n is type:return n
stack.append_array(n.get_children())
static func find_child_by_class(node:Node, cls:String):
for child in node.get_children():
if child.get_class() == cls:
return child
static func find_child_by_type(node:Node, type):
for child in node.get_children():
if child is type:
return child
static func get_nodes_by_type(node:Node, type)->Array:
var res:= []
var nodes = []
var stack = [node]
while stack:
var n = stack.pop_back()
if n is type:
res.push_back(n)
nodes.push_back(n)
stack.append_array(n.get_children())
return res
static func get_nodes_by_filter(node:Node, filter_obj:Object, filter_method:String, arg: = [])->Array:
var res:= []
var nodes = []
var stack = [node]
while stack:
var n = stack.pop_back()
if filter_obj.call(filter_method, n, arg):
res.push_back(n)
nodes.push_back(n)
stack.append_array(n.get_children())
return res
static func find_node_by_class_path(node:Node, class_path:Array)->Node:
var res:Node
var stack = []
var depths = []
var first = class_path[0]
for c in node.get_children():
if c.get_class() == first:
stack.push_back(c)
depths.push_back(0)
if not stack: return res
var max_ = class_path.size()-1
while stack:
var d = depths.pop_back()
var n = stack.pop_back()
if d>max_:
continue
if n.get_class() == class_path[d]:
if d == max_:
res = n
return res
for c in n.get_children():
stack.push_back(c)
depths.push_back(d+1)
return res
static func get_children_by_class(node:Node, cls:String)->Array:
var res:=[]
for n in node.get_children():
if n.get_class() ==cls:
res.push_back(n)
return res
static func get_nodes_by_class(node:Node, cls)->Array:
var res:= []
var nodes = []
var stack = [node]
while stack:
var n = stack.pop_back()
if n.get_class() ==cls:
res.push_back(n)
nodes.push_back(n)
stack.append_array(n.get_children())
return res
"TODO: do this without _get_nodes_and_depths() ?"
static func get_nodes_and_depths(node: Node) -> Array:
var nodes = [node]
var depths = [0]
if node.get_child_count():
_get_nodes_and_depths(node, nodes, depths, 0)
return [nodes, depths]
static func _get_nodes_and_depths(node: Node, nodes: Array, depths:Array, dep:int):
for n in node.get_children():
nodes.push_back(n)
depths.push_back(dep+1)
if n.get_child_count():
_get_nodes_and_depths(n, nodes, depths, dep+1)
"""
TODO:
1. add some visual lines etc
2. maybe only owned param - later
3. one string instead of multiple prints
4. simplify API/signature
5. indent size arg?
"""
static func my_print_tree_pretty(nodes:Array, depths:Array):
for i in range(nodes.size()):
print(StringU.str_mult(" ", depths[i])+str(nodes[i]))
static func get_parents(node:Node, stop_node)->Array:
var res = []
stop_node = stop_node as Node
while true:
res.push_back(node)
node = node.get_parent()
if node == stop_node:
break
return res
static func find_node_by_class_with_node_by_type(root:Node, cls:String, type)->Array:
var result: = []
for node in get_nodes_by_class(root, cls):
var subnode:Node = find_node_by_type(node, type)
if not subnode: continue
result = [node, subnode]
break
return result
static func has_parent_classes_sequence(node:Node, parent_sequence:Array)->bool:
var parent: = node.get_parent()
while parent:
var sequence_found: = true
var parent2: = parent
for i in parent_sequence:
i = i as String
if !i == parent2.get_class():
sequence_found = false
break
parent2 = parent2.get_parent()
if not parent2:
sequence_found = false
break
if sequence_found: return true
parent = parent.get_parent()
return false
static func get_siblings(node:Node)->Array:
var siblings: = node.get_parent().get_children()
siblings.erase(node)
return siblings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment