ruby2d 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,36 +1,59 @@
1
1
  # Ruby2D module and native extension loader, adds DSL
2
2
 
3
- require 'ruby2d/colorize'
4
- require 'ruby2d/exceptions'
5
- require 'ruby2d/renderable'
6
- require 'ruby2d/color'
7
- require 'ruby2d/window'
8
- require 'ruby2d/dsl'
9
- require 'ruby2d/quad'
10
- require 'ruby2d/line'
11
- require 'ruby2d/circle'
12
- require 'ruby2d/rectangle'
13
- require 'ruby2d/square'
14
- require 'ruby2d/triangle'
15
- require 'ruby2d/image'
16
- require 'ruby2d/sprite'
17
- require 'ruby2d/font'
18
- require 'ruby2d/text'
19
- require 'ruby2d/sound'
20
- require 'ruby2d/music'
21
-
22
- if RUBY_PLATFORM =~ /mingw/
23
- # When using the Windows CI AppVeyor
24
- if ENV['APPVEYOR']
25
- s2d_dll_path = 'C:\msys64\usr\local\bin'
26
- # When in a standard MinGW shell
27
- else
28
- s2d_dll_path = '~/../../usr/local/bin'
3
+ unless RUBY_ENGINE == 'mruby'
4
+ require 'ruby2d/colorize'
5
+ require 'ruby2d/exceptions'
6
+ require 'ruby2d/renderable'
7
+ require 'ruby2d/color'
8
+ require 'ruby2d/window'
9
+ require 'ruby2d/dsl'
10
+ require 'ruby2d/quad'
11
+ require 'ruby2d/line'
12
+ require 'ruby2d/circle'
13
+ require 'ruby2d/rectangle'
14
+ require 'ruby2d/square'
15
+ require 'ruby2d/triangle'
16
+ require 'ruby2d/image'
17
+ require 'ruby2d/sprite'
18
+ require 'ruby2d/font'
19
+ require 'ruby2d/text'
20
+ require 'ruby2d/sound'
21
+ require 'ruby2d/music'
22
+
23
+ if RUBY_PLATFORM =~ /mingw/
24
+ # When using the Windows CI AppVeyor
25
+ if ENV['APPVEYOR']
26
+ s2d_dll_path = 'C:\msys64\usr\local\bin'
27
+ # When in a standard MinGW shell
28
+ else
29
+ s2d_dll_path = '~/../../usr/local/bin'
30
+ end
31
+ RubyInstaller::Runtime.add_dll_directory(File.expand_path(s2d_dll_path))
29
32
  end
30
- RubyInstaller::Runtime.add_dll_directory(File.expand_path(s2d_dll_path))
33
+
34
+ require 'ruby2d/ruby2d' # load native extension
31
35
  end
32
36
 
33
- require 'ruby2d/ruby2d' # load native extension
37
+
38
+ module Ruby2D
39
+
40
+ @assets = nil
41
+
42
+ class << self
43
+ def assets
44
+ unless @assets
45
+ if RUBY_ENGINE == 'mruby'
46
+ @assets = Ruby2D.ext_base_path + 'assets'
47
+ else
48
+ @assets = './assets'
49
+ end
50
+ end
51
+ @assets
52
+ end
53
+
54
+ def assets=(path); @assets = path end
55
+ end
56
+ end
34
57
 
35
58
  include Ruby2D
36
59
  extend Ruby2D::DSL
@@ -4,8 +4,7 @@ module Ruby2D
4
4
  class Circle
5
5
  include Renderable
6
6
 
7
- attr_reader :color
8
- attr_accessor :x, :y, :radius, :sectors
7
+ attr_accessor :radius, :sectors
9
8
 
10
9
  def initialize(opts = {})
11
10
  @x = opts[:x] || 25
@@ -14,13 +13,10 @@ module Ruby2D
14
13
  @radius = opts[:radius] || 25
15
14
  @sectors = opts[:sectors] || 20
16
15
  self.color = opts[:color] || 'white'
16
+ self.opacity = opts[:opacity] if opts[:opacity]
17
17
  add
18
18
  end
19
19
 
20
- def color=(c)
21
- @color = Color.from(c)
22
- end
23
-
24
20
  def contains?(x, y)
25
21
  Math.sqrt((x - @x)**2 + (y - @y)**2) <= @radius
26
22
  end
