Time based loop limiting

Discussion in 'Ruby' started by Michael Tomer, Sep 8, 2009.

  1. I'm trying to write a loop that will only run a certain number of times
    per second. For instance, in Ruby-Processing, you would use
    "frame_rate(30)" to make the main loop execute no more than 30 evenly
    spaced frames per second. How might I go about doing something like
    that?

    I could try calling sleep with a float that represents the difference
    between the next time I want the loop to run and the current time. That
    seems clunky, though.

    I also thought about using the Observer pattern to have a timer alert
    the simulation each time it should update. That also seems wrong.

    I feel like I must be overlooking something simple. Any ideas?
    --
    Posted via http://www.ruby-forum.com/.
    Michael Tomer, Sep 8, 2009
    #1
    1. Advertising

  2. Michael Tomer

    Paul Smith Guest

    I think your first method is the one I've seen the most in game loops.
    You calculate how long you should sleep based on what time it is now
    and what time you want to wake up, being careful that your last frame
    could have taken over 1/30th of a second.

    You also use the elapsed time in your physics, so the physics engine
    is not tied to your frame rate.

    On Tue, Sep 8, 2009 at 5:38 PM, Michael Tomer<> wrote:
    > I'm trying to write a loop that will only run a certain number of times
    > per second. For instance, in Ruby-Processing, you would use
    > "frame_rate(30)" to make the main loop execute no more than 30 evenly
    > spaced frames per second. How might I go about doing something like
    > that?
    >
    > I could try calling sleep with a float that represents the difference
    > between the next time I want the loop to run and the current time. That
    > seems clunky, though.
    >
    > I also thought about using the Observer pattern to have a timer alert
    > the simulation each time it should update. That also seems wrong.
    >
    > I feel like I must be overlooking something simple. Any ideas?
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >




    --
    Paul Smith
    http://www.nomadicfun.co.uk

    Paul Smith, Sep 8, 2009
    #2
    1. Advertising

  3. Thanks, Paul. I feel better knowing that my first guess was right, even
    though it initially struck me as wrong. I guess that'll teach me to
    second guess myself.
    --
    Posted via http://www.ruby-forum.com/.
    Michael Tomer, Sep 8, 2009
    #3
  4. Hi,

    Am Mittwoch, 09. Sep 2009, 01:38:33 +0900 schrieb Michael Tomer:
    > I'm trying to write a loop that will only run a certain number of times
    > per second.


    The proper way to do this is to call the setitimer(2) function
    that will send SIGALRM periodically to the process. It has been
    discussed a long time ago:

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/130989

    Still I cannot find a setitimer mapping in the Ruby interpreter.
    So I wrote my own:

    http://bertram-scharpf.homelinux.com:8808/doc_root/itimer-1.0/rdoc/index.html

    Bertram


    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Sep 8, 2009
    #4
  5. Michael Tomer

    Guest

    On Tue, Sep 8, 2009 at 6:14 PM, Bertram Scharpf<> w=
    rote:
    > Am Mittwoch, 09. Sep 2009, 01:38:33 +0900 schrieb Michael Tomer:
    >> I'm trying to write a loop that will only run a certain number of times
    >> per second.

    >
    > The proper way to do this is to call the setitimer(2) function
    > that will send SIGALRM periodically to the process. It has been
    > discussed a long time ago:
    >
    > =A0http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/130989
    >
    > Still I cannot find a setitimer mapping in the Ruby interpreter.
    > So I wrote my own:
    >
    > =A0http://bertram-scharpf.homelinux.com:8808/doc_root/itimer-1.0/rdoc/ind=

    ex.html

    Took a shot with FFI:

    require 'ffi'

    module LibC
    extend FFI::Library

    class Timeval < FFI::Struct
    layout :tv_sec, :long,
    :tv_usec, :long
    end

    class Itimerval < FFI::Struct
    layout :it_interval, Timeval,
    :it_value, Timeval
    end

    attach_function :getitimer, [:int, :pointer], :int
    attach_function :setitimer, [:int, :pointer, :pointer], :int
    end


    Signal.trap("SIGALRM") do
    puts "SIGALRM: #{Time.now}"
    end

    tv =3D LibC::Timeval.new
    tv[:tv_sec] =3D 2
    tv[:tv_usec] =3D 0

    puts Time.now
    LibC::setitimer(0, tv, nil)
    sleep 15
    puts Time.now


    #=3D>
    # Wed Sep 09 02:57:18 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:20 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:22 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:24 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:26 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:28 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:30 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:32 +0000 2009
    # SIGALRM: Wed Sep 09 02:57:33 +0000 2009
    # Wed Sep 09 02:57:33 +0000 2009
    , Sep 9, 2009
    #5
  6. On Sep 8, 2:14 pm, Bertram Scharpf <> wrote:
    > Hi,
    >
    > Am Mittwoch, 09. Sep 2009, 01:38:33 +0900 schrieb Michael Tomer:
    >
    > > I'm trying to write a loop that will only run a certain number of times
    > > per second.

    >
    > The proper way to do this is to call the setitimer(2) function
    > that will send SIGALRM periodically to the process. It has been
    > discussed a long time ago:
    >
    > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/130989
    >
    > Still I cannot find a setitimer mapping in the Ruby interpreter.
    > So I wrote my own:
    >
    > http://bertram-scharpf.homelinux.com:8808/doc_root/itimer-1.0/rdoc/in...
    >
    > Bertram
    >
    > --
    > Bertram Scharpf
    > Stuttgart, Deutschland/Germanyhttp://www.bertram-scharpf.de



    How would one make use of this?
    Mike Barsalou, Sep 9, 2009
    #6
  7. Hi,

    Am Mittwoch, 09. Sep 2009, 13:05:27 +0900 schrieb Mike Barsalou:
    > On Sep 8, 2:14 pm, Bertram Scharpf <> wrote:
    > > Am Mittwoch, 09. Sep 2009, 01:38:33 +0900 schrieb Michael Tomer:
    > >
    > > > I'm trying to write a loop that will only run a certain number of times
    > > > per second.

    > >
    > > Still I cannot find a setitimer mapping in the Ruby interpreter.
    > > So I wrote my own:
    > >
    > > http://bertram-scharpf.homelinux.com:8808/doc_root/itimer-1.0/rdoc/in...

    >
    > How would one make use of this?


    Argh. I wonder how that could happen. The link is of course:

    http://bertram-scharpf.homelinux.com:8808/doc_root/itimer-1.0/rdoc/index.html

    Install the gem. You can also use this gem source:

    http://gems.bertram-scharpf.de

    Then (untested)

    require "itimer"
    trap "SIGALRM" do puts Time.now end
    Process.setitimer 2

    This puts out the time every two seconds.

    Bertram


    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Sep 9, 2009
    #7
  8. Michael Tomer, Sep 9, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. flamesrock
    Replies:
    8
    Views:
    449
    Hendrik van Rooyen
    Nov 24, 2006
  2. FMAS

    loop in loop takes too much time

    FMAS, Jun 12, 2004, in forum: Perl Misc
    Replies:
    8
    Views:
    156
    Anno Siegel
    Jun 13, 2004
  3. Mark

    limiting a loop to 100

    Mark, Jan 18, 2006, in forum: Perl Misc
    Replies:
    10
    Views:
    160
    Glenn Jackman
    Jan 19, 2006
  4. deadpickle

    time icrement based loop

    deadpickle, Sep 6, 2006, in forum: Perl Misc
    Replies:
    7
    Views:
    109
    deadpickle
    Sep 7, 2006
  5. Isaac Won
    Replies:
    9
    Views:
    364
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page