Class: Charming::Audio::System

Inherits:
Object
  • Object
show all
Defined in:
lib/charming/audio/system.rb

Overview

System is the OS adapter the Player uses to locate and control audio-player processes. It wraps Ruby’s ‘Process`/`ENV`/`RbConfig` so specs can substitute a fake collaborator and never shell out, touch the real process table, or play sound.

Instance Method Summary collapse

Constructor Details

#initialize(host_os: RbConfig::CONFIG["host_os"], path: ENV["PATH"]) ⇒ System

host_os identifies the platform (defaults to the running Ruby’s). path is the ‘PATH` string searched by #which? (defaults to the process environment).



11
12
13
14
# File 'lib/charming/audio/system.rb', line 11

def initialize(host_os: RbConfig::CONFIG["host_os"], path: ENV["PATH"])
  @host_os = host_os.to_s
  @path = path.to_s
end

Instance Method Details

#alive?(pid) ⇒ Boolean

True while pid is still running. Reaps the child (non-blocking) once it exits.

Returns:

  • (Boolean)


48
49
50
51
52
# File 'lib/charming/audio/system.rb', line 48

def alive?(pid)
  Process.waitpid(pid, Process::WNOHANG).nil?
rescue Errno::ECHILD, Errno::ESRCH
  false
end

#linux?Boolean

True on Linux.

Returns:

  • (Boolean)


22
23
24
# File 'lib/charming/audio/system.rb', line 22

def linux?
  @host_os.match?(/linux/i)
end

#macos?Boolean

True on macOS.

Returns:

  • (Boolean)


17
18
19
# File 'lib/charming/audio/system.rb', line 17

def macos?
  @host_os.match?(/darwin/i)
end

#spawn(argv) ⇒ Object

Spawns argv (an array) detached from the terminal, discarding the child’s stdout/stderr, and returns the child PID.



36
37
38
# File 'lib/charming/audio/system.rb', line 36

def spawn(argv)
  Process.spawn(*argv, out: File::NULL, err: File::NULL)
end

#terminate(pid) ⇒ Object

Sends ‘SIGTERM` to pid, ignoring a process that has already exited.



41
42
43
44
45
# File 'lib/charming/audio/system.rb', line 41

def terminate(pid)
  Process.kill("TERM", pid)
rescue Errno::ESRCH
  nil
end

#wait(pid) ⇒ Object

Blocks until pid exits, then reaps it. No-op when the child is already gone.



55
56
57
58
59
# File 'lib/charming/audio/system.rb', line 55

def wait(pid)
  Process.waitpid(pid)
rescue Errno::ECHILD, Errno::ESRCH
  nil
end

#which?(command) ⇒ Boolean

True when command resolves to an executable file on ‘PATH`.

Returns:

  • (Boolean)


27
28
29
30
31
32
# File 'lib/charming/audio/system.rb', line 27

def which?(command)
  path_dirs.any? do |dir|
    candidate = File.join(dir, command)
    File.file?(candidate) && File.executable?(candidate)
  end
end