@@ -0,0 +1,226 @@
1
+ # Build a Ruby 2D app natively and for the web
2
+
3
+ require 'fileutils'
4
+
5
+ # The installed gem directory
6
+ @gem_dir = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}"
7
+
8
+ # The Ruby 2D library files
9
+ @lib_files = [
10
+ 'colorize',
11
+ 'exceptions',
12
+ 'renderable',
13
+ 'color',
14
+ 'window',
15
+ 'dsl',
16
+ 'quad',
17
+ 'line',
18
+ 'circle',
19
+ 'rectangle',
20
+ 'square',
21
+ 'triangle',
22
+ 'image',
23
+ 'sprite',
24
+ 'font',
25
+ 'text',
26
+ 'sound',
27
+ 'music',
28
+ '../ruby2d'
29
+ ]
30
+
31
+
32
+ # Check if source file provided is good
33
+ def check_build_src_file(rb_file)
34
+ if !rb_file
35
+ puts "Please provide a Ruby file to build"
36
+ exit
37
+ elsif !File.exist? rb_file
38
+ puts "Can't find file: #{rb_file}"
39
+ exit
40
+ end
41
+ end
42
+
43
+
44
+ # Assemble the Ruby 2D library in one `.rb` file
45
+ def make_lib
46
+ FileUtils.mkdir_p 'build'
47
+
48
+ lib_dir = "#{@gem_dir}/lib/ruby2d/"
49
+
50
+ lib = ''
51
+ @lib_files.each do |f|
52
+ lib << File.read("#{lib_dir + f}.rb") + "\n\n"
53
+ end
54
+
55
+ File.write('build/lib.rb', lib)
56
+ end
57
+
58
+
59
+ # Remove `require 'ruby2d'` from source file
60
+ def strip_require(file)
61
+ output = ''
62
+ File.foreach(file) do |line|
63
+ output << line unless line =~ /require ('|")ruby2d('|")/
64
+ end
65
+ return output
66
+ end
67
+
68
+
69
+ # Build a native version of the provided Ruby application
70
+ def build_native(rb_file)
71
+ check_build_src_file(rb_file)
72
+
73
+ # Check if MRuby exists; if not, quit
74
+ if `which mruby`.empty?
75
+ puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n"
76
+ exit
77
+ end
78
+
79
+ # Add debugging information to produce backtrace
80
+ if @debug then debug_flag = '-g' end
81
+
82
+ # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
83
+ make_lib
84
+ `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb`
85
+
86
+ # Read the provided Ruby source file, copy to build dir and compile to bytecode
87
+ File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) }
88
+ `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb`
89
+
90
+ # Combine contents of C source files and bytecode into one file
91
+ open('build/app.c', 'w') do |f|
92
+ f << "#define MRUBY 1" << "\n\n"
93
+ f << File.read("build/lib.c") << "\n\n"
94
+ f << File.read("build/src.c") << "\n\n"
95
+ f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
96
+ end
97
+
98
+ # Compile to a native executable
99
+ `cc build/app.c -lmruby \`simple2d --libs\` -o build/app`
100
+
101
+ # Clean up
102
+ clean_up unless @debug
103
+
104
+ # Success!
105
+ puts "Native app created at `build/app`"
106
+ end
107
+
108
+
109
+ # Build a web-based version of the provided Ruby application
110
+ def build_web(rb_file)
111
+ puts "Warning: ".warn + "This feature is currently disabled while it's being upgraded."
112
+ end
113
+
114
+
115
+ # Build an app bundle for macOS
116
+ def build_macos(rb_file)
117
+
118
+ # Build native app for macOS
119
+ build_native(rb_file)
120
+
121
+ # Property list source for the bundle
122
+ info_plist = %(
123
+ <?xml version="1.0" encoding="UTF-8"?>
124
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
125
+ <plist version="1.0">
126
+ <dict>
127
+ <key>CFBundleExecutable</key>
128
+ <string>app</string>
129
+ <key>CFBundleIconFile</key>
130
+ <string>app.icns</string>
131
+ <key>CFBundleInfoDictionaryVersion</key>
132
+ <string>6.0</string>
133
+ <key>CFBundlePackageType</key>
134
+ <string>APPL</string>
135
+ <key>CFBundleVersion</key>
136
+ <string>1</string>
137
+ <key>NSHighResolutionCapable</key>
138
+ <string>True</string>
139
+ </dict>
140
+ </plist>
141
+ )
142
+
143
+ # Create directories
144
+ FileUtils.mkpath 'build/App.app/Contents/MacOS'
145
+ FileUtils.mkpath 'build/App.app/Contents/Resources'
146
+
147
+ # Create Info.plist and copy over assets
148
+ File.open('build/App.app/Contents/Info.plist', 'w') { |f| f.write(info_plist) }
149
+ FileUtils.cp 'build/app', 'build/App.app/Contents/MacOS/'
150
+ # Consider using an icon:
151
+ # FileUtils.cp "#{@gem_dir}/assets/app.icns", 'build/App.app/Contents/Resources'
152
+
153
+ # Clean up
154
+ FileUtils.rm_f 'build/app' unless @debug
155
+
156
+ # Success!
157
+ puts 'macOS app bundle created: `build/App.app`'
158
+ end
159
+
160
+
161
+ # Build an iOS or tvOS app
162
+ def build_ios_tvos(rb_file, device)
163
+ check_build_src_file(rb_file)
164
+
165
+ # Check for Simple 2D framework,
166
+ unless File.exist?('/usr/local/Frameworks/Simple2D/iOS/Simple2D.framework') && File.exist?('/usr/local/Frameworks/Simple2D/tvOS/Simple2D.framework')
167
+ puts "#{'Error:'.error} Simple 2D iOS and tvOS frameworks not found. Install them and try again.\n"
168
+ exit
169
+ end
170
+
171
+ # Check if MRuby exists; if not, quit
172
+ if `which mruby`.empty?
173
+ puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n"
174
+ exit
175
+ end
176
+
177
+ # Add debugging information to produce backtrace
178
+ if @debug then debug_flag = '-g' end
179
+
180
+ # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
181
+ make_lib
182
+ `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb`
183
+
184
+ # Read the provided Ruby source file, copy to build dir and compile to bytecode
185
+ File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) }
186
+ `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb`
187
+
188
+ # Copy over iOS project
189
+ FileUtils.cp_r "#{@gem_dir}/assets/#{device}", "build"
190
+
191
+ # Combine contents of C source files and bytecode into one file
192
+ File.open("build/#{device}/main.c", 'w') do |f|
193
+ f << "#define RUBY2D_IOS_TVOS 1" << "\n\n"
194
+ f << "#define MRUBY 1" << "\n\n"
195
+ f << File.read("build/lib.c") << "\n\n"
196
+ f << File.read("build/src.c") << "\n\n"
197
+ f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
198
+ end
199
+
200
+ # Build the Xcode project
201
+ `simple2d build --#{device} build/#{device}/MyApp.xcodeproj`
202
+
203
+ # Clean up
204
+ clean_up unless @debug
205
+
206
+ # Success!
207
+ puts "App created: `build/#{device}`"
208
+ end
209
+
210
+
211
+ # Clean up unneeded build files
212
+ def clean_up(cmd = nil)
213
+ FileUtils.rm(
214
+ Dir.glob('build/{src,lib}.{rb,c,js}') +
215
+ Dir.glob('build/app.c')
216
+ )
217
+ if cmd == :all
218
+ puts "cleaning up..."
219
+ FileUtils.rm_f 'build/app'
220
+ FileUtils.rm_f 'build/app.js'
221
+ FileUtils.rm_f 'build/app.html'
222
+ FileUtils.rm_rf 'build/App.app'
223
+ FileUtils.rm_rf 'build/ios'
224
+ FileUtils.rm_rf 'build/tvos'
225
+ end
226
+ end
@@ -0,0 +1,49 @@
1
+ rb_file = ARGV[1]
2
+
3
+ # Check if source file provided is good
4
+ if !rb_file
5
+ puts "Provide a Ruby file to run"
6
+ exit 1
7
+ elsif !File.exist? rb_file
8
+ puts "Can't find file: #{rb_file}"
9
+ exit 1
10
+ end
11
+
12
+ # Add libraries
13
+ require 'open3'
14
+ require 'readline'
15
+ require 'io/wait'
16
+
17
+ line = 1 # the current line number, to be incremented
18
+
19
+ # Open a new process for the Ruby file
20
+ stdin, stdout, stderr, wait_thr = Open3.popen3("ruby -r 'ruby2d/cli/enable_console' #{rb_file}")
21
+
22
+ loop do
23
+
24
+ # Read the next command
25
+ cmd = Readline.readline("ruby2d:#{line}> ", true)
26
+
27
+ # Quit if command is 'exit'
28
+ if cmd == 'exit'
29
+ Process.kill 'INT', wait_thr.pid
30
+ wait_thr.value
31
+ exit
32
+ end
33
+
34
+ # Skip if command is an empty string
35
+ unless cmd.empty?
36
+
37
+ # Send command to the Ruby file
38
+ stdin.puts cmd
39
+
40
+ # Read and print output from the Ruby file
41
+ puts stdout.gets
42
+ while stdout.ready? do
43
+ puts stdout.gets
44
+ end
45
+ end
46
+
47
+ # Advance to next line
48
+ line += 1
49
+ end
@@ -0,0 +1,5 @@
1
+ # Enable the interactive console
2
+
3
+ require 'io/wait'
4
+
5
+ $ruby2d_console_mode = true
@@ -0,0 +1,50 @@
1
+ # Launch a built Ruby 2D app
2
+
3
+ # Launch a native app
4
+ def launch_native
5
+ if !File.exist? 'build/app'
6
+ puts "No native app built!"
7
+ exit
8
+ end
9
+ `( cd build && ./app )`
10
+ end
11
+
12
+
13
+ # Launch a web app
14
+ def launch_web
15
+ if !File.exist? 'build/app.html'
16
+ puts "No web app built!"
17
+ exit
18
+ end
19
+ open_cmd = 'open'
20
+ case RUBY_PLATFORM
21
+ when /linux/
22
+ open_cmd = "xdg-#{open_cmd}"
23
+ when /mingw/
24
+ open_cmd = "start"
25
+ end
26
+ system "#{open_cmd} build/app.html"
27
+ end
28
+
29
+
30
+ # Launch an iOS or tvOS app in a simulator
31
+ def launch_apple(device)
32
+ case device
33
+ when 'ios'
34
+ if !File.exist? 'build/ios/build/Release-iphonesimulator/MyApp.app'
35
+ puts "No iOS app built!"
36
+ exit
37
+ end
38
+ puts `simple2d simulator --open "iPhone XR" &&
39
+ simple2d simulator --install "build/ios/build/Release-iphonesimulator/MyApp.app" &&
40
+ simple2d simulator --launch "Ruby2D.MyApp"`
41
+ when 'tvos'
42
+ if !File.exist? 'build/tvos/build/Release-appletvsimulator/MyApp.app'
43
+ puts "No tvOS app built!"
44
+ exit
45
+ end
46
+ puts `simple2d simulator --open "Apple TV 4K" &&
47
+ simple2d simulator --install "build/tvos/build/Release-appletvsimulator/MyApp.app" &&
48
+ simple2d simulator --launch "Ruby2D.MyApp"`
49
+ end
50
+ end
@@ -66,10 +66,23 @@ module Ruby2D
66
66
  end
