hemi 0.0.3 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b1a159b551a31d4a0ff8fda11c6c150a90bbef0d95ffedbd4dfd6e6142ccf8f
4
- data.tar.gz: a1a2ee8d0853fc8bad1c63c85fb625c80291b8e4ab5f9a0deeb3c2f902a1dec5
3
+ metadata.gz: 8f36ce1ac46670d07a633de63c38a9f5b0f5faeb44e35c207647634cc9c34319
4
+ data.tar.gz: 71a1d9d0f6833d6ec66cd952a0ffc6d538508244d30165bdbb54c8dfd461eb54
5
5
  SHA512:
6
- metadata.gz: 7f03cbe78fd24c28c0c047d0af79c30dfdf30cfc489fd68266857f13b2bfcfacb741483874010950ba32eccebe4fe48017de48c73a9888080189a35d95e5f305
7
- data.tar.gz: 907cc97ad98a88349b1d7b0bb8dbd06c8f04340cf38ecfa5bf4257593b6e1a96515390d916af67a0f8ffd7d5502210a3f0dfe6bf98831288a5e9458bc25f3094
6
+ metadata.gz: 76cb55701b6c8c2a6464baebeadd91b0fe134bc42ec7d6beb543c4e50b7ee8db5c4951f518350a650c661e26bd3d97e453b5671cb4e37d8a3f92a1ff21dac8ae
7
+ data.tar.gz: c11c2a318a70225d2cf5773c10245e842f7fdc9fc7c509006d225e004d7be9a43b58b2a2faf2dd0ad1ee424e8aa4e22844266fff898e98726b27c1f5ed1d8009
@@ -0,0 +1,79 @@
1
+ version: 2.1
2
+ orbs:
3
+ ruby: circleci/ruby@0.1.2
4
+
5
+ defaults: &defaults
6
+ working_directory: ~/hemi
7
+
8
+ ruby_machine: &ruby_machine
9
+ <<: *defaults
10
+ docker:
11
+ - image: ellmo/ruby-hemi:0.0.3
12
+ environment:
13
+ RAILS_ENV: test
14
+ BUNDLE_PATH: vendor/bundle
15
+ BUNDLER_VERSION: 2.1.4
16
+ executor: ruby/default
17
+
18
+ jobs:
19
+ build:
20
+ <<: *ruby_machine
21
+ steps:
22
+ - checkout
23
+ - attach_workspace:
24
+ at: ~/hemi
25
+ - run:
26
+ name: Bundle install
27
+ command: |
28
+ gem install bundler -v=${BUNDLER_VERSION}
29
+ bundle install --path=vendor/bundle
30
+ - run:
31
+ name: Download cc-test-reporter
32
+ command: |
33
+ mkdir -p tmp/
34
+ curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./tmp/cc-test-reporter
35
+ chmod +x ./tmp/cc-test-reporter
36
+ - persist_to_workspace:
37
+ root: ~/hemi
38
+ paths:
39
+ - vendor/bundle
40
+ - tmp/cc-test-reporter
41
+
42
+ test:
43
+ <<: *ruby_machine
44
+ steps:
45
+ - checkout
46
+ - attach_workspace:
47
+ at: ~/hemi
48
+ - run:
49
+ name: RSpec
50
+ command: |
51
+ gem install bundler -v=${BUNDLER_VERSION}
52
+ bundle exec rspec
53
+ ./tmp/cc-test-reporter format-coverage -t simplecov -o tmp/codeclimate.backend.json coverage/backend/.resultset.json
54
+ - persist_to_workspace:
55
+ root: ~/hemi
56
+ paths:
57
+ - tmp/codeclimate.backend.json
58
+ upload_coverage:
59
+ <<: *ruby_machine
60
+ steps:
61
+ - attach_workspace:
62
+ at: ~/hemi
63
+ - run:
64
+ name: Upload coverage results to Code Climate
65
+ command: |
66
+ ./tmp/cc-test-reporter sum-coverage tmp/codeclimate.*.json -p 1 -o tmp/codeclimate.total.json
67
+ ./tmp/cc-test-reporter upload-coverage -i tmp/codeclimate.total.json
68
+
69
+ workflows:
70
+ version: 2
71
+ build_and_test:
72
+ jobs:
73
+ - build
74
+ - test:
75
+ requires:
76
+ - build
77
+ - upload_coverage:
78
+ requires:
79
+ - test
data/.gitignore CHANGED
@@ -1,8 +1,10 @@
1
1
  *.gem
