diff options
| author | Tom Black <[email protected]> | 2018-12-12 01:58:37 -0800 |
|---|---|---|
| committer | Tom Black <[email protected]> | 2018-12-12 18:01:00 -0800 |
| commit | 2ca4a07d60357c3b32625a706f7411997b6258c0 (patch) | |
| tree | 732e6066c895676b08b32c537609276ec8df6b98 | |
| parent | 241093f3ea07255af6d36fa9e07c2a1ecb7c712f (diff) | |
| download | ruby2d-2ca4a07d60357c3b32625a706f7411997b6258c0.tar.gz ruby2d-2ca4a07d60357c3b32625a706f7411997b6258c0.zip | |
Add an interactive console
Also moves `bin/ruby2d` functionality to new `lib/ruby2d/cli` dir
| -rwxr-xr-x | bin/ruby2d | 240 | ||||
| -rw-r--r-- | lib/ruby2d/cli/build.rb | 181 | ||||
| -rw-r--r-- | lib/ruby2d/cli/console.rb | 49 | ||||
| -rw-r--r-- | lib/ruby2d/cli/enable_console.rb | 5 | ||||
| -rw-r--r-- | lib/ruby2d/cli/launch.rb | 50 | ||||
| -rw-r--r-- | lib/ruby2d/window.rb | 22 | ||||
| -rw-r--r-- | test/console.rb | 25 |
7 files changed, 341 insertions, 231 deletions
@@ -1,247 +1,19 @@ #!/usr/bin/env ruby + require 'ruby2d/colorize' require 'ruby2d/version' -require 'fileutils' - -# The installed gem directory -@gem_dir = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}" - -# The Ruby 2D library files -@lib_files = [ - 'renderable', - 'exceptions', - 'color', - 'window', - 'dsl', - 'quad', - 'line', - 'circle', - 'rectangle', - 'square', - 'triangle', - 'image', - 'sprite', - 'font', - 'text', - 'sound', - 'music' -] # Debugging command-line flag @debug = false - -# Check if source file provided is good -def check_build_src_file(rb_file) - if !rb_file - puts "Please provide a Ruby file to build" - exit - elsif !File.exist? rb_file - puts "Can't find file: #{rb_file}" - exit - end -end - - -# Assemble the Ruby 2D library in one `.rb` file -def make_lib - FileUtils.mkdir_p 'build' - - lib_dir = "#{@gem_dir}/lib/ruby2d/" - - lib = "" - @lib_files.each do |f| - lib << File.read("#{lib_dir + f}.rb") + "\n\n" - end - - lib << " -include Ruby2D -extend Ruby2D::DSL\n" - - File.write('build/lib.rb', lib) -end - - -# Remove `require 'ruby2d'` from source file -def strip_require(file) - output = '' - File.foreach(file) do |line| - output << line unless line =~ /require ('|")ruby2d('|")/ - end - return output -end - - -# Build a native version of the provided Ruby application -def build_native(rb_file) - check_build_src_file(rb_file) - - # Check if MRuby exists; if not, quit - if `which mruby`.empty? - puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n" - exit - end - - # Add debugging information to produce backtrace - if @debug then debug_flag = '-g' end - - # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode - make_lib - `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb` - - # Read the provided Ruby source file, copy to build dir and compile to bytecode - File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) } - `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb` - - # Combine contents of C source files and bytecode into one file - open('build/app.c', 'w') do |f| - f << "#define MRUBY 1" << "\n\n" - f << File.read("build/lib.c") << "\n\n" - f << File.read("build/src.c") << "\n\n" - f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c") - end - - # Compile to a native executable - `cc build/app.c -lmruby \`simple2d --libs\` -o build/app` - - # Clean up - clean_up unless @debug - - # Success! - puts "Native app created at `build/app`" -end - - -# Build a web-based version of the provided Ruby application -def build_web(rb_file) - puts "Warning: ".warn + "This feature is currently disabled while it's being upgraded." -end - - -# Build an iOS or tvOS app -def build_apple(rb_file, device) - check_build_src_file(rb_file) - - # Check for Simple 2D framework, - unless File.exist?('/usr/local/Frameworks/Simple2D/iOS/Simple2D.framework') && File.exist?('/usr/local/Frameworks/Simple2D/tvOS/Simple2D.framework') - puts "#{'Error:'.error} Simple 2D iOS and tvOS frameworks not found. Install them and try again.\n" - exit - end - - # Check if MRuby exists; if not, quit - if `which mruby`.empty? - puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n" - exit - end - - # Add debugging information to produce backtrace - if @debug then debug_flag = '-g' end - - # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode - make_lib - `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb` - - # Read the provided Ruby source file, copy to build dir and compile to bytecode - File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) } - `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb` - - # Copy over iOS project - FileUtils.cp_r "#{@gem_dir}/assets/#{device}", "build" - - # Combine contents of C source files and bytecode into one file - File.open("build/#{device}/main.c", 'w') do |f| - f << "#define RUBY2D_IOS_TVOS 1" << "\n\n" - f << "#define MRUBY 1" << "\n\n" - f << File.read("build/lib.c") << "\n\n" - f << File.read("build/src.c") << "\n\n" - f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c") - end - - # Build the Xcode project - `simple2d build --#{device} build/#{device}/MyApp.xcodeproj` - - # Clean up - clean_up unless @debug - - # Success! - puts "App created at `build/#{device}`" -end - - -# Clean up unneeded build files -def clean_up(cmd = nil) - FileUtils.rm( - Dir.glob('build/{src,lib}.{rb,c,js}') + - Dir.glob('build/app.c') - ) - if cmd == :all - puts "cleaning up..." - FileUtils.rm_f 'build/app' - FileUtils.rm_f 'build/app.js' - FileUtils.rm_f 'build/app.html' - FileUtils.rm_rf 'build/ios' - FileUtils.rm_rf 'build/tvos' - end -end - - -# Launch a native app -def launch_native - if !File.exist? 'build/app' - puts "No native app built!" - exit - end - `( cd build && ./app )` -end - - -# Launch a web app -def launch_web - if !File.exist? 'build/app.html' - puts "No web app built!" - exit - end - open_cmd = 'open' - case RUBY_PLATFORM - when /linux/ - open_cmd = "xdg-#{open_cmd}" - when /mingw/ - open_cmd = "start" - end - system "#{open_cmd} build/app.html" -end - - -# Launch an iOS or tvOS app in a simulator -def launch_apple(device) - case device - when 'ios' - if !File.exist? 'build/ios/build/Release-iphonesimulator/MyApp.app' - puts "No iOS app built!" - exit - end - puts `simple2d simulator --open "iPhone XR" && - simple2d simulator --install "build/ios/build/Release-iphonesimulator/MyApp.app" && - simple2d simulator --launch "Ruby2D.MyApp"` - when 'tvos' - if !File.exist? 'build/tvos/build/Release-appletvsimulator/MyApp.app' - puts "No tvOS app built!" - exit - end - puts `simple2d simulator --open "Apple TV 4K" && - simple2d simulator --install "build/tvos/build/Release-appletvsimulator/MyApp.app" && - simple2d simulator --launch "Ruby2D.MyApp"` - end -end - - -# Check Command-line Arguments ################################################# +# Usage ######################################################################## usage = "Ruby 2D: Make cross-platform 2D applications in Ruby".bold + "\n Usage: ruby2d <command> <options> [-v|--version] Summary of commands and options: + console Run script in an interactive console build Build a Ruby source file launch Launch a built Ruby 2D application simulator Interact with iOS and tvOS simulators @@ -297,8 +69,13 @@ Choose an option with the #{"simulator".bold} command: --log <app> Stream log for the app only, given the app name --log-errors Stream log containing only error messages\n\n" +# Check Command-line Arguments ################################################# + case ARGV[0] +when 'console' + require 'ruby2d/cli/console' when 'build' + require 'ruby2d/cli/build' if ARGV.delete '--debug' then @debug = true end case ARGV[1] when '--native' @@ -320,6 +97,7 @@ when 'build' puts usage_build end when 'launch' + require 'ruby2d/cli/launch' case ARGV[1] when '--native' launch_native diff --git a/lib/ruby2d/cli/build.rb b/lib/ruby2d/cli/build.rb new file mode 100644 index 0000000..92e68f7 --- /dev/null +++ b/lib/ruby2d/cli/build.rb @@ -0,0 +1,181 @@ +# Build a Ruby 2D app natively and for the web + +require 'fileutils' + +# The installed gem directory +@gem_dir = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}" + +# The Ruby 2D library files +@lib_files = [ + 'renderable', + 'exceptions', + 'color', + 'window', + 'dsl', + 'quad', + 'line', + 'circle', + 'rectangle', + 'square', + 'triangle', + 'image', + 'sprite', + 'font', + 'text', + 'sound', + 'music' +] + + +# Check if source file provided is good +def check_build_src_file(rb_file) + if !rb_file + puts "Please provide a Ruby file to build" + exit + elsif !File.exist? rb_file + puts "Can't find file: #{rb_file}" + exit + end +end + + +# Assemble the Ruby 2D library in one `.rb` file +def make_lib + FileUtils.mkdir_p 'build' + + lib_dir = "#{@gem_dir}/lib/ruby2d/" + + lib = "" + @lib_files.each do |f| + lib << File.read("#{lib_dir + f}.rb") + "\n\n" + end + + lib << " +include Ruby2D +extend Ruby2D::DSL\n" + + File.write('build/lib.rb', lib) +end + + +# Remove `require 'ruby2d'` from source file +def strip_require(file) + output = '' + File.foreach(file) do |line| + output << line unless line =~ /require ('|")ruby2d('|")/ + end + return output +end + + +# Build a native version of the provided Ruby application +def build_native(rb_file) + check_build_src_file(rb_file) + + # Check if MRuby exists; if not, quit + if `which mruby`.empty? + puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n" + exit + end + + # Add debugging information to produce backtrace + if @debug then debug_flag = '-g' end + + # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode + make_lib + `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb` + + # Read the provided Ruby source file, copy to build dir and compile to bytecode + File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) } + `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb` + + # Combine contents of C source files and bytecode into one file + open('build/app.c', 'w') do |f| + f << "#define MRUBY 1" << "\n\n" + f << File.read("build/lib.c") << "\n\n" + f << File.read("build/src.c") << "\n\n" + f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c") + end + + # Compile to a native executable + `cc build/app.c -lmruby \`simple2d --libs\` -o build/app` + + # Clean up + clean_up unless @debug + + # Success! + puts "Native app created at `build/app`" +end + + +# Build a web-based version of the provided Ruby application +def build_web(rb_file) + puts "Warning: ".warn + "This feature is currently disabled while it's being upgraded." +end + + +# Build an iOS or tvOS app +def build_apple(rb_file, device) + check_build_src_file(rb_file) + + # Check for Simple 2D framework, + unless File.exist?('/usr/local/Frameworks/Simple2D/iOS/Simple2D.framework') && File.exist?('/usr/local/Frameworks/Simple2D/tvOS/Simple2D.framework') + puts "#{'Error:'.error} Simple 2D iOS and tvOS frameworks not found. Install them and try again.\n" + exit + end + + # Check if MRuby exists; if not, quit + if `which mruby`.empty? + puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n" + exit + end + + # Add debugging information to produce backtrace + if @debug then debug_flag = '-g' end + + # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode + make_lib + `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb` + + # Read the provided Ruby source file, copy to build dir and compile to bytecode + File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) } + `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb` + + # Copy over iOS project + FileUtils.cp_r "#{@gem_dir}/assets/#{device}", "build" + + # Combine contents of C source files and bytecode into one file + File.open("build/#{device}/main.c", 'w') do |f| + f << "#define RUBY2D_IOS_TVOS 1" << "\n\n" + f << "#define MRUBY 1" << "\n\n" + f << File.read("build/lib.c") << "\n\n" + f << File.read("build/src.c") << "\n\n" + f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c") + end + + # Build the Xcode project + `simple2d build --#{device} build/#{device}/MyApp.xcodeproj` + + # Clean up + clean_up unless @debug + + # Success! + puts "App created at `build/#{device}`" +end + + +# Clean up unneeded build files +def clean_up(cmd = nil) + FileUtils.rm( + Dir.glob('build/{src,lib}.{rb,c,js}') + + Dir.glob('build/app.c') + ) + if cmd == :all + puts "cleaning up..." + FileUtils.rm_f 'build/app' + FileUtils.rm_f 'build/app.js' + FileUtils.rm_f 'build/app.html' + FileUtils.rm_rf 'build/ios' + FileUtils.rm_rf 'build/tvos' + end +end diff --git a/lib/ruby2d/cli/console.rb b/lib/ruby2d/cli/console.rb new file mode 100644 index 0000000..b30570d --- /dev/null +++ b/lib/ruby2d/cli/console.rb @@ -0,0 +1,49 @@ +rb_file = ARGV[1] + +# Check if source file provided is good +if !rb_file + puts "Provide a Ruby file to run" + exit 1 +elsif !File.exist? rb_file + puts "Can't find file: #{rb_file}" + exit 1 +end + +# Add libraries +require 'open3' +require 'readline' +require 'io/wait' + +line = 1 # the current line number, to be incremented + +# Open a new process for the Ruby file +stdin, stdout, stderr, wait_thr = Open3.popen3("ruby -r 'ruby2d/cli/enable_console' #{rb_file}") + +loop do + + # Read the next command + cmd = Readline.readline("ruby2d:#{line}> ", true) + + # Quit if command is 'exit' + if cmd == 'exit' + Process.kill 'INT', wait_thr.pid + wait_thr.value + exit + end + + # Skip if command is an empty string + unless cmd.empty? + + # Send command to the Ruby file + stdin.puts cmd + + # Read and print output from the Ruby file + puts stdout.gets + while stdout.ready? do + puts stdout.gets + end + end + + # Advance to next line + line += 1 +end diff --git a/lib/ruby2d/cli/enable_console.rb b/lib/ruby2d/cli/enable_console.rb new file mode 100644 index 0000000..8b2d3cd --- /dev/null +++ b/lib/ruby2d/cli/enable_console.rb @@ -0,0 +1,5 @@ +# Enable the interactive console + +require 'io/wait' + +$ruby2d_console_mode = true diff --git a/lib/ruby2d/cli/launch.rb b/lib/ruby2d/cli/launch.rb new file mode 100644 index 0000000..ff09873 --- /dev/null +++ b/lib/ruby2d/cli/launch.rb @@ -0,0 +1,50 @@ +# Launch a built Ruby 2D app + +# Launch a native app +def launch_native + if !File.exist? 'build/app' + puts "No native app built!" + exit + end + `( cd build && ./app )` +end + + +# Launch a web app +def launch_web + if !File.exist? 'build/app.html' + puts "No web app built!" + exit + end + open_cmd = 'open' + case RUBY_PLATFORM + when /linux/ + open_cmd = "xdg-#{open_cmd}" + when /mingw/ + open_cmd = "start" + end + system "#{open_cmd} build/app.html" +end + + +# Launch an iOS or tvOS app in a simulator +def launch_apple(device) + case device + when 'ios' + if !File.exist? 'build/ios/build/Release-iphonesimulator/MyApp.app' + puts "No iOS app built!" + exit + end + puts `simple2d simulator --open "iPhone XR" && + simple2d simulator --install "build/ios/build/Release-iphonesimulator/MyApp.app" && + simple2d simulator --launch "Ruby2D.MyApp"` + when 'tvos' + if !File.exist? 'build/tvos/build/Release-appletvsimulator/MyApp.app' + puts "No tvOS app built!" + exit + end + puts `simple2d simulator --open "Apple TV 4K" && + simple2d simulator --install "build/tvos/build/Release-appletvsimulator/MyApp.app" && + simple2d simulator --launch "Ruby2D.MyApp"` + end +end diff --git a/lib/ruby2d/window.rb b/lib/ruby2d/window.rb index e08d13c..7db80a9 100644 --- a/lib/ruby2d/window.rb +++ b/lib/ruby2d/window.rb @@ -85,6 +85,9 @@ module Ruby2D # Whether diagnostic messages should be printed @diagnostics = false + + # Console mode, enabled at command line + @console = $ruby2d_console_mode || false end # Class methods for convenient access to properties @@ -354,6 +357,25 @@ module Ruby2D # Update callback method, called by the native and web extentions def update_callback @update_proc.call + + # Accept and eval commands if in console mode + if @console + if STDIN.ready? + cmd = STDIN.gets + begin + res = eval(cmd, TOPLEVEL_BINDING) + STDOUT.puts "=> #{res.inspect}" + STDOUT.flush + rescue SyntaxError => se + STDOUT.puts se + STDOUT.flush + rescue Exception => e + STDOUT.puts e + STDOUT.flush + end + end + end + end # Show the window diff --git a/test/console.rb b/test/console.rb new file mode 100644 index 0000000..c7d29c4 --- /dev/null +++ b/test/console.rb @@ -0,0 +1,25 @@ +require 'ruby2d' + +s1 = Square.new(x: 0, y: 0, size: 100, color: 'white') +s2 = Square.new(x: 100, y: 100, size: 50, color: 'green') +c = 0.0 +switch = true + +update do + + if switch + c += 0.01 + if c > 1.0 + switch = false + end + else + c -= 0.01 + if c < 0.0 + switch = true + end + end + + s1.color = [1, 1, 1, c] +end + +show |
