Class: Btape::Recorder
- Inherits:
-
Object
- Object
- Btape::Recorder
- Defined in:
- lib/btape/recorder.rb
Overview
Captures the frames a GIF is built from.
In :interval mode it screenshots the page on a background thread until stopped. In :manual mode it captures only when the script asks with a Screenshot command, which is what a tape wants when it needs one frame per page rather than a few hundred near-identical ones.
Constant Summary collapse
- FRAME_NAME =
A name becomes part of a filename, so it may not carry anything that would put the frame somewhere other than the frames directory. Parser checks it too, to report a bad Screenshot line with its line number; this is the check for everyone else, since capture is public API.
/\A[\w.-]+\z/
Instance Attribute Summary collapse
-
#named_paths ⇒ Object
readonly
Returns the value of attribute named_paths.
-
#paths ⇒ Object
readonly
Returns the value of attribute paths.
Instance Method Summary collapse
-
#capture(name: nil) ⇒ Object
Captures one frame now.
-
#initialize(page, directory, interval: 0.1, mode: :interval, on_frame: nil, max_frames: nil, lock: Monitor.new) ⇒ Recorder
constructor
A new instance of Recorder.
- #start ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(page, directory, interval: 0.1, mode: :interval, on_frame: nil, max_frames: nil, lock: Monitor.new) ⇒ Recorder
Returns a new instance of Recorder.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/btape/recorder.rb', line 19 def initialize(page, directory, interval: 0.1, mode: :interval, on_frame: nil, max_frames: nil, lock: Monitor.new) @page = page @directory = directory @interval = interval @mode = mode.to_sym @on_frame = on_frame @max_frames = max_frames # Shared with the executor, so a screenshot and a command are never in # flight against the same page at once. @lock = lock @paths = [] @named_paths = {} end |
Instance Attribute Details
#named_paths ⇒ Object (readonly)
Returns the value of attribute named_paths.
34 35 36 |
# File 'lib/btape/recorder.rb', line 34 def named_paths @named_paths end |
#paths ⇒ Object (readonly)
Returns the value of attribute paths.
34 35 36 |
# File 'lib/btape/recorder.rb', line 34 def paths @paths end |
Instance Method Details
#capture(name: nil) ⇒ Object
Captures one frame now. A name puts it at a predictable path, so a caller can pick a particular frame out of the run.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/btape/recorder.rb', line 63 def capture(name: nil) validate_name!(name) path, index = @lock.synchronize do exhausted! if @max_frames && @paths.length >= @max_frames path = File.join(@directory, filename(name)) screenshot(path) index = @paths.length @paths << path @named_paths[name] = path if name [path, index] end # Outside the lock: the callback is the caller's code and may take as # long as it likes without holding up the next capture. @on_frame&.call(path, index) path end |
#start ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/btape/recorder.rb', line 36 def start return if manual? capture @running = true @thread = Thread.new do loop do sleep @interval capture end rescue StandardError => e @error = e end end |
#stop ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/btape/recorder.rb', line 51 def stop return unless @running @running = false @thread&.kill @thread&.join capture raise @error if @error end |