lib/cyberarm_engine/window.rb in cyberarm_engine-0.23.0 vs lib/cyberarm_engine/window.rb in cyberarm_engine-0.24.0
- old
+ new
@@ -4,20 +4,20 @@
IMAGES = {}
SAMPLES = {}
SONGS = {}
- attr_accessor :show_cursor
+ attr_accessor :show_cursor, :show_stats_plotter
attr_writer :exit_on_opengl_error
- attr_reader :last_frame_time, :states
+ attr_reader :last_frame_time, :delta_time, :states
def self.now
Gosu.milliseconds
end
def self.dt
- instance.last_frame_time / 1000.0
+ instance.dt
end
def self.instance=(window)
raise ArgumentError, "Expected window to be a subclass of CyberarmEngine::Window, got: #{window.class}" unless window.is_a?(CyberarmEngine::Window)
@@ -29,36 +29,61 @@
end
def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
@show_cursor = false
@has_focus = false
+ @show_stats_plotter = false
super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable, borderless: borderless)
Window.instance = self
@last_frame_time = Gosu.milliseconds - 1
@current_frame_time = Gosu.milliseconds
- self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.language}"
+ @delta_time = @last_frame_time
+ self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.user_languages.join(', ')}"
@states = []
@exit_on_opengl_error = false
preload_default_shaders if respond_to?(:preload_default_shaders)
+ @stats_plotter = Stats::StatsPlotter.new(2, 28) # FIXME: Make positioning easy
- setup if defined?(setup)
+ setup
end
+ def setup
+ end
+
def draw
+ Stats.frame.start_timing(:draw)
+
current_state&.draw
+ Stats.frame.start_timing(:engine_stats_renderer)
+ @stats_plotter&.draw if @show_stats_plotter
+ Stats.frame.end_timing(:engine_stats_renderer)
+
+ Stats.frame.end_timing(:draw)
+ Stats.frame.start_timing(:interframe_sleep)
end
def update
- Stats.clear
+ # Gosu calls update() then (optionally) draw(),
+ # so always end last frame and start next frame when update() is called.
+ Stats.frame&.end_timing(:interframe_sleep)
+ Stats.end_frame
- current_state&.update
+ Stats.new_frame
+ @delta_time = (Gosu.milliseconds - @current_frame_time) * 0.001
+
@last_frame_time = Gosu.milliseconds - @current_frame_time
@current_frame_time = Gosu.milliseconds
+
+ Stats.frame.start_timing(:update)
+ current_state&.update
+ Stats.frame.end_timing(:update)
+
+ Stats.frame.start_timing(:interframe_sleep) unless needs_redraw?
end
def needs_cursor?
@show_cursor
end
@@ -118,11 +143,11 @@
end
def push_state(klass, options = {})
options = { setup: true }.merge(options)
- if klass.instance_of?(klass.class) && defined?(klass.options)
+ if klass.instance_of?(klass.class) && klass.respond_to?(:options)
@states << klass
klass.setup if options[:setup]
klass.post_setup if options[:setup]
else
@states << klass.new(options) if child_of?(klass, GameState)
@@ -131,9 +156,11 @@
current_state.post_setup if current_state.instance_of?(klass) && options[:setup]
end
end
private def child_of?(input, klass)
+ return false unless input
+
input.ancestors.detect { |c| c == klass }
end
def current_state
@states.last