class_name KCUtils static func remove_children(node: Node, delete: bool = true): for i in range(node.get_child_count() - 1, -1, -1): var child = node.get_child(i) node.remove_child(child) if delete: child.queue_free() static func get_class_name(value: Object) -> String: match value.get_script(): var script when script != null: match script.get_global_name(): var name when name != null: return name _: return script.get_instance_base_type() _: return value.get_class() static func is_string_like(value: Variant) -> bool: match typeof(value): TYPE_STRING: return true TYPE_STRING_NAME: return true TYPE_NODE_PATH: return true _: return false static func to_str(value: Variant) -> String: match typeof(value): TYPE_OBJECT: if value.has_method('_to_string'): return value.to_string() else: var name = get_class_name(value) value = value as Object var props: Dictionary = inst_to_dict(value) return "%s %s" % [name, to_str(props)] _: return str(value) static func _always_pass(_any: Variant) -> bool: return true static func notify(node: Node, notification: int, up: bool = false): notify_while(node, notification, _always_pass, up) static func notify_while(node: Node, notification: int, predicate: Callable = _always_pass, up: bool = false): node.notification(notification) if up: var parent = node.get_parent() if parent != null and predicate.call(parent): notify_while(parent, notification, predicate, up) else: for child in node.get_children(): if predicate.call(child): notify_while(child, notification, predicate) static func propagate(node: Node, fn: StringName, args: Array, call_on_self: bool = true): if call_on_self and node.has_method(fn): node.callv(fn, args) for child in node.get_children(): propagate(child, fn, args) static func propagate_input_event(node: Node, fn: StringName, event: InputEvent, call_on_self: bool = true): if node.get_viewport().is_input_handled() or event.is_canceled(): return if call_on_self and node.has_method(fn): node.callv(fn, [event]) for child in node.get_children(): propagate_input_event(child, fn, event) static func get_size(value: Variant) -> Result: match typeof(value): TYPE_STRING | TYPE_VECTOR2 | TYPE_VECTOR2I | TYPE_VECTOR3 | TYPE_VECTOR3I | TYPE_VECTOR4 | TYPE_VECTOR4I | TYPE_QUATERNION: return Result.ok(value.length()) var x when x >= 27 and x <= 38: return Result.ok(value.size()) _: return Result.err(Error.NotImplemented.new('"length" or "size"')) static func len(value: Variant) -> int: return get_size(value).unwrap()