67
67
  when Array
68
68
  @r, @g, @b, @a = [c[0], c[1], c[2], c[3]]
69
+ when Color
70
+ @r, @g, @b, @a = [c.r, c.g, c.b, c.a]
69
71
  end
70
72
  end
71
73
  end
72
74
 
75
+ # Return a color set if an array of valid colors
76
+ def self.set(colors)
77
+ # If a valid array of colors, return a `Color::Set` with those colors
78
+ if colors.is_a?(Array) && colors.all? { |el| Color.is_valid? el }
79
+ Color::Set.new(colors)
80
+ # Otherwise, return single color
81
+ else
82
+ Color.new(colors)
83
+ end
84
+ end
85
+
73
86
  # Check if string is a proper hex value
74
87
  def self.is_hex?(s)
75
88
  # MRuby doesn't support regex, otherwise we'd do:
@@ -79,6 +92,7 @@ module Ruby2D
79
92
 
80
93
  # Check if the color is valid
81
94
  def self.is_valid?(c)
95
+ c.is_a?(Color) || # color object
82
96
  @@colors.key?(c) || # keyword
83
97
  self.is_hex?(c) || # hexadecimal value
84
98
 
@@ -87,17 +101,6 @@ module Ruby2D
87
101
  c.all? { |el| el.is_a?(Numeric) }
88
102
  end
89
103
 
90
- # Create a color from whatever is provided
91
- def self.from(input)
92
- # If a valid array of colors, return a `Color::Set` with those colors
93
- if input.is_a? Array and input.all? { |el| Color.is_valid? el }
94
- Color::Set.new(input)
95
- # Otherwise, return single color
96
- else
97
- Color.new(input)
98
- end
99
- end
100
-
101
104
  # Convenience methods to alias `opacity` to `@a`
102
105
  def opacity; @a end
103
106
  def opacity=(opacity); @a = opacity end
@@ -105,7 +108,6 @@ module Ruby2D
105
108
  private
106
109
 
107
110
  # Convert from Fixnum (0..255) to Float (0.0..1.0)
108
- # TODO: Only `Number` is supported in JS
109
111
  def to_f(a)
110
112
  b = []
111
113
  a.each do |n|