tap 0.12.4 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +34 -0
- data/README +62 -41
- data/bin/tap +36 -40
- data/cmd/console.rb +14 -6
- data/cmd/manifest.rb +62 -58
- data/cmd/run.rb +49 -31
- data/doc/API +84 -0
- data/doc/Class Reference +83 -115
- data/doc/Examples/Command Line +36 -0
- data/doc/Examples/Workflow +40 -0
- data/lib/tap/app.rb +293 -214
- data/lib/tap/app/node.rb +43 -0
- data/lib/tap/app/queue.rb +77 -0
- data/lib/tap/app/stack.rb +16 -0
- data/lib/tap/app/state.rb +22 -0
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/env.rb +400 -314
- data/lib/tap/env/constant.rb +227 -0
- data/lib/tap/env/gems.rb +63 -0
- data/lib/tap/env/manifest.rb +89 -0
- data/lib/tap/env/minimap.rb +292 -0
- data/lib/tap/{support → env}/string_ext.rb +2 -2
- data/lib/tap/exe.rb +113 -125
- data/lib/tap/join.rb +175 -0
- data/lib/tap/joins.rb +9 -0
- data/lib/tap/joins/switch.rb +44 -0
- data/lib/tap/joins/sync.rb +99 -0
- data/lib/tap/root.rb +100 -491
- data/lib/tap/root/utils.rb +220 -0
- data/lib/tap/{support → root}/versions.rb +31 -29
- data/lib/tap/schema.rb +248 -0
- data/lib/tap/schema/parser.rb +413 -0
- data/lib/tap/schema/utils.rb +82 -0
- data/lib/tap/support/intern.rb +19 -6
- data/lib/tap/support/templater.rb +8 -3
- data/lib/tap/task.rb +175 -171
- data/lib/tap/tasks/dump.rb +58 -0
- data/lib/tap/tasks/load.rb +62 -0
- metadata +30 -73
- data/cmd/destroy.rb +0 -27
- data/cmd/generate.rb +0 -27
- data/doc/Command Reference +0 -105
- data/doc/Syntax Reference +0 -234
- data/doc/Tutorial +0 -348
- data/lib/tap/dump.rb +0 -142
- data/lib/tap/file_task.rb +0 -384
- data/lib/tap/generator/arguments.rb +0 -13
- data/lib/tap/generator/base.rb +0 -176
- data/lib/tap/generator/destroy.rb +0 -60
- data/lib/tap/generator/generate.rb +0 -93
- data/lib/tap/generator/generators/command/command_generator.rb +0 -21
- data/lib/tap/generator/generators/command/templates/command.erb +0 -32
- data/lib/tap/generator/generators/config/config_generator.rb +0 -98
- data/lib/tap/generator/generators/generator/generator_generator.rb +0 -37
- data/lib/tap/generator/generators/generator/templates/task.erb +0 -27
- data/lib/tap/generator/generators/generator/templates/test.erb +0 -26
- data/lib/tap/generator/generators/root/root_generator.rb +0 -84
- data/lib/tap/generator/generators/root/templates/MIT-LICENSE +0 -22
- data/lib/tap/generator/generators/root/templates/README +0 -14
- data/lib/tap/generator/generators/root/templates/Rakefile +0 -84
- data/lib/tap/generator/generators/root/templates/Rapfile +0 -11
- data/lib/tap/generator/generators/root/templates/gemspec +0 -27
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -3
- data/lib/tap/generator/generators/task/task_generator.rb +0 -25
- data/lib/tap/generator/generators/task/templates/task.erb +0 -14
- data/lib/tap/generator/generators/task/templates/test.erb +0 -19
- data/lib/tap/generator/manifest.rb +0 -20
- data/lib/tap/generator/preview.rb +0 -69
- data/lib/tap/load.rb +0 -64
- data/lib/tap/spec.rb +0 -41
- data/lib/tap/support/aggregator.rb +0 -65
- data/lib/tap/support/audit.rb +0 -333
- data/lib/tap/support/constant.rb +0 -143
- data/lib/tap/support/constant_manifest.rb +0 -126
- data/lib/tap/support/dependencies.rb +0 -54
- data/lib/tap/support/dependency.rb +0 -44
- data/lib/tap/support/executable.rb +0 -198
- data/lib/tap/support/executable_queue.rb +0 -125
- data/lib/tap/support/gems.rb +0 -43
- data/lib/tap/support/join.rb +0 -144
- data/lib/tap/support/joins.rb +0 -12
- data/lib/tap/support/joins/switch.rb +0 -27
- data/lib/tap/support/joins/sync_merge.rb +0 -38
- data/lib/tap/support/manifest.rb +0 -171
- data/lib/tap/support/minimap.rb +0 -90
- data/lib/tap/support/node.rb +0 -176
- data/lib/tap/support/parser.rb +0 -450
- data/lib/tap/support/schema.rb +0 -385
- data/lib/tap/support/shell_utils.rb +0 -67
- data/lib/tap/test.rb +0 -77
- data/lib/tap/test/assertions.rb +0 -38
- data/lib/tap/test/env_vars.rb +0 -29
- data/lib/tap/test/extensions.rb +0 -73
- data/lib/tap/test/file_test.rb +0 -362
- data/lib/tap/test/file_test_class.rb +0 -15
- data/lib/tap/test/regexp_escape.rb +0 -87
- data/lib/tap/test/script_test.rb +0 -46
- data/lib/tap/test/script_tester.rb +0 -115
- data/lib/tap/test/subset_test.rb +0 -260
- data/lib/tap/test/subset_test_class.rb +0 -99
- data/lib/tap/test/tap_test.rb +0 -109
- data/lib/tap/test/utils.rb +0 -231
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'tap/support/manifest'
|
2
|
-
require 'tap/support/constant'
|
3
|
-
|
4
|
-
module Tap
|
5
|
-
module Support
|
6
|
-
|
7
|
-
# :startdoc:::-
|
8
|
-
#
|
9
|
-
# ConstantManifest builds a manifest of Constant entries using Lazydoc.
|
10
|
-
#
|
11
|
-
# Lazydoc can quickly scan files for constant attributes, and thereby
|
12
|
-
# identify constants based upon a flag like the '::manifest' attribute used
|
13
|
-
# to identify task classes. ConstantManifest registers paths that will be
|
14
|
-
# scanned for a specific resource, and lazily builds the references to load
|
15
|
-
# them as necessary.
|
16
|
-
#
|
17
|
-
# :startdoc:::+
|
18
|
-
class ConstantManifest < Support::Manifest
|
19
|
-
|
20
|
-
# The attribute identifying constants in a file
|
21
|
-
attr_reader :const_attr
|
22
|
-
|
23
|
-
# An array of registered (root, [paths]) pairs
|
24
|
-
# that will be searched for const_attr
|
25
|
-
attr_reader :search_paths
|
26
|
-
|
27
|
-
# The current index of search_paths
|
28
|
-
attr_reader :search_path_index
|
29
|
-
|
30
|
-
# The current index of paths
|
31
|
-
attr_reader :path_index
|
32
|
-
|
33
|
-
# Initializes a new ConstantManifest that will identify constants
|
34
|
-
# using the specified constant attribute.
|
35
|
-
def initialize(const_attr)
|
36
|
-
@const_attr = const_attr
|
37
|
-
@search_paths = []
|
38
|
-
@search_path_index = 0
|
39
|
-
@path_index = 0
|
40
|
-
super([])
|
41
|
-
end
|
42
|
-
|
43
|
-
# Registers the files matching pattern under dir. Returns self.
|
44
|
-
def register(dir, pattern)
|
45
|
-
paths = Dir.glob(File.join(dir, pattern)).select {|file| File.file?(file) }
|
46
|
-
search_paths << [dir, paths.sort]
|
47
|
-
self
|
48
|
-
end
|
49
|
-
|
50
|
-
# Searches all paths for entries and adds them to self. Returns self.
|
51
|
-
def build
|
52
|
-
each {|entry| } unless built?
|
53
|
-
self
|
54
|
-
end
|
55
|
-
|
56
|
-
# True if there are no more paths to search
|
57
|
-
# (ie search_path_index == search_paths.length)
|
58
|
-
def built?
|
59
|
-
search_path_index == search_paths.length
|
60
|
-
end
|
61
|
-
|
62
|
-
# Sets search_path_index and path_index to zero and clears entries.
|
63
|
-
# Returns self.
|
64
|
-
def reset
|
65
|
-
@search_paths.each {|path| Lazydoc[path].resolved = false }
|
66
|
-
@entries.clear
|
67
|
-
@search_path_index = 0
|
68
|
-
@path_index = 0
|
69
|
-
super
|
70
|
-
end
|
71
|
-
|
72
|
-
# Yields each Constant entry to the block. Unless built?, each
|
73
|
-
# lazily iterates over search_paths to look for new entries.
|
74
|
-
def each
|
75
|
-
entries.each do |entry|
|
76
|
-
yield(entry)
|
77
|
-
end
|
78
|
-
|
79
|
-
search_paths[search_path_index, search_paths.length - search_path_index].each do |(path_root, paths)|
|
80
|
-
paths[path_index, paths.length - path_index].each do |path|
|
81
|
-
new_entries = resolve(path_root, path)
|
82
|
-
entries.concat(new_entries)
|
83
|
-
|
84
|
-
@path_index += 1
|
85
|
-
new_entries.each {|entry| yield(entry) }
|
86
|
-
end
|
87
|
-
|
88
|
-
@search_path_index += 1
|
89
|
-
@path_index = 0
|
90
|
-
end unless built?
|
91
|
-
end
|
92
|
-
|
93
|
-
protected
|
94
|
-
|
95
|
-
def minikey(const) # :nodoc:
|
96
|
-
const.path
|
97
|
-
end
|
98
|
-
|
99
|
-
# Scans path for constants having const_attr, and initializes Constant
|
100
|
-
# objects for each. If the document has no default_const_name set,
|
101
|
-
# resolve will set the default_const_name based on the relative
|
102
|
-
# filepath from path_root to path.
|
103
|
-
def resolve(path_root, path) # :nodoc:
|
104
|
-
entries = []
|
105
|
-
document = nil
|
106
|
-
|
107
|
-
Lazydoc::Document.scan(File.read(path), const_attr) do |const_name, key, value|
|
108
|
-
if document == nil
|
109
|
-
relative_path = Root.relative_filepath(path_root, path).chomp(File.extname(path))
|
110
|
-
document = Lazydoc.register_file(path, relative_path.camelize)
|
111
|
-
end
|
112
|
-
|
113
|
-
const_name = document.default_const_name if const_name.empty?
|
114
|
-
comment = Lazydoc::Subject.new(nil, document)
|
115
|
-
comment.value = value
|
116
|
-
|
117
|
-
document[const_name][key] = comment
|
118
|
-
entries << Constant.new(const_name, path)
|
119
|
-
end
|
120
|
-
|
121
|
-
entries
|
122
|
-
end
|
123
|
-
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'tap/support/dependency'
|
2
|
-
|
3
|
-
module Tap
|
4
|
-
module Support
|
5
|
-
|
6
|
-
# Dependencies tracks Executable dependencies and results, and provides
|
7
|
-
# for thread-safe resolution of dependencies.
|
8
|
-
class Dependencies < Monitor
|
9
|
-
|
10
|
-
# Initializes a new Dependencies
|
11
|
-
def initialize
|
12
|
-
super
|
13
|
-
@resolve_stack = []
|
14
|
-
end
|
15
|
-
|
16
|
-
# Thread-safe registration of instance as a dependency. During
|
17
|
-
# registration, instance is extended with the Dependency module.
|
18
|
-
# Returns self.
|
19
|
-
def register(instance)
|
20
|
-
synchronize do
|
21
|
-
unless instance.kind_of?(Dependency)
|
22
|
-
instance.extend Dependency
|
23
|
-
end
|
24
|
-
end
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
# Thread-safe resolution of the instance. Resolve checks for
|
29
|
-
# circular dependencies, then yields control to the block,
|
30
|
-
# which is responsible for the actual resolution.
|
31
|
-
def resolve(instance)
|
32
|
-
synchronize do
|
33
|
-
if @resolve_stack.include?(instance)
|
34
|
-
raise CircularDependencyError.new(@resolve_stack)
|
35
|
-
end
|
36
|
-
|
37
|
-
# mark the results at the index to prevent
|
38
|
-
# infinite loops with circular dependencies
|
39
|
-
@resolve_stack.push instance
|
40
|
-
yield()
|
41
|
-
@resolve_stack.pop
|
42
|
-
end
|
43
|
-
self
|
44
|
-
end
|
45
|
-
|
46
|
-
# Raised when Dependencies#resolve detects a circular dependency.
|
47
|
-
class CircularDependencyError < StandardError
|
48
|
-
def initialize(resolve_stack)
|
49
|
-
super "circular dependency: [#{resolve_stack.join(', ')}]"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Tap
|
2
|
-
module Support
|
3
|
-
|
4
|
-
# Constrains an Executable to only _execute once, and provides several
|
5
|
-
# methods making the Executable behave like a Dependency.
|
6
|
-
module Dependency
|
7
|
-
|
8
|
-
# The audited result of self
|
9
|
-
attr_accessor :_result
|
10
|
-
|
11
|
-
def self.extended(base) # :nodoc:
|
12
|
-
base.instance_variable_set(:@_result, nil)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Conditional _execute; only calls method_name if
|
16
|
-
# resolved? is false (thus assuring self will only
|
17
|
-
# be executed once).
|
18
|
-
#
|
19
|
-
# Returns _result.
|
20
|
-
def _execute(*args)
|
21
|
-
app.dependencies.resolve(self) do
|
22
|
-
@_result = super
|
23
|
-
end unless resolved?
|
24
|
-
_result
|
25
|
-
end
|
26
|
-
|
27
|
-
# Alias for _execute().
|
28
|
-
def resolve
|
29
|
-
_execute
|
30
|
-
end
|
31
|
-
|
32
|
-
# True if _result is non-nil.
|
33
|
-
def resolved?
|
34
|
-
@_result != nil
|
35
|
-
end
|
36
|
-
|
37
|
-
# Resets the dependency by setting _result to nil.
|
38
|
-
def reset
|
39
|
-
@_result = nil
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,198 +0,0 @@
|
|
1
|
-
require 'tap/support/audit'
|
2
|
-
require 'tap/support/joins'
|
3
|
-
|
4
|
-
module Tap
|
5
|
-
module Support
|
6
|
-
|
7
|
-
# Executable wraps objects to make them executable by App.
|
8
|
-
module Executable
|
9
|
-
|
10
|
-
# The App receiving self during enq
|
11
|
-
attr_reader :app
|
12
|
-
|
13
|
-
# The method called during _execute
|
14
|
-
attr_reader :method_name
|
15
|
-
|
16
|
-
# The block called when _execute completes
|
17
|
-
attr_reader :on_complete_block
|
18
|
-
|
19
|
-
# An array of dependency indicies that will be resolved on _execute
|
20
|
-
attr_reader :dependencies
|
21
|
-
|
22
|
-
public
|
23
|
-
|
24
|
-
# Extends obj with Executable and sets up all required variables. The
|
25
|
-
# specified method will be called on _execute.
|
26
|
-
def self.initialize(obj, method_name, app=App.instance, dependencies=[], &on_complete_block)
|
27
|
-
obj.extend Executable
|
28
|
-
obj.instance_variable_set(:@app, app)
|
29
|
-
obj.instance_variable_set(:@method_name, method_name)
|
30
|
-
obj.instance_variable_set(:@on_complete_block, on_complete_block)
|
31
|
-
obj.instance_variable_set(:@dependencies, dependencies)
|
32
|
-
obj
|
33
|
-
end
|
34
|
-
|
35
|
-
# Enqueues self to app with the inputs. The number of inputs provided
|
36
|
-
# should match the number of inputs for the method_name method.
|
37
|
-
def enq(*inputs)
|
38
|
-
app.queue.enq(self, inputs)
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
# Sets a block to receive the results of _execute. Raises an error if
|
43
|
-
# an on_complete_block is already set. Override the existing
|
44
|
-
# on_complete_block by specifying override = true.
|
45
|
-
#
|
46
|
-
# Note: the block recieves an audited result and not the result
|
47
|
-
# itself (see Audit for more information).
|
48
|
-
def on_complete(override=false, &block) # :yields: _result
|
49
|
-
unless on_complete_block == nil || override
|
50
|
-
raise "on_complete_block already set: #{self}"
|
51
|
-
end
|
52
|
-
@on_complete_block = block
|
53
|
-
self
|
54
|
-
end
|
55
|
-
|
56
|
-
# Sets a sequence workflow pattern for the tasks; each task
|
57
|
-
# enques the next task with it's results, starting with self.
|
58
|
-
def sequence(*tasks, &block) # :yields: _result
|
59
|
-
options = tasks[-1].kind_of?(Hash) ? tasks.pop : {}
|
60
|
-
|
61
|
-
current_task = self
|
62
|
-
tasks.each do |next_task|
|
63
|
-
Join.new(options).join([current_task], [next_task], &block)
|
64
|
-
current_task = next_task
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Sets a fork workflow pattern for self; each target will enque the
|
69
|
-
# results of self.
|
70
|
-
def fork(*targets, &block) # :yields: _result
|
71
|
-
options = targets[-1].kind_of?(Hash) ? targets.pop : {}
|
72
|
-
Join.new(options).join([self], targets, &block)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Sets a simple merge workflow pattern for the source tasks. Each
|
76
|
-
# source enques self with it's result; no synchronization occurs,
|
77
|
-
# nor are results grouped before being enqued.
|
78
|
-
def merge(*sources, &block) # :yields: _result
|
79
|
-
options = sources[-1].kind_of?(Hash) ? sources.pop : {}
|
80
|
-
Join.new(options).join(sources, [self], &block)
|
81
|
-
end
|
82
|
-
|
83
|
-
# Sets a synchronized merge workflow for the source tasks. Results
|
84
|
-
# from each source are collected and enqued as a single group to
|
85
|
-
# self. The collective results are not enqued until all sources
|
86
|
-
# have completed. See Joins::SyncMerge.
|
87
|
-
def sync_merge(*sources, &block) # :yields: _result
|
88
|
-
options = sources[-1].kind_of?(Hash) ? sources.pop : {}
|
89
|
-
Joins::SyncMerge.new(options).join(sources, [self], &block)
|
90
|
-
end
|
91
|
-
|
92
|
-
# Sets a switch workflow pattern for self. On complete, switch yields
|
93
|
-
# the audited result to the block and the block should return the index
|
94
|
-
# of the target to enque with the results. No target will be enqued if
|
95
|
-
# the index is false or nil. An error is raised if no target can be
|
96
|
-
# found for the specified index. See Joins::Switch.
|
97
|
-
def switch(*targets, &block) # :yields: _result
|
98
|
-
options = targets[-1].kind_of?(Hash) ? targets.pop : {}
|
99
|
-
Joins::Switch.new(options).join([self], targets, &block)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Adds the dependencies to self. Dependencies are resolved during
|
103
|
-
# _execute through resolve_dependencies.
|
104
|
-
def depends_on(*dependencies)
|
105
|
-
raise ArgumentError, "cannot depend on self" if dependencies.include?(self)
|
106
|
-
|
107
|
-
dependencies.each do |dependency|
|
108
|
-
app.dependencies.register(dependency)
|
109
|
-
self.dependencies << dependency unless self.dependencies.include?(dependency)
|
110
|
-
end
|
111
|
-
|
112
|
-
self
|
113
|
-
end
|
114
|
-
|
115
|
-
# Resolves dependencies. (See Dependency#resolve).
|
116
|
-
def resolve_dependencies
|
117
|
-
dependencies.each {|dependency| dependency.resolve }
|
118
|
-
self
|
119
|
-
end
|
120
|
-
|
121
|
-
# Resets dependencies so they will be re-resolved on
|
122
|
-
# resolve_dependencies. (See Dependency#reset).
|
123
|
-
def reset_dependencies
|
124
|
-
dependencies.each {|dependency| dependency.reset }
|
125
|
-
self
|
126
|
-
end
|
127
|
-
|
128
|
-
# Auditing method call. Resolves dependencies, executes method_name,
|
129
|
-
# and sends the audited result to the on_complete_block (if set).
|
130
|
-
#
|
131
|
-
# Returns the audited result.
|
132
|
-
def _execute(*inputs)
|
133
|
-
resolve_dependencies
|
134
|
-
|
135
|
-
previous = []
|
136
|
-
inputs.collect! do |input|
|
137
|
-
if input.kind_of?(Audit)
|
138
|
-
previous << input
|
139
|
-
input.value
|
140
|
-
else
|
141
|
-
previous << Audit.new(nil, input)
|
142
|
-
input
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
audit = Audit.new(self, send(method_name, *inputs), app.audit ? previous : nil)
|
147
|
-
if complete_block = on_complete_block || app.on_complete_block
|
148
|
-
complete_block.call(audit)
|
149
|
-
else
|
150
|
-
app.aggregator.store(audit)
|
151
|
-
end
|
152
|
-
|
153
|
-
audit
|
154
|
-
end
|
155
|
-
|
156
|
-
# Calls _execute with the inputs and returns the non-audited result.
|
157
|
-
def execute(*inputs)
|
158
|
-
_execute(*inputs).value
|
159
|
-
end
|
160
|
-
|
161
|
-
# Raises a TerminateError if app.state == State::TERMINATE.
|
162
|
-
# check_terminate may be called at any time to provide a
|
163
|
-
# breakpoint in long-running processes.
|
164
|
-
def check_terminate
|
165
|
-
if app.state == App::State::TERMINATE
|
166
|
-
raise App::TerminateError.new
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# Tap extends Object with <tt>_method</tt> to generate executable methods
|
175
|
-
# that can be enqued by Tap::App and incorporated into workflows.
|
176
|
-
#
|
177
|
-
# array = []
|
178
|
-
# push_to_array = array._method(:push)
|
179
|
-
#
|
180
|
-
# task = Tap::Task.new
|
181
|
-
# task.sequence(push_to_array)
|
182
|
-
#
|
183
|
-
# task.enq(1).enq(2,3)
|
184
|
-
# task.app.run
|
185
|
-
#
|
186
|
-
# array # => [[1],[2,3]]
|
187
|
-
#
|
188
|
-
class Object
|
189
|
-
|
190
|
-
# Initializes a Tap::Support::Executable using the object returned by
|
191
|
-
# Object#method(method_name).
|
192
|
-
#
|
193
|
-
# Returns nil if Object#method returns nil.
|
194
|
-
def _method(method_name, app=Tap::App.instance)
|
195
|
-
return nil unless m = method(method_name)
|
196
|
-
Tap::Support::Executable.initialize(m, :call, app)
|
197
|
-
end
|
198
|
-
end
|
@@ -1,125 +0,0 @@
|
|
1
|
-
require 'tap/support/executable'
|
2
|
-
|
3
|
-
module Tap
|
4
|
-
module Support
|
5
|
-
|
6
|
-
# ExecutableQueue allows thread-safe enqueing and dequeing of Executable
|
7
|
-
# methods and inputs for execution.
|
8
|
-
class ExecutableQueue < Monitor
|
9
|
-
|
10
|
-
# Creates a new ExecutableQueue
|
11
|
-
def initialize
|
12
|
-
super
|
13
|
-
@rounds = [[]]
|
14
|
-
end
|
15
|
-
|
16
|
-
# Clears self and returns an array of the enqueued methods and inputs,
|
17
|
-
# organized by round.
|
18
|
-
def clear
|
19
|
-
synchronize do
|
20
|
-
current, @rounds = @rounds, [[]]
|
21
|
-
current
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Returns the number of enqueued methods
|
26
|
-
def size
|
27
|
-
synchronize do
|
28
|
-
size = 0
|
29
|
-
@rounds.each {|round| size += round.length }
|
30
|
-
size
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# True if no methods are enqueued
|
35
|
-
def empty?
|
36
|
-
synchronize { size == 0 }
|
37
|
-
end
|
38
|
-
|
39
|
-
def has?(entry)
|
40
|
-
synchronize do
|
41
|
-
entry_id = entry.object_id
|
42
|
-
|
43
|
-
@rounds.each do |round|
|
44
|
-
round.each do |enqued_entry|
|
45
|
-
return true if entry_id == enqued_entry.object_id
|
46
|
-
end
|
47
|
-
end
|
48
|
-
false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Enqueues the method and inputs. Raises an error if the
|
53
|
-
# method is not an Executable.
|
54
|
-
def enq(method, inputs)
|
55
|
-
synchronize do
|
56
|
-
check_method(method)
|
57
|
-
queue.push [method, inputs]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Enqueues the method and inputs, but to the top of the queue.
|
62
|
-
# Raises an error if the method is not an Executable.
|
63
|
-
def unshift(method, inputs)
|
64
|
-
synchronize do
|
65
|
-
check_method(method)
|
66
|
-
queue.unshift [method, inputs]
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Dequeues the next method and inputs as an array like
|
71
|
-
# [method, inputs]. Returns nil if the queue is empty.
|
72
|
-
def deq
|
73
|
-
synchronize { queue.shift }
|
74
|
-
end
|
75
|
-
|
76
|
-
# Enques an array of [method, inputs] entries as a round. Rounds are
|
77
|
-
# dequeued completely before the next round is dequeued.
|
78
|
-
def concat(round)
|
79
|
-
synchronize do
|
80
|
-
round.each do |method, inputs|
|
81
|
-
check_method(method)
|
82
|
-
end
|
83
|
-
|
84
|
-
@rounds << round
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# Converts self to an array. If flatten is specified, all rounds are
|
89
|
-
# concatenated into a single array.
|
90
|
-
def to_a(flatten=true)
|
91
|
-
synchronize do
|
92
|
-
if flatten
|
93
|
-
array = []
|
94
|
-
@rounds.each {|round| array.concat(round) }
|
95
|
-
array
|
96
|
-
else
|
97
|
-
@rounds.collect {|round| round.dup}
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
protected
|
103
|
-
|
104
|
-
# Returns the active round.
|
105
|
-
def queue # :nodoc:
|
106
|
-
while @rounds.length > 1
|
107
|
-
queue = @rounds[0]
|
108
|
-
|
109
|
-
if queue.empty?
|
110
|
-
@rounds.shift
|
111
|
-
else
|
112
|
-
return queue
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
@rounds[0]
|
117
|
-
end
|
118
|
-
|
119
|
-
# Checks if the input method is extended with Executable
|
120
|
-
def check_method(method) # :nodoc:
|
121
|
-
raise "not executable: #{method.inspect}" unless method.kind_of?(Executable)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|