summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--Rakefile32
m---------assets0
-rwxr-xr-xbin/ruby2d283
-rw-r--r--ext/ruby2d/ruby2d.c25
-rw-r--r--lib/ruby2d/window.rb8
m---------test/media0
-rw-r--r--test/triangle-ios-tvos.rb20
8 files changed, 301 insertions, 69 deletions
diff --git a/README.md b/README.md
index 4eafddc..51e2473 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ git submodule init
git submodule update --remote
```
-Update these submodules at any time using `git submodule update --remote`
+Update these submodules at any time using `git submodule update --remote` or the `rake update` task.
Next, install dependencies:
- With [Bundler](http://bundler.io), run `bundle install` to get the required development gems.
diff --git a/Rakefile b/Rakefile
index 6125d4e..3c0d1cc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -32,17 +32,19 @@ end
def run_mri_test(file)
print_task "Running MRI test: #{file}.rb"
- system "( cd test/ && ruby #{file}.rb )"
+ run_cmd "( cd test/ && ruby #{file}.rb )"
end
def run_native_test(file)
print_task "Running native test: #{file}.rb"
+ run_cmd "ruby2d build --clean"
run_cmd "ruby2d build --native test/#{file}.rb --debug"
- system "( cd test/ && ../build/app )"
+ run_cmd "( cd test/ && ../build/app )"
end
def run_web_test(file)
print_task "Running web test: #{file}.rb"
+ run_cmd "ruby2d build --clean"
run_cmd "ruby2d build --web test/#{file}.rb --debug"
open_cmd = 'open'
case RUBY_PLATFORM
@@ -51,7 +53,13 @@ def run_web_test(file)
when /mingw/
open_cmd = "start"
end
- system "#{open_cmd} build/app.html"
+ run_cmd "#{open_cmd} build/app.html"
+end
+
+def run_apple_test(device)
+ run_cmd "ruby2d build --clean"
+ run_cmd "ruby2d build --#{device} test/triangle-ios-tvos.rb --debug"
+ run_cmd "ruby2d launch --#{device}"
end
# Tasks
@@ -76,6 +84,11 @@ task :install do
run_cmd "gem install ruby2d-#{Ruby2D::VERSION}.gem --local --verbose"
end
+desc "Update submodules"
+task :update do
+ run_cmd "git submodule update --remote"
+end
+
desc "Run the RSpec tests"
RSpec::Core::RakeTask.new do |t|
print_task "Running RSpec"
@@ -100,6 +113,19 @@ namespace :test do
get_args
run_web_test ARGV[1]
end
+
+ desc "Run iOS test"
+ task :ios do
+ print_task "Running iOS test"
+ run_apple_test('ios')
+ end
+
+ desc "Run tvOS test"
+ task :tvos do
+ print_task "Running tvOS test"
+ run_apple_test('tvos')
+ end
+
end
desc "Uninstall, build, install, and test"
diff --git a/assets b/assets
-Subproject dc5064b4a104e4cd3b3518ac18430291e6ad51a
+Subproject a063585233cde9839b4f8bab3bf734088ba356b
diff --git a/bin/ruby2d b/bin/ruby2d
index 03f455b..5c11a67 100755
--- a/bin/ruby2d
+++ b/bin/ruby2d
@@ -6,7 +6,7 @@ require 'fileutils'
class String
def colorize(c); "\e[#{c}m#{self}\e[0m" end
def bold; colorize('1') end
- def error; colorize('4;31') end
+ def error; colorize('1;31') end
end
# The installed gem directory
@@ -32,11 +32,14 @@ end
'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."
+ puts "Please provide a Ruby file to build"
exit
elsif !File.exists? rb_file
puts "Can't find file: #{rb_file}"
@@ -76,6 +79,7 @@ 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?
@@ -88,11 +92,7 @@ def build_native(rb_file)
`mrbc -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') do |file|
- file << strip_require(rb_file)
- end
-
+ File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) }
`mrbc -Bruby2d_app -obuild/src.c build/src.rb`
# Combine contents of C source files and bytecode into one file
@@ -103,9 +103,12 @@ def build_native(rb_file)
f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
end
- # Compile to native executable
+ # 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
@@ -113,19 +116,15 @@ end
# Build a web-based version of the provided Ruby application
def build_web(rb_file)
+ check_build_src_file(rb_file)
# Assemble the Ruby 2D library in one `.rb` file and compile to JS
make_lib
`opal --compile --no-opal build/lib.rb > build/lib.js`
# Read the provided Ruby source file, copy to build dir, and compile to JS
-
- File.open('build/src.rb', 'w') do |file|
- file << strip_require(rb_file)
- end
-
+ File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) }
`opal --compile --no-opal build/src.rb > build/src.js`
-
FileUtils.cp "#{@gem_dir}/ext/ruby2d/ruby2d-opal.rb", "build/"
`opal --compile --no-opal build/ruby2d-opal.rb > build/ruby2d-opal.js`
@@ -141,56 +140,127 @@ def build_web(rb_file)
# Copy over HTML template
FileUtils.cp "#{@gem_dir}/assets/template.html", "build/app.html"
+ # Clean up
+ clean_up unless @debug
+
# Success!
puts "Web app created at `build/app.js`",
" Run by opening `build/app.html`"
end
-# Build an application package for the current platform
-def build_package
- require 'fileutils'
-
- icon_path = "#{@gem_dir}/assets/app.icns"
-
- FileUtils.mkpath "build/App.app/Contents/MacOS"
- FileUtils.mkpath "build/App.app/Contents/Resources"
- FileUtils.cp icon_path, "build/App.app/Contents/Resources"
-
- info_plist = %(
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleExecutable</key>
- <string>app</string>
- <key>CFBundleIconFile</key>
- <string>app.icns</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>1.0</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1.0</string>
-</dict>
-</plist>
-)
-
- File.open("build/App.app/Contents/Info.plist", 'w') { |f| f.write(info_plist) }
- FileUtils.cp "build/app", "build/App.app/Contents/MacOS/"
- puts "App written to `build/App.app`."
+# 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.exists?('/usr/local/Frameworks/Simple2D/iOS/Simple2D.framework') && File.exists?('/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
+
+ # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
+ make_lib
+ `mrbc -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 -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
+def clean_up(cmd = nil)
FileUtils.rm(
Dir.glob('build/{src,lib}.{rb,c,js}') +
Dir.glob('build/ruby2d-opal.{rb,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.exists? 'build/app'
+ puts "No native app built!"
+ exit
+ end
+ `( cd build && ./app )`
+end
+
+
+# Launch a web app
+def launch_web
+ if !File.exists? '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.exists? 'build/ios/build/Release-iphonesimulator/MyApp.app'
+ puts "No iOS app built!"
+ exit
+ end
+ puts `simple2d simulator --open "iPhone 8" &&
+ simple2d simulator --install "build/ios/build/Release-iphonesimulator/MyApp.app" &&
+ simple2d simulator --launch "Ruby2D.MyApp"`
+ when 'tvos'
+ if !File.exists? 'build/tvos/build/Release-appletvsimulator/MyApp.app'
+ puts "No tvOS app built!"
+ exit
+ end
+ puts `simple2d simulator --open "Apple TV" &&
+ simple2d simulator --install "build/tvos/build/Release-appletvsimulator/MyApp.app" &&
+ simple2d simulator --launch "Ruby2D.MyApp"`
+ end
end
@@ -201,31 +271,116 @@ Usage: ruby2d <command> <options>
[-v|--version]
Summary of commands and options:
- build Build the application both natively and for the web
- --native Build only native
- --web Build only web
- --debug Build native and web, keeping all intermediate files
- package Create application package for distribution (experimental)
+ build Build a Ruby source file
+ launch Launch a built Ruby 2D application
+ simulator Interact with iOS and tvOS simulators
-v|--version Prints the installed version\n\n"
+usage_build = "
+Use the #{"build".bold} command to compile or build Ruby 2D apps.
+
+To compile and create a native executable, use:
+ build --native <ruby_file>
+
+To build for the web, creating a JavaScript and HTML package, use:
+ build --web <ruby_file>
+
+To build an iOS or tvOS app, use the following:
+ build --ios <ruby_file>
+ build --tvos <ruby_file>
+
+To build for every platform supported by the current system, use:
+ build --all <ruby_file>
+
+To clean up the build directory, use:
+ build --clean
+
+Add the #{"--debug".bold} option to print debugging info
+and keep all intermediate files generated.\n\n"
+
+usage_launch = "
+Use the #{"launch".bold} command to run a Ruby 2D app that has been built.
+Choose one of the following options to select the kind of app to run:
+
+ --native
+ --web
+ --ios
+ --tvos\n\n"
+
+usage_simulator = "
+Choose an option with the #{"simulator".bold} command:
+
+ --list List available devices
+ --booted Show currently booted devices
+
+ --open <device_name> Open a simulator device with a given device name
+
+ --install <app_file> Install an app on the booted simulator given the path
+ to the app e.g. \"Release-iphonesimulator/MyApp.app\"
+
+ --launch <bundle_id> Launch an app given the app bundle's identifier,
+ e.g. \"Ruby2D.MyApp\"
+
+ --log Stream log of the booted simulator
+ --log <app> Stream log for the app only, given the app name
+ --log-errors Stream log containing only error messages\n\n"
+
+# puts ARGV.inspect
+
case ARGV[0]
when 'build'
- puts "Building..."
+ if ARGV.delete '--debug' then @debug = true end
case ARGV[1]
when '--native'
build_native(ARGV[2])
when '--web'
build_web(ARGV[2])
+ when '--ios'
+ build_apple(ARGV[2], 'ios')
+ when '--tvos'
+ build_apple(ARGV[2], 'tvos')
+ when '--all'
+ build_native(ARGV[2])
+ build_web(ARGV[2])
+ build_apple(ARGV[2], 'ios')
+ build_apple(ARGV[2], 'tvos')
+ when '--clean'
+ clean_up(:all)
+ else
+ puts usage_build
+ end
+when 'launch'
+ case ARGV[1]
+ when '--native'
+ launch_native
+ when '--web'
+ launch_web
+ when '--ios'
+ launch_apple('ios')
+ when '--tvos'
+ launch_apple('tvos')
else
- if ARGV[2]; puts usage; exit end
- check_build_src_file(ARGV[1])
- build_native(ARGV[1])
- build_web(ARGV[1])
- end
- unless ARGV.include? '--debug'; clean_up end
-when 'package'
- puts "Running package..."
- build_package
+ puts usage_launch
+ end
+when 'simulator'
+ case ARGV[1]
+ when '--list'
+ puts `simple2d simulator --list`
+ when '--booted'
+ puts `simple2d simulator --booted`
+ when '--open'
+ puts `simple2d simulator --open "#{ARGV[2]}"`
+ when '--install'
+ puts `simple2d simulator --install "#{ARGV[2]}"`
+ when '--launch'
+ puts `simple2d simulator --launch "#{ARGV[2]}"`
+ when '--log'
+ puts `simple2d simulator --log`
+ when '--log-errors'
+ puts `simple2d simulator --log-errors`
+ else
+ puts usage_simulator
+ end
when '-v', '--version'
puts Ruby2D::VERSION
else
diff --git a/ext/ruby2d/ruby2d.c b/ext/ruby2d/ruby2d.c
index d5c2191..6cbe219 100644
--- a/ext/ruby2d/ruby2d.c
+++ b/ext/ruby2d/ruby2d.c
@@ -1,7 +1,11 @@
// ruby2d.c – Native C extension for Ruby and MRuby
// Simple 2D includes
-#include <simple2d.h>
+#if RUBY2D_IOS_TVOS
+ #include <Simple2D/simple2d.h>
+#else
+ #include <simple2d.h>
+#endif
// Ruby includes
#if MRUBY
@@ -801,6 +805,22 @@ static void render() {
/*
+ * Ruby2D::Window#ext_get_display_dimensions
+ */
+#if MRUBY
+static R_VAL ruby2d_window_ext_get_display_dimensions(mrb_state* mrb, R_VAL self) {
+#else
+static R_VAL ruby2d_window_ext_get_display_dimensions(R_VAL self) {
+#endif
+ int w; int h;
+ S2D_GetDisplayDimensions(&w, &h);
+ r_iv_set(self, "@display_width" , INT2NUM(w));
+ r_iv_set(self, "@display_height", INT2NUM(h));
+ return R_NIL;
+}
+
+
+/*
* Ruby2D::Window#ext_show
*/
#if MRUBY
@@ -977,6 +997,9 @@ void Init_ruby2d() {
// Ruby2D::Window
R_CLASS ruby2d_window_class = r_define_class(ruby2d_module, "Window");
+ // Ruby2D::Window#ext_get_display_dimensions
+ r_define_method(ruby2d_window_class, "ext_get_display_dimensions", ruby2d_window_ext_get_display_dimensions, r_args_none);
+
// Ruby2D::Window#ext_show
r_define_method(ruby2d_window_class, "ext_show", ruby2d_window_ext_show, r_args_none);
diff --git a/lib/ruby2d/window.rb b/lib/ruby2d/window.rb
index d3e8143..0a5a995 100644
--- a/lib/ruby2d/window.rb
+++ b/lib/ruby2d/window.rb
@@ -17,6 +17,7 @@ module Ruby2D
@width = args[:width] || 640
@height = args[:height] || 480
@viewport_width, @viewport_height = nil, nil
+ @display_width, @display_height = nil, nil
@resizable = false
@borderless = false
@fullscreen = false
@@ -60,6 +61,13 @@ module Ruby2D
when :height; @height
when :viewport_width; @viewport_width
when :viewport_height; @viewport_height
+ when :display_width, :display_height
+ ext_get_display_dimensions
+ if sym == :display_width
+ @display_width
+ else
+ @display_height
+ end
when :resizable; @resizable
when :borderless; @borderless
when :fullscreen; @fullscreen
diff --git a/test/media b/test/media
-Subproject fd57d1c22c11b1cc84b160236718b7e26c438a3
+Subproject 0d54e768f8da2217203649cb270f4d0add82328
diff --git a/test/triangle-ios-tvos.rb b/test/triangle-ios-tvos.rb
new file mode 100644
index 0000000..5189173
--- /dev/null
+++ b/test/triangle-ios-tvos.rb
@@ -0,0 +1,20 @@
+require 'ruby2d'
+
+set title: "Hello Triangle",
+ width: get(:display_width), height: get(:display_height),
+ borderless: true
+
+Rectangle.new(
+ x: 0, y: 0,
+ width: get(:width), height: get(:height),
+ color: [[1, 0, 1, 1], [0, 1, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1]]
+)
+
+Triangle.new(
+ x1: get(:width) / 2, y1: get(:height) / 5,
+ x2: get(:width), y2: get(:height) / 1.5,
+ x3: 0, y3: get(:height) / 1.5,
+ color: [[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]]
+)
+
+show