mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Implement NodeIterator
This commit is contained in:
parent
cf7d67c972
commit
67b4c0589b
1 changed files with 49 additions and 0 deletions
49
src/spectator/node_iterator.cr
Normal file
49
src/spectator/node_iterator.cr
Normal file
|
@ -0,0 +1,49 @@
|
|||
require "./node"
|
||||
|
||||
module Spectator
|
||||
# Iterates through all nodes in a group and its nested groups.
|
||||
# Nodes are iterated in pre-order.
|
||||
class NodeIterator
|
||||
include Iterator(Node)
|
||||
|
||||
# A stack is used to track where in the tree this iterator is.
|
||||
@stack = Deque(Node).new(1)
|
||||
|
||||
# Creates a new iterator.
|
||||
# The *group* is the example group to iterate through.
|
||||
def initialize(@group : Node)
|
||||
@stack.push(@group)
|
||||
end
|
||||
|
||||
# Retrieves the next `Node`.
|
||||
# If there are none left, then `Iterator::Stop` is returned.
|
||||
def next
|
||||
# Keep going until either:
|
||||
# a. a node is found.
|
||||
# b. the stack is empty.
|
||||
until @stack.empty?
|
||||
# Retrieve the next node.
|
||||
node = @stack.pop
|
||||
|
||||
# If the node is a group, add its direct children to the queue
|
||||
# in reverse order so that the tree is traversed in pre-order.
|
||||
if node.is_a?(Indexable(Node))
|
||||
node.reverse_each { |child| @stack.push(child) }
|
||||
end
|
||||
|
||||
# Return the current node.
|
||||
return node
|
||||
end
|
||||
|
||||
# Nothing left to iterate.
|
||||
stop
|
||||
end
|
||||
|
||||
# Restart the iterator at the beginning.
|
||||
def rewind
|
||||
@stack.clear
|
||||
@stack.push(@group)
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue