sdl2_ffi 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +6 -0
  4. data/Guardfile +47 -25
  5. data/Rakefile +6 -0
  6. data/bin/approvals +16 -0
  7. data/bin/autospec +16 -0
  8. data/bin/htmldiff +16 -0
  9. data/bin/ldiff +16 -0
  10. data/bin/nokogiri +16 -0
  11. data/bin/rspec +16 -0
  12. data/lib/enumerable_constants.rb +23 -8
  13. data/lib/sdl2.rb +116 -39
  14. data/lib/sdl2/color.rb +19 -7
  15. data/lib/sdl2/events.rb +184 -85
  16. data/lib/sdl2/gamecontroller.rb +1 -1
  17. data/lib/sdl2/gem_version.rb +1 -1
  18. data/lib/sdl2/joystick.rb +1 -1
  19. data/lib/sdl2/keyboard.rb +3 -0
  20. data/lib/sdl2/mouse.rb +5 -5
  21. data/lib/sdl2/pixel_format.rb +11 -3
  22. data/lib/sdl2/pixels.rb +40 -40
  23. data/lib/sdl2/point.rb +17 -1
  24. data/lib/sdl2/power.rb +12 -3
  25. data/lib/sdl2/rect.rb +19 -0
  26. data/lib/sdl2/render.rb +3 -3
  27. data/lib/sdl2/scancode.rb +7 -0
  28. data/lib/sdl2/stdinc.rb +2 -0
  29. data/lib/sdl2/surface.rb +64 -12
  30. data/lib/sdl2/ttf.rb +52 -66
  31. data/lib/sdl2/ttf/font.rb +115 -0
  32. data/lib/sdl2/video.rb +23 -23
  33. data/lib/sdl2/window.rb +15 -15
  34. data/sdl2_ffi.gemspec +5 -2
  35. data/spec/fixtures/approvals/lazyfoonet_lesson_01_hello_world/draws_hello_to_the_window_surface.approved.png +0 -0
  36. data/spec/fixtures/approvals/lazyfoonet_lesson_01_hello_world/loaded_and_optimizes_hello_bitmap.approved.png +0 -0
  37. data/spec/fixtures/approvals/lazyfoonet_lesson_02_optimized_images/draws_the_message_and_background.approved.png +0 -0
  38. data/spec/fixtures/approvals/lazyfoonet_lesson_03_extension_libraries/should_blit_a_png_to_screen.approved.png +0 -0
  39. data/spec/fixtures/approvals/lazyfoonet_lesson_04_event_driven_programming/draws_something_to_the_screen.approved.png +0 -0
  40. data/spec/fixtures/approvals/lazyfoonet_lesson_05_color_keying/draws_the_sprite_using_a_color_key.approved.png +0 -0
  41. data/spec/fixtures/approvals/lazyfoonet_lesson_06_clip_blitting_and_sprite_sheets/draws_the_clipped_sprites_to_the_screen.approved.png +0 -0
  42. data/spec/fixtures/approvals/lazyfoonet_lesson_07_true_type_fonts/draws_the_message_to_the_screen.approved.png +0 -0
  43. data/spec/fixtures/approvals/lazyfoonet_lesson_07_true_type_fonts/writes_a_message_to_a_surface.approved.png +0 -0
  44. data/spec/fixtures/approvals/lazyfoonet_lesson_08_key_presses/rendered_the_down_message.approved.png +0 -0
  45. data/spec/fixtures/approvals/lazyfoonet_lesson_08_key_presses/rendered_the_left_message.approved.png +0 -0
  46. data/spec/fixtures/approvals/lazyfoonet_lesson_08_key_presses/rendered_the_right_message.approved.png +0 -0
  47. data/spec/fixtures/approvals/lazyfoonet_lesson_08_key_presses/rendered_the_up_message.approved.png +0 -0
  48. data/spec/fixtures/approvals/sdl2_color/looks_blue_when_it_should.approved.png +0 -0
  49. data/spec/fixtures/approvals/sdl2_color/looks_green_when_it_should.approved.png +0 -0
  50. data/spec/fixtures/approvals/sdl2_color/looks_red_when_it_should.approved.png +0 -0
  51. data/spec/fixtures/approvals/sdl2_color/should_cast_arrays_properly.approved.png +0 -0
  52. data/spec/fixtures/approvals/sdl2_color/should_cast_hashes_properly.approved.png +0 -0
  53. data/spec/fixtures/fonts/FreeMono.ttf +0 -0
  54. data/spec/fixtures/fonts/GaroaHackerClubeBold.otf +0 -0
  55. data/spec/fixtures/fonts/GaroaHackerClubeBold.otf.credits.yaml +4 -0
  56. data/spec/fixtures/images/an_example.png +0 -0
  57. data/spec/fixtures/images/background.bmp +0 -0
  58. data/spec/fixtures/images/background.jpg +0 -0
  59. data/spec/fixtures/images/background.png +0 -0
  60. data/spec/fixtures/images/foo.jpg +0 -0
  61. data/spec/fixtures/images/hello.bmp +0 -0
  62. data/spec/fixtures/images/sprites.jpg +0 -0
  63. data/spec/fixtures/images/tile.png +0 -0
  64. data/spec/fixtures/images/x.png +0 -0
  65. data/spec/functional/lazy_foo_tutorial/lazy_foo_01_hello_world_spec.rb +39 -0
  66. data/spec/functional/lazy_foo_tutorial/lazy_foo_02_optimized_images_spec.rb +51 -0
  67. data/spec/functional/lazy_foo_tutorial/lazy_foo_03_extension_libraries_spec.rb +31 -0
  68. data/spec/functional/lazy_foo_tutorial/lazy_foo_04_event_driven_programming_spec.rb +55 -0
  69. data/spec/functional/lazy_foo_tutorial/lazy_foo_05_color_keying_spec.rb +41 -0
  70. data/spec/functional/lazy_foo_tutorial/lazy_foo_06_clip_blitting_and_sprite_sheets_spec.rb +41 -0
  71. data/spec/functional/lazy_foo_tutorial/lazy_foo_07_true_type_fonts_spec.rb +56 -0
  72. data/spec/functional/lazy_foo_tutorial/lazy_foo_08_key_presses_spec.rb +120 -0
  73. data/spec/functional/lazy_foo_tutorial/lazy_foo_helper.rb +6 -0
  74. data/spec/png_writer.rb +21 -0
  75. data/spec/spec_helper.rb +23 -0
  76. data/spec/unit/sdl2/color_spec.rb +46 -0
  77. data/spec/unit/unit_helper.rb +3 -0
  78. data/test/approvals/clip_blitting_and_sprite_sheets.received.bmp +0 -0
  79. data/test/approvals/color_keying_example.approved.png +0 -0
  80. data/test/approvals/hello_world_example_hello.approved.png +0 -0
  81. data/test/approvals/hello_world_example_screen.approved.png +0 -0
  82. data/test/approvals/optimized_surface_loading.approved.png +0 -0
  83. data/test/fixtures/background.jpg +0 -0
  84. data/test/fixtures/foo.jpg +0 -0
  85. data/test/fixtures/sprites.jpg +0 -0
  86. data/test/fixtures/x.png +0 -0
  87. data/test/functional/examples/lazyfoo.net_s/test_clip_blitting_and_sprite_sheets.rb +50 -0
  88. data/test/functional/examples/lazyfoo.net_s/test_color_keying.rb +42 -0
  89. data/test/functional/examples/test_lazy_foo_examples.rb +120 -48
  90. data/test/test_helper.rb +9 -0
  91. metadata +138 -4
  92. data/graph +0 -566
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8be28ad160c53b7d6a78228b54f51b52cdd3f23f
4
- data.tar.gz: 614dda38c426b697ab56834290ac2aea6eff897d
3
+ metadata.gz: 60ab089f8e71037fce4c4f2a46cf5586db4af65f
4
+ data.tar.gz: cd50c7524713298ed2ad850d637a46f0c20d6347
5
5
  SHA512:
6
- metadata.gz: 71725da19c1cd8fa51d6f0fbbbe3ff956beb69b84443539c9935a46935b8ed7f4e07bbd1c4085ba38288ea132a8c7aaff9579168aa0729d86b7c93992120110e
7
- data.tar.gz: ba822728cec706ca7a4401e81db8fc6f230d5ce156dee6a8bc40785022b215207b3ace9450c9eebcd5c5bea4f20cc80d629b43d669e0c26ddf7dc606caf3503a
6
+ metadata.gz: 8322d3174b86096df92c9fd2127b54604c3ef9e99a4f1c055bb56570e0e986bcd93fd8d576bd7d444daac7bca497162b5f0aea94eac8e5c58c113d62797034ea
7
+ data.tar.gz: 028e8e3b02c672c1fb45796bb21bdc8cb25f369b9cf34f8861e816f099f3a56277d7003ac5256efcbd697f7f88ed96299b41cbe4ebb0c6e1dd89c6ed0ba35d30
data/.gitignore CHANGED
@@ -19,3 +19,5 @@ tmp
19
19
  .buildpath
20
20
  *~
21
21
  .settings
22
+ .approvals
23
+ spec/fixtures/approvals/**/*received*
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in sdl2_ffi.gemspec
4
4
  gemspec