2
2
  .DS_store
3
3
  .bundle/
4
- .yardoc/
4
+ .yardoc
5
5
 
6
6
  vendor/bundle/
7
7
  examples/
8
+ coverage/
9
+ doc/
8
10
 
@@ -41,12 +41,23 @@ Style/ClassAndModuleChildren:
41
41
  Style/Documentation:
42
42
  Enabled: false
43
43
 
44
+ # NAMING
45
+ Naming/FileName:
46
+ Exclude:
47
+ - 'demo/**/*'
48
+
44
49
  # RSPEC
45
50
  RSpec/ContextWording:
46
51
  Enabled: false
52
+ RSpec/MessageSpies:
53
+ Enabled: false
54
+ RSpec/MultipleExpectations:
55
+ Max: 5
47
56
  RSpec/NamedSubject:
48
57
  Enabled: false
49
58
  RSpec/NestedGroups:
50
59
  Max: 5
60
+ RSpec/SubjectStub:
61
+ Enabled: false
51
62
  RSpec/VerifiedDoubles:
52
63
  Enabled: false
@@ -0,0 +1 @@
1
+ --markup=markdown
data/DEV.md ADDED
@@ -0,0 +1,26 @@
1
+ ## Development
2
+ (`sdl2` libs are - obviously - still required)
3
+
4
+ #### 1. Install Ruby and gems
5
+
6
+ Install specific ruby version using Rbenv (`rbenv install`) or RVM (yuck)
7
+
8
+ Make sure you have Bundler gem installed for this revsion (`gem install bundler -v=1.17.3`)
9
+
10
+ And `bundle install` away.
11
+
12
+ #### 2. Update code (and bump the version)
13
+
14
+ Dont forget to `git tag` and push with `--tags option`
15
+
16
+ #### 3. Build and push to Rubygems
17
+
18
+ `gem build hemi.gemspec`
19
+
20
+ `gem push hemi-{VERSION}.gem`
21
+
22
+ And if you need to test gem installation locally:
23
+
24
+ `gem push hemi-{VERSION}.gem`
25
+
26
+
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hemi (0.0.2)
4
+ hemi (0.0.3)
5
5
  pry (~> 0.12)
6
6
  ruby-sdl2 (= 0.3.5)
7
7
 
@@ -11,6 +11,7 @@ GEM
11
11
  ast (2.4.0)
12
12
  coderay (1.1.3)
13
13
  diff-lcs (1.3)
14
+ docile (1.3.4)
14
15
  jaro_winkler (1.5.4)
15
16
  method_source (1.0.0)
16
17
  parallel (1.19.1)
@@ -46,7 +47,14 @@ GEM
46
47
  rubocop (>= 0.68.1)
47
48
  ruby-progressbar (1.10.1)
48
49
  ruby-sdl2 (0.3.5)
50
+ simplecov (0.20.0)
51
+ docile (~> 1.1)
52
+ simplecov-html (~> 0.11)
53
+ simplecov_json_formatter (~> 0.1)
54
+ simplecov-html (0.12.3)
55
+ simplecov_json_formatter (0.1.2)
49
56
  unicode-display_width (1.6.0)
57
+ yard (0.9.26)
50
58
 
51
59
  PLATFORMS
52
60
  ruby
@@ -57,6 +65,8 @@ DEPENDENCIES
57
65
  rubocop (~> 0.77)
58
66
  rubocop-performance (~> 1.5)
59
67
  rubocop-rspec (~> 1.37)
68
+ simplecov (~> 0.20)
69
+ yard (~> 0.9)
60
70
 
61
71
  BUNDLED WITH
62
72
  2.1.4
data/README.md CHANGED
@@ -7,37 +7,90 @@ Made for self-educational purposes.
7
7
 
8
8
  ## Usage
