[wxruby-users] No joy from Wx::App.dispatch, Wx::App.yield...

Jay McGavren jay at mcgavren.com
Sat Jan 19 18:27:31 EST 2008


OK, back with another iteration of the same problem...  I updated my
game demo, but the Close button failed to respond when (and only when)
there were too many objects onscreen.  The drawing loop is probably
lasting longer than my drawing timer interval.  I was able to
reproduce the problem in my (probably familiar by now) test script
just by boosting the number of lines drawn per frame.

After each frame, I tried Wx::App.dispatch, Wx::App.dispatch while
Wx::App.pending, and Wx::App.yield, all without effect.  The
(commented out) statements are in the code below.

I'm running Ruby 1.8.6 on Windows with wxRuby 1.9.2 (1.9.3 and 1.9.4
both give me errors).

If wxRuby is busy drawing when the close button is clicked, is the
window close event getting lost altogether, or merely going unhandled?
 If it's just going unhandled, how can I find it and process it?  Help
is, as always, most appreciated!

-Jay McGavren
http://jay.mcgavren.com/zyps


  require 'rubygems'
  require 'wx'

  class MyApp < Wx::App

    def on_init

      #Containing frame.
      frame = Wx::Frame.new(nil, :size => [300, 300])
      frame.show

      #Offscreen drawing buffer.
      buffer = Wx::Bitmap.new(300, 300)

      #Displays drawing.
      window = Wx::Window.new(frame, :size => [300, 300])
      window.evt_paint do |event|
        update_window(window, buffer)
      end

      #Initialize drawing loop counter.
      @i = 0

      #Animate periodically.
      timer_id = Wx::ID_HIGHEST + 1
      t = Wx::Timer.new(self, timer_id)
      evt_timer(timer_id) do
        animate(window, buffer)
        #No effect.
        #self.dispatch
        #No effect.
        #self.dispatch while self.pending
        #No effect.
        #self.yield
      end
      t.start(33)

    end

    def animate(window, buffer)
      green_pen = Wx::Pen.new(Wx::Colour.new(128, 255, 128), 3)
      black_pen = Wx::Pen.new(Wx::Colour.new(0, 0, 0), 0)
      buffer.draw do |surface|
        #Clear screen.
        surface.pen = black_pen
        surface.brush = Wx::BLACK_BRUSH
        surface.draw_rectangle(0, 0, 300, 300)
        #Draw lines.
        surface.pen = green_pen
        surface.pen.cap = Wx::CAP_ROUND
        30000.times do |j|
          x = @i + j
          surface.draw_line(x, 0, x+100, 100)
        end
      end
      #Update screen.
      update_window(window, buffer)
      @i += 1
      @i = 0 if @i > 300
    end

    def update_window(window, buffer)
      window.paint do |dc|
        #Copy the buffer to the viewable window.
        dc.draw_bitmap(buffer, 0, 0, false)
      end
    end

  end

  app = MyApp.new
  app.main_loop


More information about the wxruby-users mailing list