5
+
6
+ # TODO: Once SDL/Image support has been added, migrate to official
7
+ # gem.
8
+ group :development do
9
+ gem 'approvals', git:'http://github.com/BadQuanta/approvals', branch: 'feature_binary_formats'
10
+ end
data/Guardfile CHANGED
@@ -1,33 +1,55 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard :minitest do
5
- # with Minitest::Unit
6
- watch(%r{^test/(.*)\/?test_(.*)\.rb})
7
- watch(%r{^lib/(.*/)?([^/]+)\.rb}) { |m| "test/unit/#{m[1]}test_#{m[2]}.rb" }
8
- watch(%r{^test/test_helper\.rb}) { 'test' }
4
+ #guard :minitest do
5
+ # # with Minitest::Unit
6
+ # watch(%r{^test/(.*)\/?test_(.*)\.rb})
7
+ # watch(%r{^lib/(.*/)?([^/]+)\.rb}) { |m| "test/unit/#{m[1]}test_#{m[2]}.rb" }
8
+ # watch(%r{^test/test_helper\.rb}) { 'test' }
9
+ #
10
+ # # with Minitest::Spec
11
+ # watch(%r{^spec/(.*)_spec\.rb})
12
+ # watch(%r{^lib/(.+)\.rb}) { |m| "spec/unit/#{m[1]}_spec.rb" }
13
+ # watch(%r{^spec/spec_helper\.rb}) { 'spec' }
14
+ #
15
+ # # Rails 4
16
+ # # watch(%r{^test/test_helper\.rb}) { 'test' }
17
+ # # watch(%r{^test/.+_test\.rb})
18
+ # # watch(%r{^app/(.+)\.rb}) { |m| "test/#{m[1]}_test.rb" }
19
+ # # watch(%r{^app/controllers/application_controller\.rb}) { 'test/controllers' }
20
+ # # watch(%r{^app/controllers/(.+)_controller\.rb}) { |m| "test/integration/#{m[1]}_test.rb" }
21
+ # # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
22
+ # # watch(%r{^lib/(.+)\.rb}) { |m| "test/lib/#{m[1]}_test.rb" }
23
+ #
24
+ # # Rails 3.2
25
+ # # watch(%r{^app/controllers/(.*)\.rb}) { |m| "test/controllers/#{m[1]}_test.rb" }
26
+ # # watch(%r{^app/helpers/(.*)\.rb}) { |m| "test/helpers/#{m[1]}_test.rb" }
27
+ # # watch(%r{^app/models/(.*)\.rb}) { |m| "test/unit/#{m[1]}_test.rb" }
28
+ #
29
+ # # Rails
30
+ # # watch(%r{^app/controllers/(.*)\.rb}) { |m| "test/functional/#{m[1]}_test.rb" }
31
+ # # watch(%r{^app/helpers/(.*)\.rb}) { |m| "test/helpers/#{m[1]}_test.rb" }
32
+ # # watch(%r{^app/models/(.*)\.rb}) { |m| "test/unit/#{m[1]}_test.rb" }
33
+ #end
9
34
 
10
- # with Minitest::Spec
11
- watch(%r{^spec/(.*)_spec\.rb})
12
- watch(%r{^lib/(.+)\.rb}) { |m| "spec/unit/#{m[1]}_spec.rb" }
13
- watch(%r{^spec/spec_helper\.rb}) { 'spec' }
35
+ guard :rspec do
36
+ watch(%r{^spec/.+_spec\.rb$})
37
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
38
+ watch('spec/spec_helper.rb') { "spec" }
14
39
 
