cyberarm_engine 0.25.0 → 0.30.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.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/Gemfile.lock +37 -25
  7. data/LICENSE.txt +21 -21
  8. data/README.md +74 -74
  9. data/Rakefile +10 -10
  10. data/assets/shaders/fragment/g_buffer.glsl +30 -30
  11. data/assets/shaders/fragment/lighting.glsl +115 -115
  12. data/assets/shaders/include/light_struct.glsl +11 -11
  13. data/assets/shaders/include/material_struct.glsl +16 -16
  14. data/assets/shaders/vertex/g_buffer.glsl +28 -28
  15. data/assets/shaders/vertex/lighting.glsl +24 -24
  16. data/assets/textures/ui/circle.png +0 -0
  17. data/assets/textures/ui/circle_small.png +0 -0
  18. data/assets/textures/ui/rounded.png +0 -0
  19. data/assets/textures/ui/rounded_bottom.png +0 -0
  20. data/assets/textures/ui/rounded_left.png +0 -0
  21. data/assets/textures/ui/rounded_left_bottom.png +0 -0
  22. data/assets/textures/ui/rounded_left_top.png +0 -0
  23. data/assets/textures/ui/rounded_right.png +0 -0
  24. data/assets/textures/ui/rounded_right_bottom.png +0 -0
  25. data/assets/textures/ui/rounded_right_top.png +0 -0
  26. data/assets/textures/ui/rounded_small.png +0 -0
  27. data/assets/textures/ui/rounded_tiny.png +0 -0
  28. data/assets/textures/ui/rounded_top.png +0 -0
  29. data/assets/textures/ui/square.png +0 -0
  30. data/bin/console +14 -14
  31. data/bin/setup +8 -8
  32. data/cyberarm_engine.gemspec +35 -36
  33. data/lib/cyberarm_engine/animator.rb +219 -219
  34. data/lib/cyberarm_engine/background.rb +156 -158
  35. data/lib/cyberarm_engine/background_image.rb +93 -93
  36. data/lib/cyberarm_engine/background_nine_slice.rb +182 -142
  37. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  38. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  39. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  40. data/lib/cyberarm_engine/cache.rb +4 -4
  41. data/lib/cyberarm_engine/common.rb +133 -131
  42. data/lib/cyberarm_engine/config_file.rb +46 -46
  43. data/lib/cyberarm_engine/console/command.rb +157 -157
  44. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  45. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  46. data/lib/cyberarm_engine/console.rb +248 -248
  47. data/lib/cyberarm_engine/event_bus.rb +39 -0
  48. data/lib/cyberarm_engine/game_object.rb +244 -244
  49. data/lib/cyberarm_engine/game_state.rb +134 -124
  50. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +111 -111
  51. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  52. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  53. data/lib/cyberarm_engine/model/material.rb +21 -21
  54. data/lib/cyberarm_engine/model/mesh.rb +131 -131
  55. data/lib/cyberarm_engine/model/parser.rb +74 -74
  56. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  57. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  58. data/lib/cyberarm_engine/model.rb +216 -216
  59. data/lib/cyberarm_engine/model_cache.rb +31 -31
  60. data/lib/cyberarm_engine/notification.rb +82 -82
  61. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  62. data/lib/cyberarm_engine/opengl/light.rb +52 -52
  63. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  64. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -41
  65. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  66. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -167
  67. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -307
  68. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  69. data/lib/cyberarm_engine/opengl/shader.rb +408 -408
  70. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  71. data/lib/cyberarm_engine/opengl.rb +53 -53
  72. data/lib/cyberarm_engine/pathfinding/graph.rb +64 -0
  73. data/lib/cyberarm_engine/pathfinding/graph_search.rb +6 -0
  74. data/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb +6 -0
  75. data/lib/cyberarm_engine/pathfinding/graph_searches/breadth_first_search.rb +27 -0
  76. data/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb +6 -0
  77. data/lib/cyberarm_engine/pathfinding/graphs/grid.rb +52 -0
  78. data/lib/cyberarm_engine/ray.rb +56 -56
  79. data/lib/cyberarm_engine/result.rb +19 -0
  80. data/lib/cyberarm_engine/stats.rb +200 -200
  81. data/lib/cyberarm_engine/text.rb +288 -260
  82. data/lib/cyberarm_engine/timer.rb +27 -23
  83. data/lib/cyberarm_engine/transform.rb +296 -296
  84. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -126
  85. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -55
  86. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -29
  87. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  88. data/lib/cyberarm_engine/ui/dialog.rb +24 -0
  89. data/lib/cyberarm_engine/ui/dsl.rb +170 -142
  90. data/lib/cyberarm_engine/ui/element.rb +664 -662
  91. data/lib/cyberarm_engine/ui/elements/button.rb +99 -100
  92. data/lib/cyberarm_engine/ui/elements/check_box.rb +58 -54
  93. data/lib/cyberarm_engine/ui/elements/container.rb +413 -407
  94. data/lib/cyberarm_engine/ui/elements/edit_box.rb +200 -179
  95. data/lib/cyberarm_engine/ui/elements/edit_line.rb +299 -297
  96. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  97. data/lib/cyberarm_engine/ui/elements/image.rb +78 -72
  98. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  99. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  100. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  101. data/lib/cyberarm_engine/ui/elements/progress.rb +95 -93
  102. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  103. data/lib/cyberarm_engine/ui/elements/slider.rb +111 -107
  104. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  105. data/lib/cyberarm_engine/ui/elements/text_block.rb +236 -222
  106. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +71 -67
  107. data/lib/cyberarm_engine/ui/elements/widget.rb +45 -0
  108. data/lib/cyberarm_engine/ui/event.rb +54 -54
  109. data/lib/cyberarm_engine/ui/gui_state.rb +402 -326
  110. data/lib/cyberarm_engine/ui/page.rb +39 -0
  111. data/lib/cyberarm_engine/ui/style.rb +94 -61
  112. data/lib/cyberarm_engine/ui/theme.rb +237 -225
  113. data/lib/cyberarm_engine/vector.rb +312 -312
  114. data/lib/cyberarm_engine/version.rb +4 -4
  115. data/lib/cyberarm_engine/window.rb +234 -195
  116. data/lib/cyberarm_engine.rb +88 -76
  117. data/mrbgem.rake +29 -29
  118. metadata +30 -5
