lib/roby/planning/task.rb in roby-0.7.3 vs lib/roby/planning/task.rb in roby-0.8.0
- old
+ new
@@ -1,51 +1,73 @@
-require 'roby/task'
-require 'roby/relations/planned_by'
-require 'roby/control'
-require 'roby/transactions'
-
module Roby
# An asynchronous planning task using Ruby threads
class PlanningTask < Roby::Task
attr_reader :planner, :transaction
- arguments :planner_model, :method_name,
- :method_options, :planned_model,
- :planning_owners
+ arguments :planner_model, :method_options, :method_name, :planned_model, :planning_owners
+ def planning_method
+ arguments[:planning_method]
+ end
+
+ def self.validate_planning_options(options)
+ options = options.dup
+ if options[:method_name]
+ method_name = options[:planning_method] = options[:method_name]
+ elsif options[:planning_method].respond_to?(:to_str) || options[:planning_method].respond_to?(:to_sym)
+ method_name = options[:method_name] = options[:planning_method].to_s
+ end
+
+ if !options[:planner_model]
+ raise ArgumentError, "missing required argument 'planner_model'"
+ elsif !options[:planning_method]
+ raise ArgumentError, "missing required argument 'planning_method'"
+ elsif !method_name
+ if options[:planning_method].kind_of?(Roby::Planning::MethodDefinition)
+ method_name = options[:method_name] = options[:planning_method].name
+ else
+ raise ArgumentError, "the planning_method argument is neither a method object nor a name"
+ end
+ end
+ options[:planned_model] ||= nil
+ options[:planning_owners] ||= nil
+ options
+ end
+
def self.filter_options(options)
task_options, method_options = Kernel.filter_options options,
:planner_model => nil,
- :method_name => nil,
+ :planning_method => nil,
:method_options => {},
+ :method_name => nil, # kept for backward compatibility
:planned_model => nil,
:planning_owners => nil
- if !task_options[:planner_model]
- raise ArgumentError, "missing required argument 'planner_model'"
- elsif !task_options[:method_name]
- raise ArgumentError, "missing required argument 'method_name'"
- end
- task_options[:planned_model] ||= nil
+ task_options = validate_planning_options(task_options)
task_options[:method_options] ||= Hash.new
task_options[:method_options].merge! method_options
- task_options[:planning_owners] ||= nil
task_options
end
def initialize(options)
task_options = PlanningTask.filter_options(options)
super(task_options)
end
def planned_model
- arguments[:planned_model] ||= planner_model.model_of(method_name, method_options).returns || Roby::Task
+ arguments[:planned_model] ||= if method_name
+ planner_model.model_of(method_name, method_options).returns
+ else
+ planning_method.returns
+ end
+
+ arguments[:planned_model] ||= Roby::Task
end
def to_s
- "#{super}[#{method_name}:#{method_options}] -> #{@planned_task || "nil"}"
+ "#{super}[#{planning_method}:#{method_options}] -> #{@planned_task || "nil"}"
end
def planned_task
if success? || result
result
@@ -86,11 +108,15 @@
planning_thread(context)
end
end
def planning_thread(context)
- result_task = planner.send(method_name, method_options.merge(:context => context))
+ result_task = if planning_method.kind_of?(Roby::Planning::MethodDefinition)
+ planner.send(:call_planning_methods, Hash.new, method_options.merge(:context => context), planning_method)
+ else
+ planner.send(method_name, method_options.merge(:context => context))
+ end
# Don't replace the planning task with ourselves if the
# transaction specifies another planning task
if !result_task.planning_task
result_task.planned_by transaction[self]
@@ -116,11 +142,11 @@
return
end
# Check if the transaction has been committed. If it is not the
# case, assume that the thread failed
- if transaction.freezed?
+ if transaction.committed?
emit :success
else
error = begin
thread.value
rescue Exception => e
@@ -143,9 +169,10 @@
end
class TransactionProxy < Roby::Transactions::Task
proxy_for PlanningTask
def_delegator :@__getobj__, :planner
+ def_delegator :@__getobj__, :planning_method
def_delegator :@__getobj__, :method_name
def_delegator :@__getobj__, :method_options
end
end
end