15
- # Rails 4
16
- # watch(%r{^test/test_helper\.rb}) { 'test' }
17
- # watch(%r{^test/.+_test\.rb})
18
- # watch(%r{^app/(.+)\.rb}) { |m| "test/#{m[1]}_test.rb" }
19
- # watch(%r{^app/controllers/application_controller\.rb}) { 'test/controllers' }
20
- # watch(%r{^app/controllers/(.+)_controller\.rb}) { |m| "test/integration/#{m[1]}_test.rb" }
21
- # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
22
- # watch(%r{^lib/(.+)\.rb}) { |m| "test/lib/#{m[1]}_test.rb" }
40
+ # Rails example
41
+ #watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
42
+ #watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
43
+ #watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
44
+ #watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
45
+ #watch('config/routes.rb') { "spec/routing" }
46
+ #watch('app/controllers/application_controller.rb') { "spec/controllers" }
23
47
 
24
- # Rails 3.2
25
- # watch(%r{^app/controllers/(.*)\.rb}) { |m| "test/controllers/#{m[1]}_test.rb" }
26
- # watch(%r{^app/helpers/(.*)\.rb}) { |m| "test/helpers/#{m[1]}_test.rb" }
27
- # watch(%r{^app/models/(.*)\.rb}) { |m| "test/unit/#{m[1]}_test.rb" }
48
+ # Capybara features specs
49
+ #watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
28
50
 
29
- # Rails
30
- # watch(%r{^app/controllers/(.*)\.rb}) { |m| "test/functional/#{m[1]}_test.rb" }
31
- # watch(%r{^app/helpers/(.*)\.rb}) { |m| "test/helpers/#{m[1]}_test.rb" }
32
- # watch(%r{^app/models/(.*)\.rb}) { |m| "test/unit/#{m[1]}_test.rb" }
51
+ # Turnip features and steps
52
+ #watch(%r{^spec/acceptance/(.+)\.feature$})
53
+ #watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
33
54
  end
55
+
data/Rakefile CHANGED
@@ -1,5 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
+ require 'rspec/core/rake_task.rb'
4
+
5
+ RSpec::Core::RakeTask.new do |t|
6
+
7
+
8
+ end
3
9
 
4
10
  Rake::TestTask.new do |t|
5
11
  t.pattern = 'test/**/test*.rb'
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'approvals' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('sdl2_ffi', 'approvals')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'autospec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('sdl2_ffi', 'autospec')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'htmldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('sdl2_ffi', 'htmldiff')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'ldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('sdl2_ffi', 'ldiff')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'nokogiri' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('sdl2_ffi', 'nokogiri')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('sdl2_ffi', 'rspec')
@@ -6,13 +6,13 @@ require 'ffi'
6
6
  # An example:
7
7
  # module MyEnumeration
8
8
  # include EnumerableConstants
9
- # MY_FIRST_CONSTANT = next_const_value # defaults to 0
10
- # MY_NEXT_CONSTANT = next_const_value # will be 1
11
- # MY_THIRD_CONSTANT = next_const_value # will be 2, and the next would be 3 unless
9
+ # MY_FIRST_CONSTANT # defaults to 0
10
+ # MY_NEXT_CONSTANT # will be 1
11
+ # MY_THIRD_CONSTANT # will be 2, and the next would be 3 unless
12
12
  # MY_FOURTH_CONSTANT = 100 # you assign a value.
13
- # MY_FIFTH_CONSTANT = next_const_value # will be 101
13
+ # MY_FIFTH_CONSTANT # will be 101
14
14
  # MY_SIXTH_CONSTANT = MY_THIRD_CONSTANT # There are no rules against duplicate values.
15
- # MY_SEVENTH_CONSTANT = next_const_value # will be 3, be careful you don't unintentionally reuse values.
15
+ # MY_SEVENTH_CONSTANT # will be 3, be careful you don't unintentionally reuse values.
16
16
  # end
17
17
  #
18
18
  # With this module, you can:
@@ -34,10 +34,14 @@ require 'ffi'
34
34
  #
35
35
  # MyEnumeration::MY_EIGTH_CONSTANT = MyEnumeration.next_const_value # 4
36
36
  #
37
+ # Or, you could just do:
38
+ #
39
+ # MyEnumeration::MY_NINTH_CONSTANT #=> Automatically assigned value 5
40
+ #
37
41
  # However, successive calls to just `#next_const_value` will just result in
