mirror of
https://github.com/cyberarm/cyberarm_engine.git
synced 2025-12-15 04:32:35 +00:00
Refactored CyberarmEngine::Stats to track data for last N frames
This commit is contained in:
@@ -8,8 +8,19 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def draw(camera, lights, entities)
|
||||
Stats.frame.start_timing(:opengl_renderer)
|
||||
|
||||
Stats.frame.start_timing(:opengl_model_renderer)
|
||||
@opengl_renderer.render(camera, lights, entities)
|
||||
@bounding_box_renderer.render(entities) if @show_bounding_boxes
|
||||
Stats.frame.end_timing(:opengl_model_renderer)
|
||||
|
||||
if @show_bounding_boxes
|
||||
Stats.frame.start_timing(:opengl_boundingbox_renderer)
|
||||
@bounding_box_renderer.render(entities)
|
||||
Stats.frame.end_timing(:opengl_boundingbox_renderer)
|
||||
end
|
||||
|
||||
Stats.frame.end_timing(:opengl_renderer)
|
||||
end
|
||||
|
||||
def canvas_size_changed
|
||||
|
||||
@@ -1,20 +1,91 @@
|
||||
module CyberarmEngine
|
||||
class Stats
|
||||
@@hash = {
|
||||
gui_recalculations_last_frame: 0
|
||||
}
|
||||
@frames = []
|
||||
@frame_index = -1
|
||||
@max_frame_history = 1024
|
||||
|
||||
def self.get(key)
|
||||
@@hash.dig(key)
|
||||
def self.new_frame
|
||||
if @frames.size < @max_frame_history
|
||||
@frames << Frame.new
|
||||
else
|
||||
@frames[@frame_index] = Frame.new
|
||||
end
|
||||
end
|
||||
|
||||
def self.increment(key, n)
|
||||
@@hash[key] += n
|
||||
def self.frame
|
||||
@frames[@frame_index]
|
||||
end
|
||||
|
||||
def self.clear
|
||||
@@hash.each do |key, _value|
|
||||
@@hash[key] = 0
|
||||
def self.end_frame
|
||||
frame&.complete
|
||||
|
||||
@frame_index += 1
|
||||
@frame_index %= @max_frame_history
|
||||
end
|
||||
|
||||
def self.frames
|
||||
if @frames.size < @max_frame_history
|
||||
@frames
|
||||
else
|
||||
@frames.rotate(@frame_index - (@max_frame_history - (@frames.size - 1)))
|
||||
end
|
||||
end
|
||||
|
||||
def self.frame_index
|
||||
@frame_index
|
||||
end
|
||||
|
||||
def self.max_frame_history
|
||||
@max_frame_history
|
||||
end
|
||||
|
||||
class Frame
|
||||
Timing = Struct.new(:start_time, :end_time, :duration)
|
||||
|
||||
attr_reader :frame_timing, :counters, :timings
|
||||
def initialize
|
||||
@frame_timing = Timing.new(start_time: Gosu.milliseconds, end_time: -1, duration: -1)
|
||||
|
||||
@counters = {
|
||||
gui_recalculations: 0
|
||||
}
|
||||
|
||||
@timings = {}
|
||||
end
|
||||
|
||||
def increment(key, number = 1)
|
||||
@counters[key] ||= 0
|
||||
@counters[key] += number
|
||||
end
|
||||
|
||||
def start_timing(key)
|
||||
raise "key must be a symbol!" unless key.is_a?(Symbol)
|
||||
warn "Only one timing per key per frame. (Timing for #{key.inspect} already exists!)" if @timings[key]
|
||||
|
||||
@timings[key] = Timing.new(start_time: Gosu.milliseconds, end_time: -1, duration: -1)
|
||||
end
|
||||
|
||||
def end_timing(key)
|
||||
timing = @timings[key]
|
||||
|
||||
warn "Timing #{key.inspect} already ended!" if timing.end_time != -1
|
||||
|
||||
timing.end_time = Gosu.milliseconds
|
||||
timing.duration = timing.end_time - timing.start_time
|
||||
end
|
||||
|
||||
def complete
|
||||
@frame_timing.end_time = Gosu.milliseconds
|
||||
@frame_timing.duration = @frame_timing.end_time - @frame_timing.start_time
|
||||
|
||||
# Lock data structures
|
||||
@frame_timing.freeze
|
||||
@counters.freeze
|
||||
@timings.freeze
|
||||
end
|
||||
|
||||
def complete?
|
||||
@frame_timing.duration != -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -118,7 +118,7 @@ module CyberarmEngine
|
||||
|
||||
return unless visible?
|
||||
|
||||
Stats.increment(:gui_recalculations_last_frame, 1)
|
||||
Stats.frame.increment(:gui_recalculations)
|
||||
|
||||
stylize
|
||||
|
||||
@@ -176,7 +176,7 @@ module CyberarmEngine
|
||||
child.recalculate
|
||||
child.reposition # TODO: Implement top,bottom,left,center, and right positioning
|
||||
|
||||
Stats.increment(:gui_recalculations_last_frame, 1)
|
||||
Stats.frame.increment(:gui_recalculations)
|
||||
|
||||
child.element_visible = child.x >= @x - child.width && child.x <= @x + width &&
|
||||
child.y >= @y - child.height && child.y <= @y + height
|
||||
|
||||
@@ -79,16 +79,23 @@ module CyberarmEngine
|
||||
|
||||
def update
|
||||
if @pending_recalculate_request
|
||||
Stats.frame.start_timing(:gui_recalculate)
|
||||
@root_container.recalculate
|
||||
@root_container.recalculate
|
||||
@root_container.recalculate
|
||||
|
||||
@pending_recalculate_request = false
|
||||
|
||||
Stats.frame.end_timing(:gui_recalculate)
|
||||
end
|
||||
|
||||
Stats.frame.start_timing(:gui_element_recalculate_requests)
|
||||
|
||||
@pending_element_recalculate_requests.each(&:recalculate)
|
||||
@pending_element_recalculate_requests.clear
|
||||
|
||||
Stats.frame.end_timing(:gui_element_recalculate_requests)
|
||||
|
||||
if @pending_focus_request
|
||||
@pending_focus_request = false
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@ module CyberarmEngine
|
||||
|
||||
attr_accessor :show_cursor
|
||||
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)
|
||||
@@ -37,6 +37,7 @@ module CyberarmEngine
|
||||
|
||||
@last_frame_time = Gosu.milliseconds - 1
|
||||
@current_frame_time = Gosu.milliseconds
|
||||
@delta_time = @last_frame_time
|
||||
self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.user_languages.join(', ')}"
|
||||
|
||||
@states = []
|
||||
@@ -50,16 +51,32 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def draw
|
||||
Stats.frame.start_timing(:draw)
|
||||
|
||||
current_state&.draw
|
||||
|
||||
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?
|
||||
|
||||
Reference in New Issue
Block a user