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 +4 -4
- data/.circleci/config.yml +79 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +11 -0
- data/.yardopts +1 -0
- data/DEV.md +26 -0
- data/Gemfile.lock +11 -1
- data/README.md +87 -34
- data/hemi.gemspec +2 -0
- data/lib/hemi/engine.rb +67 -5
- data/lib/hemi/event/_manifest.rb +4 -0
- data/lib/hemi/event/event_loop.rb +2 -24
- data/lib/hemi/event/key_handler.rb +30 -0
- data/lib/hemi/event/loop_machine.rb +51 -3
- data/lib/hemi/event/pattern/key.rb +38 -0
- data/lib/hemi/helpers/injections.rb +11 -0
- data/lib/hemi/helpers/simple.rb +3 -2
- data/lib/hemi/loader.rb +3 -3
- data/lib/hemi/render/texture.rb +2 -2
- data/lib/hemi/version.rb +1 -1
- metadata +36 -2
- data/lib/hemi/helpers/self_manager.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f36ce1ac46670d07a633de63c38a9f5b0f5faeb44e35c207647634cc9c34319
|
4
|
+
data.tar.gz: 71a1d9d0f6833d6ec66cd952a0ffc6d538508244d30165bdbb54c8dfd461eb54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/.rubocop.yml
CHANGED
@@ -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
|
data/.yardopts
ADDED
@@ -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
|
+
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hemi (0.0.
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
`
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
+
```
|
data/hemi.gemspec
CHANGED
@@ -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
|
data/lib/hemi/engine.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -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
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
data/lib/hemi/helpers/simple.rb
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
Size
|
2
|
-
Position
|
1
|
+
Size = Struct.new(:width, :height, keyword_init: true)
|
2
|
+
Position = Struct.new(:x, :y, keyword_init: true)
|
3
|
+
KeyPattern = Struct.new(:scancode, :mod)
|
data/lib/hemi/loader.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
8
|
+
relative ? require_relative(file) : require(file)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/hemi/render/texture.rb
CHANGED
@@ -2,7 +2,7 @@ module Hemi::Render
|
|
2
2
|
class Texture
|
3
3
|
ERR__INVALID_POSITION = "Ivalid position.".freeze
|
4
4
|
|
5
|
-
def initialize
|
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
|
69
|
+
raise ArgumentError, ERR__INVALID_POSITION
|
70
70
|
end
|
71
71
|
|
72
72
|
position_obj
|
data/lib/hemi/version.rb
CHANGED
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.
|
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/
|
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
|