38
42
  # the same value.
39
- # MyEnumeration.next_const_value # 5
40
- # MyEnumeration.next_const_value # 5
43
+ # MyEnumeration.next_const_value # 6
44
+ # MyEnumeration.next_const_value # 6
41
45
  module EnumerableConstants
42
46
 
43
47
  # This is the method that injects the new static-scope routines.
@@ -54,6 +58,15 @@ module EnumerableConstants
54
58
  return result
55
59
  end
56
60
 
61
+ # Return the defined constants in a hash keyed by value.
62
+ def self.by_value
63
+ result = {}
64
+ self.constants.each do |constant|
65
+ result[self.const_get(constant)] = constant
66
+ end
67
+ return result
68
+ end
69
+
57
70
  # This routine returns a flattened array of alternating symbols and values.
58
71
  # The symbols are the CONSTANT names and values are the values defined by that constant.
59
72
  def self.flatten_consts
@@ -76,7 +89,9 @@ module EnumerableConstants
76
89
  last_const_value.next
77
90
  end
78
91
 
92
+ def self.const_missing(const)
93
+ self.const_set(const, next_const_value)
94
+ end
79
95
  end
80
96
  end
81
-
82
97
  end
@@ -2,48 +2,35 @@ require 'sdl2/sdl_module'
2
2
  require 'active_support/inflector'
3
3
  require 'enumerable_constants'
4
4
  require 'sdl2/stdinc'
5
+
5
6
  # libSDL2's prototypes are attached directly to this module.
6
7
  #
7
8
  module SDL2
8
9
  extend FFI::Library
9
10
  extend Library
10
- ffi_lib SDL_MODULE
11
-
12
- # FFI::Struct class with some useful additions.
13
- class Struct < FFI::Struct
11
+ ffi_lib SDL_MODULE
14
12
 
15
- # Allows creation and use within block, automatically freeing pointer after block.
16
- def initialize(*args, &block)
17
- super(*args)
18
- if block_given?
19
- throw 'Release must be defined to use block' unless self.class.respond_to?(:release)
20
- yield self
21
- self.class.release(self.pointer)
22
- end
23
- end
13
+ PrintDebug = false
24
14
 
25
- # A default release scheme is defined, but should be redefined where appropriate.
26
- def self.release(pointer)
27
- pointer.free
28
- end
15
+ module StructHelper
29
16
 
30
17
  # Define a set of member readers
31
18
  # Ex1: `member_readers [:one, :two, :three]`
32
19
  # Ex2: `member_readers *members`
33
- def self.member_readers(*members_to_define)
20
+ def member_readers(*members_to_define)
34
21
  #self.class_eval do
35
22
  members_to_define.each do |member|
36
23
  define_method member do
37
- [member]
24
+ self[member]
38
25
  end
39
26
  end
40
27
  #end
41
28
  end
42
29
 
43
30
  # Define a set of member writers
44
- # Ex1: `member_writers [:one, :two, :three]`
45
- # Ex2: `member_writers *members`
46
- def self.member_writers(*members_to_define)
31
+ # Ex1: `member_writers [:one, :two, :three]`
32
+ # Ex2: `member_writers *members`
33
+ def member_writers(*members_to_define)
47
34
  members_to_define.each do |member|
48
35
  define_method "#{member}=".to_sym do |value|
49
36
  self[member]= value
@@ -51,32 +38,121 @@ module SDL2
51
38
  end
52
39
  end
53
40
 
54
- # A human-readable representation of the struct and it's values.
55
- def inspect
56
- return 'nil' if self.null?
41
+ end
42
+
43
+ # Augmented for compares with anything that can be an array
44
+ class FFI::Struct::InlineArray
45
+
46
+ def ==(other)
47
+ self.to_a == other.to_a
48
+ end
49
+ end
57
50
 
58
- #binding.pry
59
- #return self.to_s
51
+ # FFI::Struct class with some useful additions.
52
+ class Struct < FFI::Struct
53
+ extend StructHelper
54
+
55
+ # Allows creation and use within block, automatically freeing pointer after block.
56
+ def initialize(*args, &block)
57
+ super(*args)
58
+ if block_given?
59
+ throw 'Release must be defined to use block' unless self.class.respond_to?(:release)
60
+ yield self
61
+ self.class.release(self.pointer)
62
+ end
63
+ end
60
64
 
