Skip to content

Commit

Permalink
Tools - add barebones REPL
Browse files Browse the repository at this point in the history
This can be used as a template for integration with external tools
  • Loading branch information
samaaron committed Jul 29, 2024
1 parent 675d178 commit 05e49e4
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
72 changes: 72 additions & 0 deletions app/server/ruby/bin/repl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require 'open3'

require_relative "../lib/sonicpi/osc/osc"
require_relative "../paths"
require_relative "../lib/sonicpi/promise"

## This is a very simple barebones REPL for Sonic Pi
## All stdin is sent to Sonic Pi for evaluation and output is sent to stdout
## It also ensures the server is kept alive.

module SonicPi
class Repl
def initialize()
daemon_stdin, daemon_stdout_and_err, daemon_wait_thr = Open3.popen2e Paths.ruby_path, Paths.daemon_path

puts "Sonic Pi Daemon started with PID: #{daemon_wait_thr.pid}"
puts "Log files are located at: #{Paths.log_path}"

daemon_info_prom = Promise.new

daemon_io_thr = Thread.new do
daemon_stdout_and_err.each do |line|
line = line.force_encoding("UTF-8")
daemon_info_prom.deliver! line
Thread.current.kill
end
end

daemon_info = daemon_info_prom.get.split.map(&:to_i)

daemon_port = daemon_info[0]
gui_listen_to_spider_port = daemon_info[1]
gui_send_to_spider_port = daemon_info[2]
scsynth_port = daemon_info[3]
osc_cues_port = daemon_info[4]
tau_port = daemon_info[5]
tau_booter_port = daemon_info[6]
daemon_token = daemon_info[7]

puts "OSC Cues port: #{osc_cues_port}"

daemon_zombie_feeder = Thread.new do
osc_client = OSC::UDPClient.new("localhost", daemon_port)

at_exit do
puts "Killing the Daemon..."
osc_client.send("/daemon/exit", daemon_token)
end

loop do
osc_client.send("/daemon/keep-alive", daemon_token)
sleep 5
end
end

repl_print_osc_server = OSC::UDPServer.new(gui_listen_to_spider_port)
repl_print_osc_server.add_global_method do |osc_path, msg|
puts "#{osc_path} #{msg[1]}"
end

repl_eval_osc_client = OSC::UDPClient.new("localhost", gui_send_to_spider_port)

loop do
input = gets
repl_eval_osc_client.send("/run-code", daemon_token, input)
end
end
end
end


SonicPi::Repl.new()
4 changes: 4 additions & 0 deletions app/server/ruby/paths.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ def self.ruby_path
end
end

def self.daemon_path
File.absolute_path("#{server_path}/ruby/bin/daemon.rb")
end


def self.tau_boot_path
case os
Expand Down
18 changes: 18 additions & 0 deletions bin/sonic-pi-repl.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@echo off
REM Note: set the SONIC_PI_HOME env variable to specify the location of the log files
REM otherwise it will default to Sonic Pi's standard location in the home directory

set SCRIPT_DIR=%~dp0
set WORKING_DIR=%cd%

set RUBY_PATH=%SCRIPT_DIR%\..\app\server\native\ruby\bin\ruby.exe
if not exist "%RUBY_PATH%" (
set RUBY_PATH=ruby
)

cd "%SCRIPT_DIR%"
"%RUBY_PATH%" "..\app\server\ruby\bin\repl.rb"

REM Restore working directory as it was prior to this script running...
echo Goodbye...
cd "%WORKING_DIR%"
26 changes: 26 additions & 0 deletions bin/sonic-pi-repl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

## Note: set the SONIC_PI_HOME env variable to specify the location of the log files
## otherwise it will default to Sonic Pi's standard location in the home directory

set -e # Quit script on error

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
WORKING_DIR="$(pwd)"

cleanup_function() {
echo "Goodbye..."
cd "${WORKING_DIR}"
}

RUBY_PATH="${SCRIPT_DIR}/../app/server/native/ruby/bin/ruby"
if [ ! -x "${RUBY_PATH}" ]; then
RUBY_PATH="ruby"
fi


cd "${SCRIPT_DIR}"
"${RUBY_PATH}" "../app/server/ruby/bin/repl.rb"

# Restore working directory as it was prior to this script running...
trap cleanup_function EXIT

0 comments on commit 05e49e4

Please sign in to comment.