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