61
- report = "struct #{self.class.to_s}{"
62
- report += self.class.members.collect do |field|
63
- "#{field}->#{self[field].inspect}"
64
- end.join(' ')
65
- report += "}"
65
+ # A default release scheme is defined, but should be redefined where appropriate.
66
+ def self.release(pointer)
67
+ pointer.free
66
68
  end
67
69
 
70
+ # A human-readable representation of the struct and it's values.
71
+ #def inspect
72
+ # return 'nil' if self.null?
73
+ #
74
+ # #binding.pry
75
+ # #return self.to_s
76
+ #
77
+ # report = "struct #{self.class.to_s}{"
78
+ # report += self.class.members.collect do |field|
79
+ # "#{field}->#{self[field].inspect}"
80
+ # end.join(' ')
81
+ # report += "}"
82
+ # end
83
+
68
84
  # Compare two structures by class and values.
69
85
  def ==(other)
70
- return false unless self.class == other.class
71
- self.class.members.each do |field|
72
- return false unless self[field] == other[field]
86
+ if PrintDebug
87
+ @@rec ||= -1
88
+ @@rec += 1
89
+ pad = "\t"*@@rec
90
+
91
+ puts
92
+ puts " #{pad}COMPARING #{self} to #{other}"
93
+ end
94
+
95
+ result = catch(:result) do
96
+ unless self.class == other.class
97
+ puts "Class Mismatch" if PrintDebug
98
+ throw :result, false
99
+ end
100
+
101
+ if self.null? or other.null?
102
+ unless self.null? and other.null?
103
+ puts "AHHHAOne is null and the other is not" if PrintDebug
104
+ throw :result, false
105
+ end
106
+ else
107
+ self.class.members.each do |field|
108
+ print "#{pad} #{field}:#{self[field].class} = " if PrintDebug
109
+
110
+ unless self[field] == other[field]
111
+ binding.pry
112
+ puts "NO MATCH: #{self[field].to_s} #{other[field].to_s}" if PrintDebug
113
+ throw :result, false
114
+ end
115
+ puts "MATCH" if PrintDebug
116
+ end
117
+ end
118
+
119
+ true # Everything passed.
120
+
121
+ end
122
+ if PrintDebug
123
+ @@rec += -1
124
+ puts
125
+ puts "#{pad}RESULT = #{result}"
126
+ end
127
+ return result
128
+ end
129
+
130
+ # Default cast handler
131
+ def self.cast(something)
132
+ if something.kind_of? self
133
+ return something
134
+ elsif something.kind_of? Hash
135
+ common = (self.members & something.keys)
136
+ if common.empty?
137
+ raise "#{self} can't cast this Hash: #{something.inspect}"
138
+ else
139
+ tmp = self.new
140
+ common.each do |field|
141
+ tmp[field] = something[field]
142
+ end
143
+ return tmp
144
+ end
145
+ elsif something.nil?
146
+ return something #TODO: Assume NUL is ok?
147
+ else
148
+ raise "#{self} can't cast #{something.insepct}"
73
149
  end
74
- true # return true if we get this far.
75
150
  end
76
151
  end
77
152
 
78
153
  # FFI::ManagedStruct possibly with useful additions.
79
154
  class ManagedStruct < FFI::ManagedStruct
155
+ extend StructHelper
80
156
 
81
157
  # Allows create and use the struct within a block.
82
158
  def initialize(*args, &block)
@@ -88,7 +164,9 @@ module SDL2
88
164
 
89
165
  end
90
166
 
91
-
167
+ class Union < FFI::Union
168
+ extend StructHelper
169
+ end
92
170
 
93
171
  class TypedPointer < Struct
94
172
 
@@ -126,7 +204,7 @@ module SDL2
126
204
  class UInt8Struct < TypedPointer
127
205
  type :uint8
128
206
  end
129
-
207
+
130
208
  # TODO: Review if this is the best place to put it.
131
209
  # BlendMode is defined in a header file that is always included, so I'm
132
210
  # defineing again here.
@@ -148,7 +226,6 @@ module SDL2
148
226
 
149
227
  end
150
228
 
151
-
152
229
  require 'sdl2/init'
153
230
 
154
231
  #TODO: require 'sdl2/assert'