lib/progressive_press.rb
70 lines · ruby
Project files
# frozen_string_literal: true
require_relative "placement"
require_relative "press_results"
class ProgressivePress
def initialize(stations:)
@stations = stations.dup.freeze
@plate = Array.new(@stations.length)
@completed = []
end
def feed(work)
return Placement.new(item: work, reason: :position_occupied) if @plate[0]
@plate[0] = work
Placement.new(item: work, reason: nil)
end
def cycle
outcomes = stroke
return CycleResult.new(advanced: false, outcomes: outcomes, ejected: nil) if faulted?(outcomes)
CycleResult.new(advanced: true, outcomes: outcomes, ejected: advance)
end
def positions
@stations.zip(@plate).map { |station, work| PositionSnapshot.new(station:, work:) }.freeze
end
def completed
@completed.dup.freeze
end
def empty?
@plate.compact.empty?
end
private
def stroke
@stations.each_with_index.map { |station, index| strike(station, index) }
end
def strike(station, index)
work = @plate[index]
return PositionOutcome.new(station: station.name, status: :empty, fault: nil) unless work
record_strike(index, station.apply(work))
end
def record_strike(index, result)
name = @stations[index].name
return PositionOutcome.new(station: name, status: :faulted, fault: result.fault) if result.fault
@plate[index] = result.work
PositionOutcome.new(station: name, status: :completed, fault: nil)
end
def faulted?(outcomes)
outcomes.any? { |outcome| outcome.status == :faulted }
end
def advance
ejected = @plate.last
@plate = [nil, *@plate[0..-2]]
@completed << ejected if ejected
ejected
end
end
Read along in the manual: The Reloading Lab · Download the project (zip)