tap 0.12.4 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|