Class: Roby::Queries::TaskMatcher
- Inherits:
-
PlanObjectMatcher
- Object
- MatcherBase
- PlanObjectMatcher
- Roby::Queries::TaskMatcher
- Includes:
- DRoby::V5::Queries::TaskMatcherDumper
- Defined in:
- lib/roby/queries/task_matcher.rb,
lib/roby/droby/enable.rb
Overview
This class represents a predicate which can be used to filter tasks. To filter plan-related properties, use Query.
A TaskMatcher object is a AND combination of various tests against tasks.
For instance, if one does
matcher = TaskMatcher.new.which_fullfills(Tasks::Simple).pending
Then
matcher === task
will return true if task is an instance of the Tasks::Simple model and is pending (not started yet), and false if one of these two characteristics is not true.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#arguments ⇒ Hash
readonly
Set of arguments that should be tested on the task.
Attributes inherited from PlanObjectMatcher
#children, #indexed_neg_predicates, #indexed_predicates, #instance, #model, #owners, #parents
Attributes inherited from MatcherBase
Instance Method Summary collapse
-
#===(task) ⇒ Object
True if
taskmatches all the criteria defined on this object. -
#abstract? ⇒ Object
:method: not_finishing.
- #find_event(event_name) ⇒ Object
-
#handle_parent_child_arguments(other_query, relation, relation_options) ⇒ Object
Helper method for #with_child and #with_parent.
-
#indexed_query? ⇒ Boolean
Returns true if filtering with this TaskMatcher using #=== is equivalent to calling #filter() using a Index.
-
#initialize ⇒ TaskMatcher
constructor
Initializes an empty TaskMatcher object.
- #method_missing(m, *args) ⇒ Object
- #respond_to_missing?(m, include_private) ⇒ Boolean
- #to_s ⇒ Object
-
#which_fullfills(model, arguments = nil) ⇒ Object
Filters on task model and arguments.
-
#with_arguments(arguments) ⇒ Object
Filters on the arguments that are declared in the model.
-
#with_model_arguments(arguments) ⇒ Object
Filters on the arguments that are declared in the model.
Methods included from DRoby::V5::Queries::TaskMatcherDumper
Methods inherited from PlanObjectMatcher
#executable?, #filter, #handle_parent_child_match, #indexed_sets, match_predicate, #not_self_owned, #owned_by, #self_owned, #with_child, #with_instance, #with_model, #with_parent
Methods included from DRoby::V5::Queries::PlanObjectMatcherDumper
Methods inherited from MatcherBase
#&, declare_class_methods, #describe_failed_match, #each, #match, match_predicate, match_predicates, #negate, #|
Constructor Details
#initialize ⇒ TaskMatcher
Initializes an empty TaskMatcher object
27 28 29 30 31 |
# File 'lib/roby/queries/task_matcher.rb', line 27 def initialize super @arguments = Hash.new @interruptible = nil end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args) ⇒ Object
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/roby/queries/task_matcher.rb', line 316 def method_missing(m, *args) if m =~ /_event$/ event_name = $` model = find_event(event_name) if !model task_models = if !@model.empty? @model else [Roby::Task] end raise NoMethodError.new(m), "no event '#{event_name}' in match model #{task_models.map(&:to_s).join(", ")}, use #which_fullfills to narrow the task model" elsif !args.empty? raise ArgumentError, "#{m} expected zero arguments, got #{args.size}" else return TaskEventGeneratorMatcher.new(self, event_name) end else super end end |
Instance Attribute Details
#arguments ⇒ Hash (readonly)
Set of arguments that should be tested on the task
24 25 26 |
# File 'lib/roby/queries/task_matcher.rb', line 24 def arguments @arguments end |
Instance Method Details
#===(task) ⇒ Object
True if task matches all the criteria defined on this object.
285 286 287 288 289 |
# File 'lib/roby/queries/task_matcher.rb', line 285 def ===(task) return unless task.kind_of?(Roby::Task) return unless task.arguments.slice(*arguments.keys) == arguments return super end |
#abstract? ⇒ Object
:method: not_finishing
Matches if the task is not finishing
See also #finishing, Task#finishing?
260 261 |
# File 'lib/roby/queries/task_matcher.rb', line 260 match_predicates :abstract?, :partially_instanciated?, :fully_instanciated?, :starting?, :pending?, :running?, :finished?, :success?, :failed?, :interruptible? |
#find_event(event_name) ⇒ Object
298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/roby/queries/task_matcher.rb', line 298 def find_event(event_name) event_name = event_name.to_sym models = if !@model.empty? @model else [Roby::Task] end models.each do |m| if event_m = m.find_event(event_name) return TaskEventGeneratorMatcher.new(self, event_name) end end nil end |
#handle_parent_child_arguments(other_query, relation, relation_options) ⇒ Object
Helper method for #with_child and #with_parent
271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/roby/queries/task_matcher.rb', line 271 def handle_parent_child_arguments(other_query, relation, ) # :nodoc: if !other_query.kind_of?(TaskMatcher) && !other_query.kind_of?(Task) if relation.kind_of?(Hash) arguments = relation relation = (arguments.delete(:relation) || arguments.delete('relation')) = (arguments.delete(:relation_options) || arguments.delete('relation_options')) else arguments = Hash.new end other_query = TaskMatcher.which_fullfills(other_query, arguments) end return relation, [other_query, ] end |
#indexed_query? ⇒ Boolean
Returns true if filtering with this TaskMatcher using #=== is equivalent to calling #filter() using a Index. This is used to avoid an explicit O(N) filtering step after filter() has been called
294 295 296 |
# File 'lib/roby/queries/task_matcher.rb', line 294 def indexed_query? arguments.empty? && super end |
#respond_to_missing?(m, include_private) ⇒ Boolean
312 313 314 |
# File 'lib/roby/queries/task_matcher.rb', line 312 def respond_to_missing?(m, include_private) m =~ /_event$/ || super end |
#to_s ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/roby/queries/task_matcher.rb', line 33 def to_s result = super if !arguments.empty? result << ".with_arguments(#{arguments.map { |k, v| ":#{k} => #{v}" }.join(", ")})" end result end |
#which_fullfills(model, arguments = nil) ⇒ Object
Filters on task model and arguments
Will match if the task is an instance of model or one of its subclasses, and if parts of its arguments are the ones provided. Set arguments to nil if you don’t want to filter on arguments.
46 47 48 49 50 51 52 |
# File 'lib/roby/queries/task_matcher.rb', line 46 def which_fullfills(model, arguments = nil) with_model(model) if arguments with_model_arguments(arguments) end self end |
#with_arguments(arguments) ⇒ Object
Filters on the arguments that are declared in the model
Will match if the task arguments for which there is a value in arguments are set to that very value. Unlike #with_model_arguments, all values set in arguments are considered.
See also #with_model_arguments
Example:
class TaskModel < Roby::Task
argument :a
argument :b
end
task = TaskModel.new(a: 10, b: 20)
# Matches on :a, :b is ignored altogether
TaskMatcher.new.
with_arguments(a: 10) === task # => true
# Looks for both :a and :b
TaskMatcher.new.
with_arguments(a: 10, b: 30) === task # => false
# Looks for both :a and :c, even though :c is not declared in TaskModel
TaskMatcher.new.
with_arguments(a: 10, c: 30) === task # => false
116 117 118 119 120 121 122 123 124 125 |
# File 'lib/roby/queries/task_matcher.rb', line 116 def with_arguments(arguments) @arguments ||= Hash.new self.arguments.merge!(arguments) do |k, old, new| if old != new raise ArgumentError, "a constraint has already been set on the #{k} argument" end old end self end |
#with_model_arguments(arguments) ⇒ Object
Filters on the arguments that are declared in the model
Will match if the task arguments for which there is a value in arguments are set to that very value, only looking at arguments that are defined in the model set by #with_model.
See also #with_arguments
Example:
class TaskModel < Roby::Task
argument :a
argument :b
end
task = TaskModel.new(a: 10, b: 20)
# Matches on :a, :b is ignored altogether
TaskMatcher.new.
with_model(TaskModel).
with_model_arguments(a: 10) === task # => true
# Looks for both :a and :b
TaskMatcher.new.
with_model(TaskModel).
with_model_arguments(a: 10, b: 30) === task # => false
# Matches on :a, :c is ignored as it is not an argument of +TaskModel+
TaskMatcher.new.
with_model(TaskModel).
with_model_arguments(a: 10, c: 30) === task # => true
In general, one would use #which_fullfills, which sets both the model and the model arguments
85 86 87 88 89 |
# File 'lib/roby/queries/task_matcher.rb', line 85 def with_model_arguments(arguments) valid_arguments = model.inject(Array.new) { |set, model| set | model.arguments.to_a } with_arguments(arguments.slice(*valid_arguments)) self end |