# FPSTimerLight
# http://www.kmc.gr.jp/~ohai/rubysdl_intro.html

require 'sdl'


class FPSTimerLight
  N = 12
  DT = 2
  FPS_COUNT = 10
  
  attr_reader :fps
  attr_reader :real_fps
  # +fps+ is the number of frames per second that you want to keep,
  # +accurary+ is the accurary of sleep/SDL.delay in milisecond
  def initialize(fps = 60, accurary = 10, skip_limit = 15)
    @fps = fps
    @accurary = accurary * N
    @skip_limit = 15
    @one_frame = 1000*N / fps
    @delay = accurary - 2
  end
  
  # reset timer, you should call just before starting loop
  def reset
    @old = get_ticks
    @skip = 0
    
    # for calculate real fps
    @frame_count = 0
    @fps_old = @old
    @real_fps = @fps
  end

  def wait_frame
    now = get_ticks
    nxt = @old + @one_frame
    if nxt > now || @skip > @skip_limit
      yield
      @skip = 0
      wait(nxt)
      @old = nxt
    else
      @skip += 1
      @old = get_ticks
    end

    calc_real_fps
  end

  private
  def get_ticks
    SDL.getTicks * N
  end
  
  def wait(nxt)
    while nxt > get_ticks + @accurary
      SDL.delay(@delay) 
    end

    while nxt > get_ticks
      # busy loop, do nothing
    end
  end

  def calc_real_fps
    @frame_count += 1
    if @frame_count >= FPS_COUNT
      @frame_count = 0
      now = get_ticks
      @real_fps = (N*1000*FPS_COUNT)/(now - @fps_old)
      @fps_old = now
    end
  end
end
