diff options
Diffstat (limited to 'lua/clever_f')
| -rw-r--r-- | lua/clever_f/sequence_coordinator.lua | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/lua/clever_f/sequence_coordinator.lua b/lua/clever_f/sequence_coordinator.lua index 5a05f53..ee50fbd 100644 --- a/lua/clever_f/sequence_coordinator.lua +++ b/lua/clever_f/sequence_coordinator.lua @@ -1,6 +1,7 @@ local acquisition_service_factory = require("clever_f.acquisition_service") local domain = require("clever_f.domain") local feedback_service_factory = require("clever_f.feedback_service") +local motion_executor_factory = require("clever_f.motion_executor") local motion_plan_factory = require("clever_f.motion_plan") local policy = require("clever_f.policy") local repeat_resolver_factory = require("clever_f.repeat_resolver") @@ -100,6 +101,17 @@ function SequenceCoordinator.new(options) if type(acquisition) ~= "table" or type(acquisition.acquire) ~= "function" then fail("SequenceCoordinator acquisition service must provide acquire", 2) end + local executor = options.motion_executor + or options.executor + or motion_executor_factory.new({ + host = host, + state = state, + transitions = transitions, + feedback = feedback, + }) + if type(executor) ~= "table" or type(executor.execute) ~= "function" then + fail("SequenceCoordinator motion executor must provide execute", 2) + end local coordinator = setmetatable({}, SequenceCoordinator) coordinator_records[coordinator] = { @@ -112,6 +124,8 @@ function SequenceCoordinator.new(options) target_factory = target_factory, motion_factory = motion_factory, acquisition = acquisition, + motion_executor = executor, + last_primary_resolution = nil, } return coordinator end @@ -410,6 +424,36 @@ function SequenceCoordinator:stored_primary_resolution( return resolution end +function SequenceCoordinator:execute_primary_resolution(resolution) + if type(resolution) ~= "table" + or not domain.ModeContext.is(resolution.invocation.context) + or not domain.ResolvedMotionPlan.is(resolution.motion_plan) + then + fail("primary execution requires a resolved motion", 2) + end + local record = coordinator_records[self] + record.last_primary_resolution = resolution + if resolution.skip_destination then + return domain.ActionOutcome.empty(resolution.invocation.position) + end + local view = resolution.text_view or text_topology.from_host(record.host) + local outcome = record.motion_executor:execute( + view, + resolution.invocation.context, + resolution.motion_plan, + resolution.invocation.count, + resolution.first_move + ) + if not domain.ActionOutcome.is(outcome) then + fail("MotionExecutor must return an ActionOutcome", 2) + end + return outcome +end + +function SequenceCoordinator:last_primary_resolution() + return coordinator_records[self].last_primary_resolution +end + function SequenceCoordinator:primary(value) local descriptor = self:validate_primary_descriptor(value) local invocation = self:read_primary_invocation() @@ -420,7 +464,11 @@ function SequenceCoordinator:primary(value) ) invocation.repeat_decision = self:decide_primary(invocation) if invocation.repeat_decision == repeat_resolver_factory.Decision.ACQUIRE then - return self:resolve_acquisition(descriptor, invocation) + local acquired = self:resolve_acquisition(descriptor, invocation) + if domain.ActionOutcome.is(acquired) then + return acquired + end + return self:execute_primary_resolution(acquired) end local timeout = self:evaluate_repeat_timeout(invocation) if timeout.decision == repeat_resolver_factory.Decision.ACQUIRE then @@ -431,9 +479,15 @@ function SequenceCoordinator:primary(value) end record.feedback:release_transition_cleanup(timeout.cleanup) end - return self:resolve_acquisition(descriptor, invocation) + local acquired = self:resolve_acquisition(descriptor, invocation) + if domain.ActionOutcome.is(acquired) then + return acquired + end + return self:execute_primary_resolution(acquired) end - return self:stored_primary_resolution(invocation, descriptor, timeout) + return self:execute_primary_resolution( + self:stored_primary_resolution(invocation, descriptor, timeout) + ) end function M.new(options) |