@@ -1,200 +1,200 @@
1
- module CyberarmEngine
2
- class Stats
3
- @frames = []
4
- @frame_index = -1
5
- @max_frame_history = 1024
6
-
7
- def self.new_frame
8
- if @frames.size < @max_frame_history
9
- @frames << Frame.new
10
- else
11
- @frames[@frame_index] = Frame.new
12
- end
13
- end
14
-
15
- def self.frame
16
- @frames[@frame_index]
17
- end
18
-
19
- def self.end_frame
20
- frame&.complete
21
-
22
- @frame_index += 1
23
- @frame_index %= @max_frame_history
24
- end
25
-
26
- def self.frames
27
- if @frames.size < @max_frame_history
28
- @frames
29
- else
30
- @frames.rotate(@frame_index - (@max_frame_history - (@frames.size - 1)))
31
- end
32
- end
33
-
34
- def self.frame_index
35
- @frame_index
36
- end
37
-
38
- def self.max_frame_history
39
- @max_frame_history
40
- end
41
-
42
- class Frame
43
- Timing = Struct.new(:start_time, :end_time, :duration)
44
-
45
- attr_reader :frame_timing, :counters, :timings, :multitimings
46
- def initialize
47
- @frame_timing = Timing.new(Gosu.milliseconds, -1, -1)
48
- @attempted_multitiming = false
49
-
50
- @counters = {
51
- gui_recalculations: 0
52
- }
53
-
54
- @timings = {}
55
- @multitimings = {}
56
- end
57
-
58
- def increment(key, number = 1)
59
- @counters[key] ||= 0
60
- @counters[key] += number
61
- end
62
-
63
- def start_timing(key)
64
- raise "key must be a symbol!" unless key.is_a?(Symbol)
65
- if @timings[key]
66
- # FIXME: Make it not spammy...
67
- # warn "Only one timing per key per frame. (Timing for #{key.inspect} already exists!)"
68
- @attempted_multitiming = true
69
- @multitimings[key] = true
70
-
71
- return
72
- end
73
-
74
- @timings[key] = Timing.new(Gosu.milliseconds, -1, -1)
75
- end
76
-
77
- def end_timing(key)
78
- timing = @timings[key]
79
-
80
- # FIXME: Make it not spammy...
81
- # warn "Timing #{key.inspect} already ended!" if timing.end_time != -1
82
-
83
- timing.end_time = Gosu.milliseconds
84
- timing.duration = timing.end_time - timing.start_time
85
- end
86
-
87
- def complete
88
- @frame_timing.end_time = Gosu.milliseconds
89
- @frame_timing.duration = @frame_timing.end_time - @frame_timing.start_time
90
-
91
- # Lock data structures
92
- @frame_timing.freeze
93
- @counters.freeze
94
- @timings.freeze
95
- @multitimings.freeze
96
- end
97
-
98
- def complete?
99
- @frame_timing.duration != -1
100
- end
101
-
102
- def attempted_multitiming?
103
- @attempted_multitiming
104
- end
105
- end
106
-
107
- class StatsPlotter
108
- attr_reader :position
109
-
110
- def initialize(x, y, z = Float::INFINITY, width = 128, height = 128)
111
- @position = Vector.new(x, y, z)
112
- @width = width
113
- @height = height
114
-
115
- @padding = 2
116
- @text_size = 16
117
-
118
- @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true, static: true)
119
- @avg_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding + @height / 2 - @text_size / 2, z: z, size: @text_size, border: true, static: true)
120
- @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true, static: true)
121
-
122
- @data_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true, static: true)
123
-
124
- @frame_stats = []
125
- @graphs = {
126
- frame_timings: []
127
- }
128
- end
129
-
130
- def calculate_graphs
131
- calculate_frame_timings_graph
132
- end
133
-
134
- def calculate_frame_timings_graph
135
- @graphs[:frame_timings].clear
136
-
137
- samples = @width - @padding
138
- nodes = Array.new(samples.ceil) { [] }
139
-
140
- slice = 0
141
- @frame_stats.each_slice((CyberarmEngine::Stats.max_frame_history / samples.to_f).ceil) do |bucket|
142
- bucket.each do |frame|
143
- nodes[slice] << frame.frame_timing.duration
144
- end
145
-
146
- slice += 1
147
- end
148
-
149
- max_node = CyberarmEngine::Stats.frames.select(&:complete?).map { |f| f.frame_timing.duration }.max
150
- scale = 1
151
- scale = (@height - @padding).to_f / max_node
152
- scale = 1 if scale > 1
153
-
154
- nodes.each_with_index do |cluster, i|
155
- break if cluster.empty?
156
-
157
- @graphs[:frame_timings] << CyberarmEngine::Vector.new(@position.x + @padding + 1 * i, (@position.y + @height - @padding) - cluster.max * scale)
158
- end
159
- end
160
-
161
- def draw
162
- @frame_stats = CyberarmEngine::Stats.frames.select(&:complete?)
163
- return if @frame_stats.empty?
164
-
165
- calculate_graphs
166
-
167
- @max_timing_label.text = "<c=d44>Max:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
168
- @avg_timing_label.text = "<c=f80>Avg:</c> #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
169
- @min_timing_label.text = "<c=0d0>Min:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
170
-
171
- Gosu.draw_rect(@position.x, @position.y, @width, @height, 0xaa_222222, @position.z)
172
- Gosu.draw_rect(@position.x + @padding, @position.y + @padding, @width - @padding * 2, @height - @padding * 2, 0xaa_222222, @position.z)
173
-
174
- draw_graphs
175
-
176
- @max_timing_label.draw
177
- @avg_timing_label.draw
178
- @min_timing_label.draw
179
-
180
- # TODO: Make this optional
181
- draw_timings_and_counters
182
- end
183
-
184
- def draw_graphs
185
- Gosu.draw_path(@graphs[:frame_timings], Gosu::Color::WHITE, Float::INFINITY)
186
- end
187
-
188
- def draw_timings_and_counters
189
- frame = @frame_stats.last
190
-
191
- @data_label.text = "<c=f8f>COUNTERS:</c>\n#{frame.counters.map { |t, v| "#{t}: #{v}" }.join("\n")}\n\n"\
192
- "<c=f80>TIMINGS:</c>\n#{frame.attempted_multitiming? ? "<c=d00>Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }</c>\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
193
- Gosu.draw_rect(@data_label.x - @padding, @data_label.y - @padding, @data_label.width + @padding * 2, @data_label.height + @padding * 2, 0xdd_222222, @position.z)
194
- @data_label.draw
195
-
196
- # puts "Recalcs this frame: #{frame.counters[:gui_recalculations]} [dt: #{(CyberarmEngine::Window.dt * 1000).round} ms]" if frame.counters[:gui_recalculations] && frame.counters[:gui_recalculations].positive?
197
- end
198
- end
199
- end
200
- end
1
+ module CyberarmEngine
2
+ class Stats
3
+ @frames = []
4
+ @frame_index = -1
5
+ @max_frame_history = 1024
6
+
7
+ def self.new_frame
8
+ if @frames.size < @max_frame_history
9
+ @frames << Frame.new
10
+ else
11
+ @frames[@frame_index] = Frame.new
12
+ end
13
+ end
14
+
15
+ def self.frame
16
+ @frames[@frame_index]
17
+ end
18
+
19
+ def self.end_frame
20
+ frame&.complete
21
+
22
+ @frame_index += 1
23
+ @frame_index %= @max_frame_history
24
+ end
25
+
26
+ def self.frames
27
+ if @frames.size < @max_frame_history
28
+ @frames
29
+ else
30
+ @frames.rotate(@frame_index - (@max_frame_history - (@frames.size - 1)))
31
+ end
32
+ end
33
+
34
+ def self.frame_index
35
+ @frame_index
36
+ end
37
+
38
+ def self.max_frame_history
39
+ @max_frame_history
40
+ end
41
+
42
+ class Frame
43
+ Timing = Struct.new(:start_time, :end_time, :duration)
44
+
45
+ attr_reader :frame_timing, :counters, :timings, :multitimings
46
+ def initialize
47
+ @frame_timing = Timing.new(Gosu.milliseconds, -1, -1)
48
+ @attempted_multitiming = false
49
+
50
+ @counters = {
51
+ gui_recalculations: 0
52
+ }
53
+
54
+ @timings = {}
55
+ @multitimings = {}
56
+ end
57
+
58
+ def increment(key, number = 1)
59
+ @counters[key] ||= 0
60
+ @counters[key] += number
61
+ end
62
+
63
+ def start_timing(key)
64
+ raise "key must be a symbol!" unless key.is_a?(Symbol)
65
+ if @timings[key]
66
+ # FIXME: Make it not spammy...
67
+ # warn "Only one timing per key per frame. (Timing for #{key.inspect} already exists!)"
68
+ @attempted_multitiming = true
69
+ @multitimings[key] = true
70
+
71
+ return
72
+ end
73
+
74
+ @timings[key] = Timing.new(Gosu.milliseconds, -1, -1)
75
+ end
76
+
77
+ def end_timing(key)
78
+ timing = @timings[key]
79
+
80
+ # FIXME: Make it not spammy...
81
+ # warn "Timing #{key.inspect} already ended!" if timing.end_time != -1
82
+
83
+ timing.end_time = Gosu.milliseconds
84
+ timing.duration = timing.end_time - timing.start_time
85
+ end
86
+
87
+ def complete
88
+ @frame_timing.end_time = Gosu.milliseconds
89
+ @frame_timing.duration = @frame_timing.end_time - @frame_timing.start_time
90
+
91
+ # Lock data structures
92
+ @frame_timing.freeze
93
+ @counters.freeze
94
+ @timings.freeze
95
+ @multitimings.freeze
96
+ end
97
+
98
+ def complete?
99
+ @frame_timing.duration != -1
100
+ end
101
+
102
+ def attempted_multitiming?
103
+ @attempted_multitiming
104
+ end
105
+ end
106
+
107
+ class StatsPlotter
108
+ attr_reader :position
109
+
110
+ def initialize(x, y, z = Float::INFINITY, width = 128, height = 128)
111
+ @position = Vector.new(x, y, z)
112
+ @width = width
113
+ @height = height
114
+
115
+ @padding = 2
116
+ @text_size = 16
117
+
118
+ @max_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding, z: z, size: @text_size, border: true, static: true)
119
+ @avg_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @padding + @height / 2 - @text_size / 2, z: z, size: @text_size, border: true, static: true)
120
+ @min_timing_label = CyberarmEngine::Text.new("", x: x + @padding + 1, y: y + @height - (@text_size + @padding / 2), z: z, size: @text_size, border: true, static: true)
121
+
122
+ @data_label = CyberarmEngine::Text.new("", x: x + @padding + @width + @padding, y: y + @padding, z: z, size: @text_size, border: true, static: true)
123
+
124
+ @frame_stats = []
125
+ @graphs = {
126
+ frame_timings: []
127
+ }
128
+ end
129
+
130
+ def calculate_graphs
131
+ calculate_frame_timings_graph
132
+ end
133
+
134
+ def calculate_frame_timings_graph
135
+ @graphs[:frame_timings].clear
136
+
137
+ samples = @width - @padding
138
+ nodes = Array.new(samples.ceil) { [] }
139
+
140
+ slice = 0
141
+ @frame_stats.each_slice((CyberarmEngine::Stats.max_frame_history / samples.to_f).ceil) do |bucket|
142
+ bucket.each do |frame|
143
+ nodes[slice] << frame.frame_timing.duration
144
+ end
145
+
146
+ slice += 1
147
+ end
148
+
149
+ max_node = CyberarmEngine::Stats.frames.select(&:complete?).map { |f| f.frame_timing.duration }.max
150
+ scale = 1
151
+ scale = (@height - @padding).to_f / max_node
152
+ scale = 1 if scale > 1
153
+
154
+ nodes.each_with_index do |cluster, i|
155
+ break if cluster.empty?
156
+
157
+ @graphs[:frame_timings] << CyberarmEngine::Vector.new(@position.x + @padding + 1 * i, (@position.y + @height - @padding) - cluster.max * scale)
158
+ end
159
+ end
160
+
161
+ def draw
162
+ @frame_stats = CyberarmEngine::Stats.frames.select(&:complete?)
163
+ return if @frame_stats.empty?
164
+
165
+ calculate_graphs
166
+
167
+ @max_timing_label.text = "<c=d44>Max:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.max.to_s.rjust(3, " ")}ms"
168
+ @avg_timing_label.text = "<c=f80>Avg:</c> #{(@frame_stats.map { |f| f.frame_timing.duration }.sum / @frame_stats.size).to_s.rjust(3, " ")}ms"
169
+ @min_timing_label.text = "<c=0d0>Min:</c> #{@frame_stats.map { |f| f.frame_timing.duration }.min.to_s.rjust(3, " ")}ms"
170
+
171
+ Gosu.draw_rect(@position.x, @position.y, @width, @height, 0xaa_222222, @position.z)
172
+ Gosu.draw_rect(@position.x + @padding, @position.y + @padding, @width - @padding * 2, @height - @padding * 2, 0xaa_222222, @position.z)
173
+
174
+ draw_graphs
175
+
176
+ @max_timing_label.draw
177
+ @avg_timing_label.draw
178
+ @min_timing_label.draw
179
+
180
+ # TODO: Make this optional
181
+ draw_timings_and_counters
182
+ end
183
+
184
+ def draw_graphs
185
+ Gosu.draw_path(@graphs[:frame_timings], Gosu::Color::WHITE, Float::INFINITY)
186
+ end
187
+
188
+ def draw_timings_and_counters
189
+ frame = @frame_stats.last
190
+
191
+ @data_label.text = "<c=f8f>COUNTERS:</c>\n#{frame.counters.map { |t, v| "#{t}: #{v}" }.join("\n")}\n\n"\
192
+ "<c=f80>TIMINGS:</c>\n#{frame.attempted_multitiming? ? "<c=d00>Attempted Multitiming!\nTimings may be inaccurate for:\n#{frame.multitimings.map { |m, _| m}.join("\n") }</c>\n\n" : ''}#{frame.timings.map { |t, v| "#{t}: #{v.duration}ms" }.join("\n")}"
193
+ Gosu.draw_rect(@data_label.x - @padding, @data_label.y - @padding, @data_label.width + @padding * 2, @data_label.height + @padding * 2, 0xdd_222222, @position.z)
194
+ @data_label.draw
195
+
196
+ # puts "Recalcs this frame: #{frame.counters[:gui_recalculations]} [dt: #{(CyberarmEngine::Window.dt * 1000).round} ms]" if frame.counters[:gui_recalculations] && frame.counters[:gui_recalculations].positive?
197
+ end
198
+ end
199
+ end
200
+ end