# frozen_string_literal: true require_relative '../command' require_relative '../frame' require_relative '../frame_buffer' require_relative '../publish_scanner_data_worker' require 'pastel' require 'serialport' module Sftui module Commands class Stream < Sftui::Command def initialize(uart, options) @uart = uart @options = options @serialport = SerialPort.new(uart) @frame_buffer = FrameBuffer.new @byte_buffer = [] end def execute pastel = Pastel.new puts pastel.red.bold('📡 Streaming') trap 'INT' do @serialport.flush puts pastel.red.bold('Stopped!') exit end @serialport.flush main end def main loop do c = @serialport.read(1).ord @byte_buffer << c frame = Frame.new(@byte_buffer) next unless frame.completed? puts frame.display handle_frame(frame) @byte_buffer = [] end end def handle_frame(frame) # rubocop:disable Metrics/MethodLength previous_frame = @frame_buffer.latest_frame if frame.machine_id == previous_frame&.machine_id @frame_buffer.pop(previous_frame) @frame_buffer.push(previous_frame + frame) else @frame_buffer.push(frame) end latest_frame = @frame_buffer.latest_frame return unless latest_frame.last_frame_in_transaction? publish_scanner_data(latest_frame) @frame_buffer.pop(latest_frame) end def publish_scanner_data(frame) PublishScannerDataWorker.perform_async( { machine_id: frame.machine_id, data: frame.sanitized_data } ) end end end end