9
9
 
10
- #### 1. Required libraries
11
-
12
- Install `sdl2`, `sdl2_image`, `sdl2_mixer` and `sdl2_ttf` libraries. For MacOS you can simply `brew install` all of them.
13
-
14
- #### 2. Using gem
15
-
16
- Refer to [demo](https://github.com/ellmo/hemi/blob/master/demo/loop_machine_demo.rb) for now.
17
-
18
- ## Development
19
- (`sdl2` libs are - obviously - still required)
20
-
21
- #### 1. Install Ruby and gems
22
-
23
- Install specific ruby version using Rbenv (`rbenv install`) or RVM (yuck)
24
-
25
- Make sure you have Bundler gem installed for this revsion (`gem install bundler -v=1.17.3`)
26
-
27
- And `bundle install` away.
28
-
29
- #### 2. Update code (and bump the version)
30
-
31
- Dont forget to `git tag` and push with `--tags option`
32
-
33
- #### 3. Build and push to Rubygems
34
-
35
- `gem build hemi.gemspec`
36
-
37
- `gem push hemi-{VERSION}.gem`
38
-
39
- And if you need to test gem installation locally:
40
-
41
- `gem push hemi-{VERSION}.gem`
42
-
43
-
10
+ ### 0. Required libraries
11
+ Install `sdl2`, `sdl2_image`, `sdl2_mixer` and `sdl2_ttf` libraries.
12
+ For MacOS you can simply `brew install` all of them.
13
+
14
+ ### 1. Using the gem
15
+
16
+ #### 1.0 installation
17
+ Install the gem, either straight-up with `gem install hemi` or using Bundler:
18
+
19
+ ```ruby
20
+ # Gemfile
21
+ source "https://rubygems.org"
22
+
23
+ gem "hemi"
24
+ ```
25
+
26
+ #### 1.1 prepend your starting class
27
+ ```ruby
28
+ require "hemi"
29
+
30
+ class Game
31
+ prepend Hemi::Engine
32
+ end
33
+
34
+ ```
35
+
36
+ #### 1.2 prepare a logic proc
37
+ This `proc` will contain logic to be performed during each rendered frame.
38
+ ```ruby
39
+ Font = Hemi::Render::Font
40
+ Sprite = Hemi::Render::Sprite
41
+
42
+ def text_logic
43
+ proc {
44
+ Font[:jost_32].render("quick brown fox jumped over the lazy dog", position: [20, 20])
45
+ Font[:jost_16].render("press [space] to change LoopState", position: [20, 400])
46
+ Font[:jost_16].render("press [q] or [esc] to quit", position: [20, 420])
47
+ Font[:jost_16].render("press [F12] to start debug", position: [20, 440])
48
+ }
49
+ end
50
+
51
+ def sprite_logic
52
+ proc {
53
+ Sprite[:gem].render(position: { y: 220, x: 20 })
54
+ Sprite[:gem].render(position: { y: 320, x: 220 }, size: { height: 64, width: 128 })
55
+ Font[:jost_16].render("press [space] to change LoopState", position: [20, 400])
56
+ Font[:jost_16].render("press [q] or [esc] to quit", position: [20, 420])
57
+ Font[:jost_16].render("press [F12] to start debug", position: [20, 440])
58
+ }
59
+ end
60
+ ```
61
+
62
+ #### 1.3 prepare an {event:action} hash
63
+ ```ruby
64
+ LM = Hemi::Event::LoopMachine
65
+
66
+ def text_events
67
+ {
68
+ space: -> { LM.switch(:image) },
69
+ escape: :stop!,
70
+ q: :stop!,
71
+ f12: :debug!
72
+ }
73
+ end
74
+
75
+ def sprite_events
76
+ {
77
+ space: -> { LM.switch(:text) },
78
+ escape: :stop!,
79
+ q: :stop!,
80
+ f12: :debug!
81
+ }
82
+ end
83
+ ```
84
+
85
+ #### 1.4 register Loop Machine states
86
+ ```ruby
87
+ def run
88
+ LM.register(:text, text_logic, text_events)
89
+ LM.register(:image, sprite_logic, sprite_events)
90
+ end
91
+ ```
92
+
93
+ #### 1.5 and run it
94
+ ```ruby
95
+ Game.instance.run
96
+ ```
@@ -30,4 +30,6 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "rubocop", "~> 0.77"
31
31
  spec.add_development_dependency "rubocop-performance", "~> 1.5"
32
32
  spec.add_development_dependency "rubocop-rspec", "~> 1.37"
33
+ spec.add_development_dependency "simplecov", "~> 0.20"
34
+ spec.add_development_dependency "yard", "~> 0.9"
33
35
  end
@@ -4,24 +4,54 @@ require "sdl2"
4
4
  require_relative "loader"
5
5
 
6
6
  module Hemi
7
+ # Entry-level module, meant to be _prepended_ in the main class of the game using the `hemi` gem.
8
+ #
9
+ # Prepending this module allows developers to write their custom +initialize+ and +run+ methods
10
+ # without overriding any of the mandatory logic. Becasue of the `prepend` behavior,
11
+ # `Hemi::Engine` will end up first in ancestors' list.
12
+ #
13
+ # So, technically, if `Game` implements its own `initialize` / `run` methods, those will be
14
+ # super-called from `Hemi::Engine`:
15
+ #
16
+ # ```ruby
17
+ # require "hemi"
18
+ #
19
+ # class Game
20
+ # prepend Hemi::Engine
21
+ # end
22
+ #
23
+ # Game.ancestors
24
+ # => [Hemi::Engine, Game, Singleton, Object, PP::ObjectMixin, Kernel, BasicObject]
25
+ # ```
7
26
  module Engine
8
27
  @debug = false
9
28
  @stop = false
10
29
 
30
+ # Initializes all required `SDL` modules and then proceeds to execute the constructor of the
31
+ # class it prepends.
11
32
  def initialize
12
33
  sdl_init
13
34
  super
14
35
  end
15
36
 
37
+ # @return [SDL2::Window]
38
+ # @api private
16
39
  attr_reader :window
17
40
 
18
- def sdl_init
19
- SDL2.init(SDL2::INIT_EVERYTHING)
20
- end
21
-
22
41
  class << self
23
- attr_reader :debug, :stop
42
+ # @return [Boolean] Returns `true` if the engine is set to debugging mode.
43
+ attr_reader :debug
44
+ # @return [Boolean] Returns `true` if the engine is set to gracefully exit upon finishing
45
+ # this event loop.
46
+ attr_reader :stop
24
47
 
48
+ # Ran when a class calls to be prepended by this module.
49
+ #
50
+ # As mentioned - this module is meant to be _prepended_ in the main game class. When
51
+ # prepended, this method is automatically ran, making the class a Singleton and makes sure all
52
+ # `Hemi` modules are loaded in required order.
53
+ #
54
+ # @param [Class] klass
25
55
  def prepended(klass)
26
56
  klass.include Singleton
27
57
 
@@ -31,19 +61,47 @@ module Hemi
31
61
  Loader.load_tree "event"
32
62
  end
33
63
 
64
+ # Sets `@debug` instance variable to `true`. Doing this will trigger the current
65
+ # {Hemi::Event::LoopMachine#call LoopMachine's} {Hemi::Event::EventLoop EventLoop} to stop at
66
+ # the nearest `binding.pry` (thus, halting the game and allowing game's current state to be
67
+ # debugged).
68
+ #
69
+ # @note Ideally this method should NOT be called manually, {Hemi::Event::EventLoop EventLoop}
70
+ # calls it when it receives an event resulting in a `:debug!` action.
71
+ #
72
+ # @api private
34
73
  def debug_on!
35
74
  @debug = true
36
75
  end
37
76
 
77
+ # Sets `@debug` instance variable to `false`. This makes sure that after opening a pry
78
+ # REPL session and ending it with calling `exit` from pry's REPL, the `@debug` flag is off
79
+ # and the program can continue operating normally.
80
+ #
81
+ # @note Ideally this method should NOT be called manually. It is called internally right after
82
+ # {Hemi::Event::LoopMachine#call LoopMachine} handles `binding.pry` in `#debug?` method.
83
+ #
84
+ # @api private
38
85
  def debug_off!
39
86
  @debug = false
40
87
  end
41
88
 
89
+ # Sets `@stop` instance variable to `true`. This triggers a _graceful_ exit of the entire
90
+ # {Hemi::Event::LoopMachine#call LoopMachine's} {Hemi::Event::EventLoop EventLoop} - and,
91
+ # by extension, exits the program upon the next complete loop.
92
+ #
93
+ # @note Ideally this method should NOT be called manually, {Hemi::Event::EventLoop EventLoop}
94
+ # calls it when it receives an event resulting in a `:stop!` action.
95
+ #
96
+ # @api private
42
97
  def stop!
43
98
  @stop = true
44
99
  end
45
100
  end
46
101
 
102
+ # Starts the game engine. Takes care of all custom logic in prepended class' `#run` method, then
103
+ # initializes a program window and calls {Hemi::Event::LoopMachine LoopMachine} to start running
104
+ # its event loops.
47
105
  def run
48
106
  super if defined?(super)
49
107
  init_window
@@ -52,6 +110,10 @@ module Hemi
52
110
 
53
111
  private
54
112
 
113
+ def sdl_init
114
+ SDL2.init(SDL2::INIT_EVERYTHING)
115
+ end
116
+
55
117
  def init_window
56
118
  @window = Hemi::Render::Window.instance
57
119
  end
@@ -0,0 +1,4 @@
1
+ require_relative "key_handler"
2
+ require_relative "pattern/key"
3
+ require_relative "event_loop"
4
+ require_relative "loop_machine"
@@ -1,11 +1,10 @@
1
1
  module Hemi::Event
2
2
  class EventLoop
3
+ include Hemi::Event::KeyHandler
3
4
 
4
5
  def initialize(logic, events)
5
6
  @logic = logic
6
- @events = events.each_with_object({}) do |(key, action), hsh|
7
- hsh[SDL2::Key::Scan.const_get(key.upcase)] = action
8
- end
7
+ register_events!(events)
9
8
  end
10
9
 
11
10
  attr_reader :logic, :events, :event
@@ -17,8 +16,6 @@ module Hemi::Event
17
16
  when SDL2::Event::KeyDown
18
17
  handle_key
19
18
  end
20
-
21
- @event = nil
22
19
  end
23
20
 
24
21
  def process
@@ -27,25 +24,6 @@ module Hemi::Event
27
24
 
28
25
  private
29
26
 
30
- def handle_key
31
- case action = events[event.scancode]
32
- when Symbol
33
- instance_eval action.to_s
34
- when Proc
35
- action.call
36
- end
37
- end
38
-
39
- def key_event?
40
- event.is_a?
41
- end
42
-
43
- def key_down
44
- return unless key_event?
45
-
46
- SDL2::Key::Scan.const_get(event.scancode).downcase
47
- end
48
-
49
27
  def debug!
50
28
  Hemi::Engine.debug_on!
51
29
  end
@@ -0,0 +1,30 @@
1
+ module Hemi::Event
2
+ module KeyHandler
3
+ private
4
+
5
+ def handle_key
6
+ case action = events[event.structize]
7
+ when Symbol
8
+ instance_eval action.to_s
9
+ when Proc
10
+ action.call
11
+ end
12
+ end
13
+
14
+ def register_events!(events)
15
+ @events = event_hash(events)
16
+ end
17
+
18
+ def event_hash(events)
19
+ events.each_with_object({}) do |(input, action), hsh|
20
+ key, mods = if input.is_a? Array
21
+ [input.shift, input]
22
+ else
23
+ input
24
+ end
25
+
26
+ hsh[Hemi::Event::Pattern::Key.new(key, mods: mods)] = action
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,12 +1,27 @@
1
1
  module Hemi::Event
2
+ # The brain of the operation. A state machine which keeps performing assigned logic, while
3
+ # listening for assigned events.
2
4
  class LoopMachine
3
5
  include Singleton
4
6
 
5
7
  @loops = {}
6
8
  @current = nil
7
9
 
10
+ # @return [SDL2::Event] the last/current SDL event being handled.
11
+ # @api private
8
12
  attr_reader :event
9
13
 
14
+ # Main operation method. Performs these steps in order:
15
+ #
16
+ # 1. Wipes the current window (by drawing a black rectangle over it).
17
+ # 2. Checks if SDL picked up any events and handles them.
18
+ # 3. Processes the "frame" logic: calculating, moving and drawing to framebuffer.
19
+ # 4. Copies the frame's content from framebuffer to display (inside the window).
20
+ # 5. Checks if `Hemi::Engine.debug` has been set to `true`; opens a `pry` session if so.
21
+ # 6. Checks if `Hemi::Engine.stop` has been set to `true`; breaks from the loop if so.
22
+ # 7. Sleeps for a hardcoded amount of time.
23
+ #
24
+ # @note This method is being automatically called by {Hemi::Engine#run Hemi::Engine's} `#run`.
10
25
  def call
11
26
  loop do
12
27
  Hemi::Render::Window.wipe_screen
@@ -24,9 +39,32 @@ module Hemi::Event
24
39
  end
25
40
 
26
41
  class << self
27
- attr_reader :loops, :current
28
-
29
- def register(name, logic = -> {}, events = {})
42
+ # @return [Hash] A simple collection of "loop-states", with as their keys,
43
+ # and {EventLoop} instances as values.
44
+ attr_reader :loops
45
+ # @return [EventLoop] The currently active "loop-state", which logic and events are being
46
+ # handled in the main `#call` loop.
47
+ attr_reader :current
48
+
49
+ # Registers an {EventLoop} in the `@loops` collection with the `name` as its identifier.
50
+ # If the collection was empty before registration, the first {EventLoop} is automatically
51
+ # set as _current_.
52
+ #
53
+ # @param [Symbol] name The {EventLoop}'s identifier, i.e. - a key in `@loops` collection.
54
+ # @param [Proc] logic Proc-wrapped logic to be ran at every iteration of the loop (frame).
55
+ # @param [Hash] events A simple collection of events and their corresponding actions.
56
+ #
57
+ # @example excerpt from demo/01-loop_machine_demo.rb
58
+ # class LoopMachineDemo
59
+ # prepend Hemi::Engine
60
+ # LM = Hemi::Event::LoopMachine
61
+ #
62
+ # def run
63
+ # LM.register(:text, text_block, text_events)
64
+ # LM.register(:image, sprite_block, sprite_events)
65
+ # end
66
+ # end
67
+ def register(name, logic = proc {}, events = {})
30
68
  event_loop = EventLoop.new(logic, events)
31
69
  @current = event_loop if loops.empty?
32
70
  @loops[name] = event_loop
@@ -34,14 +72,24 @@ module Hemi::Event
34
72
  event_loop
35
73
  end
36
74
 
75
+ # Fetch a registered {EventLoop} from `@loops` collection.
76
+ #
77
+ # @param [Symbol] name
78
+ # @return [EventLoop]
37
79
  def [](name)
38
80
  @loops[name]
39
81
  end
40
82
 
83
+ # Transitions to another state, setting its {EventLoop} as `@current`. Starts performing its
84
+ # logic and listening to its events.
41
85
  def switch(name)
42
86
  @current = LoopMachine[name]
43
87
  end
44
88
 
89
+ # Empties `@loops` collection and sets `@current` state to nil. Currently only used
90
+ # to ensure spec scenario isolation.
91
+ #
92
+ # @api private
45
93
  def purge!
46
94
  @loops = {}
47
95
  @current = nil
@@ -0,0 +1,38 @@
1
+ module Hemi::Event
2
+ module Pattern
3
+ class Key
4
+ MATCHED_EVENT = "SDL2::Event::KeyDown".freeze
5
+
6
+ ALLOWED_TYPES = %i[up down].freeze
7
+ MOD_KEYS = %i[lshift rshift lctrl rctrl lalt ralt lgui rgui].freeze
8
+
9
+ def initialize(key, type: :down, mods: nil)
10
+ @type = type.to_s
11
+ @key = key.to_s
12
+ @mods = mods
13
+ key_to_scancode
14
+ mods_to_modcode
15
+ end
16
+
17
+ attr_reader :type, :key, :mods, :scancode, :modcode
18
+
19
+ def hash
20
+ KeyPattern.new(scancode, modcode).hash
21
+ end
22
+
23
+ def inspect
24
+ "#<#{self.class}:#{hash} key=#{key} mods=#{mods.join(', ')}>"
25
+ end
26
+
27
+ def key_to_scancode
28
+ @scancode = SDL2::Key::Scan.const_get(key.upcase)
29
+ end
30
+
31
+ def mods_to_modcode
32
+ @modcode = mods&.sum do |modkey|
33
+ SDL2::Key::Mod.const_get(modkey.upcase)
34
+ end || 0
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ class SDL2::Event
2
+ def structize
3
+ KeyPattern.new(scancode, mod)
4
+ end
5
+ end
6
+
7
+ class Struct
8
+ def eql?(other)
9
+ hash == other.hash
10
+ end
11
+ end
@@ -1,2 +1,3 @@
1
- Size = Struct.new(:width, :height, keyword_init: true)
2
- Position = Struct.new(:x, :y, keyword_init: true)
1
+ Size = Struct.new(:width, :height, keyword_init: true)
2
+ Position = Struct.new(:x, :y, keyword_init: true)
3
+ KeyPattern = Struct.new(:scancode, :mod)
@@ -1,11 +1,11 @@
1
1
  module Hemi
2
2
  module Loader
3
- def self.load_tree(tree_dir)
3
+ def self.load_tree(tree_dir, relative: false)
4
4
  if File.exist?(manifest_file = File.join(__dir__, tree_dir, "_manifest.rb"))
5
- require manifest_file
5
+ relative ? require_relative(manifest_file) : require(manifest_file)
6
6
  else
7
7
  Dir[File.join(__dir__, tree_dir, "**", "*.rb")].sort.each do |file|
8
- require file
8
+ relative ? require_relative(file) : require(file)
9
9
  end
10
10
  end
11
11
  end
@@ -2,7 +2,7 @@ module Hemi::Render
2
2
  class Texture
3
3
  ERR__INVALID_POSITION = "Ivalid position.".freeze
4
4
 
5
- def initialize(name)
5
+ def initialize
6
6
  raise NotImplementedError
7
7
  end
8
8
 
@@ -66,7 +66,7 @@ module Hemi::Render
66
66
  position_obj.x = position[:x]
67
67
  position_obj.y = position[:y]
68
68
  else
69
- raise ArgumentError(ERR__INVALID_POSITION)
69
+ raise ArgumentError, ERR__INVALID_POSITION
70
70
  end
71
71
 
72
72
  position_obj
@@ -1,3 +1,3 @@
1
1
  module Hemi
2
- VERSION = "0.0.3".freeze
2
+ VERSION = "0.0.4".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hemi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Żuchowski
@@ -94,25 +94,59 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.37'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.20'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.20'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.9'
97
125
  description:
98
126
  email: ellmo@ellmo.net
99
127
  executables: []
100
128
  extensions: []
101
129
  extra_rdoc_files: []
102
130
  files:
131
+ - ".circleci/config.yml"
103
132
  - ".gitignore"
104
133
  - ".rspec"
105
134
  - ".rubocop.yml"
106
135
  - ".ruby-version"
136
+ - ".yardopts"
137
+ - DEV.md
107
138
  - Gemfile
108
139
  - Gemfile.lock
109
140
  - README.md
110
141
  - hemi.gemspec
111
142
  - lib/hemi.rb
112
143
  - lib/hemi/engine.rb
144
+ - lib/hemi/event/_manifest.rb
113
145
  - lib/hemi/event/event_loop.rb
146
+ - lib/hemi/event/key_handler.rb
114
147
  - lib/hemi/event/loop_machine.rb
115
- - lib/hemi/helpers/self_manager.rb
148
+ - lib/hemi/event/pattern/key.rb
149
+ - lib/hemi/helpers/injections.rb
116
150
  - lib/hemi/helpers/simple.rb
117
151
  - lib/hemi/loader.rb
118
152
  - lib/hemi/render/_manifest.rb
File without changes