lib/whirled_peas/frame/producer.rb in whirled_peas-0.3.0 vs lib/whirled_peas/frame/producer.rb in whirled_peas-0.4.0

- old
+ new

@@ -1,50 +1,61 @@ require 'socket' require 'json' +require_relative '../null_logger' + module WhirledPeas module Frame class Producer LOGGER_ID = 'PRODUCER' - def self.produce(event_loop:, logger: NullLogger.new) - producer = new(event_loop, logger) - logger.info(LOGGER_ID) { 'Starting' } + # Manages the EventLoop lifecycle and yields a Producer to send frames to the + # EventLoop + def self.produce(consumer, logger=NullLogger.new) + producer = new(consumer, logger) + consumer_thread = Thread.new do + Thread.current.report_on_exception = false + consumer.start + end yield producer - logger.info(LOGGER_ID) { 'Done with yield' } producer.send_frame(Frame::EOF) - logger.info(LOGGER_ID) { 'Exited normally' } + producer.flush rescue => e - producer.send_frame(Frame::TERMINATE) + consumer.stop if consumer logger.warn(LOGGER_ID) { 'Exited with error' } logger.error(LOGGER_ID) { e } raise + ensure + consumer_thread.join if consumer_thread end - def initialize(event_loop, logger=NullLogger.new) - @event_loop = event_loop + def initialize(consumer, logger=NullLogger.new) + @consumer = consumer @logger = logger @queue = Queue.new end + # Buffer a frame to be played for the given duration. `#flush` must be called + # for frames to get pushed to the EventLoop. + # + # @param name [String] name of frame, which is passed to #build of the + # TemplateFactory + # @param duration [Float|Integer] duration in seconds the frame should be, + # displayed (default is nil, which results in a duration of a single refresh + # cycle) + # @param args [Hash] key/value pair of arguments, which is passed to #build of + # the TemplateFactory def send_frame(name, duration: nil, args: {}) - event_loop.enqueue(name: name, duration: duration, args: args) - logger.debug(LOGGER_ID) { "Sending frame: #{name}" } - end - - def enqueue_frame(name, duration: nil, args: {}) queue.push([name, duration, args]) end + # Send any buffered frames to the EventLoop def flush - while !queue.empty? - name, duration, args = queue.pop - send_frame(name: name, duration: duration, args: args) - end + consumer.enqueue(*queue.pop) while !queue.empty? end private - attr_reader :event_loop, :logger + attr_reader :consumer, :logger, :queue end end end