Class: Build::Graph::Walker

Inherits:
Object
  • Object
show all
Defined in:
lib/build/graph/walker.rb

Overview

A walker walks over a graph and applies a task to each node.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(controller, &task) ⇒ Walker

Returns a new instance of Walker.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/build/graph/walker.rb', line 29

def initialize(controller, &task)
	@controller = controller
	@task = task

	@count = 0

	@outputs = {}
	@dirty = Set.new

	# Generate a list of dirty outputs, possibly a subset, if the build graph might generate additional nodes:
	@controller.nodes.each do |key, node|
		# For a given child, a list of any parents waiting on it.
		if node.dirty?
			@dirty << node
		
			@outputs[node] = []
		
			node.outputs.each do |output|
				@outputs[output] = []
			end
		end
	end

	@parents = {}

	# Failed output paths:
	@failed = Set.new
end

Instance Attribute Details

#controllerObject (readonly)

Returns the value of attribute controller.



58
59
60
# File 'lib/build/graph/walker.rb', line 58

def controller
  @controller
end

#countObject

Returns the value of attribute count.



61
62
63
# File 'lib/build/graph/walker.rb', line 61

def count
  @count
end

#dirtyObject (readonly)

Returns the value of attribute dirty.



63
64
65
# File 'lib/build/graph/walker.rb', line 63

def dirty
  @dirty
end

#outputObject (readonly)

Returns the value of attribute output.



59
60
61
# File 'lib/build/graph/walker.rb', line 59

def output
  @output
end

#parentsObject (readonly)

Returns the value of attribute parents.



64
65
66
# File 'lib/build/graph/walker.rb', line 64

def parents
  @parents
end

Instance Method Details

#exit(node) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/build/graph/walker.rb', line 104

def exit(node)
	@dirty.delete(node)

	# Fail outputs if the node failed:
	@failed += node.outputs if node.failed?

	# Clean the node's outputs:
	node.outputs.each do |path|
		if edges = @outputs.delete(path)
			edges.each{|edge| edge.traverse(node)}
		end
	end
		
	# Trigger the parent nodes:
	if parents = @parents.delete(node)
		parents.each{|edge| edge.traverse(node)}
	end
end

#task(*arguments) ⇒ Object



66
67
68
# File 'lib/build/graph/walker.rb', line 66

def task(*arguments)
	@task.call(self, *arguments)
end

#wait_for_nodes(children) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/build/graph/walker.rb', line 89

def wait_for_nodes(children)
	edge = Edge.new

	children.each do |child|
		if @dirty.include?(child)
			edge.increment!
		
			@parents[child] ||= []
			@parents[child] << edge
		end
	end

	edge.wait
end

#wait_on_paths(paths) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/build/graph/walker.rb', line 70

def wait_on_paths(paths)
	edge = Edge.new
	failed = false

	paths.each do |path|
		if @outputs.include? path
			@outputs[path] << edge
		
			edge.increment!
		end
	
		if !failed and @failed.include?(path)
			failed = true
		end
	end

	edge.wait || failed
end