Anton Hörnquist wrote:
Alex F. wrote:
It would be good to see some code that we can actually run, and more
information about the app - eg is the refreshing event-driven (the user
doees something, the display changes) or time-driven?
Sure! Find memu.rb attached. It’s a little hack, a monome emulator. You
will need rosc by hans fugal for it to work - hans.fugal.net/src/rosc/.
See www.monome.org for details about the actual device.
Thanks, looks interesting although I have only a hazy idea what it’s
about. Please don’t take this the wrong way, but if you’re sending in
code for advice it’s much preferred that the code is self-contained (as
yours is) and doesn’t have external dependencies that need to be
installed (as yours does). I and others on this list are really happy to
try things out and advise, but it’s too much to expect people to
download, compile and install third-party libs to do that.
Depending on this different things might help - eg preparing drawing in
idle time, only updating voided parts of the canvas, etc
The MemuWindow is refreshed when a user presses or releases one of the
buttons on the virtual device (mouse cursor and
evt_left_down/evt_left_up). The box around the button is thickened.
Also, when certain osc parameters are received, the leds within the
buttons are lit up!
I haven’t tried it out, but from reviewing your script perhaps I can
make a few suggestions:
First, and most important, it looks like you’re repainting the whole 64
buttons when, for any given event, only one has changed state. An
alternate and more efficient approach might be to make each LED a
separate widget, an instance of a class inheriting from Wx::Window. It
knows its state, and draws its own rectangle. The TargetControl class in
the events.rb sample would be an example to look at for this.
You could then layout the buttons using a 8x8 Wx::GridSizer, store them
in a two dimensional array (faster lookup than your buttons.detect
method), then when an event is received, change the state of the
relevant button and call refresh (or update) on it alone. This means
that a much smaller amount of drawing has to be done for each change. It
would also make your handling of left-down and left-up simpler as you
wouldn’t have to test which LED might have been hit.
Second, you might see whether, if each LED has only an on and off state
and these look the same, whether it is faster to cache an image for each
state and do draw_bitmap for each button. It may or may not be faster
than drawing each one with primitives like draw_rectangle.
Third, you could try playing around with, instead of having the server
in a different ruby thread, polling it for messages in evt_idle or
directly in a timer (Wx::Timer.every(20) { server.serve }). Also, is it
possible to have update the UI based only on server messages - ie
evt_left_down only notifies the server of change of state, and the
server notifies back to update the GUI? This design is generally more
scalable, in my experience, than having the state-changing event handler
also update the UI.
There is really no complex drawing going on, just a bunch of rectangles
:), but it’s rather important that the stuff is updated in realtime.
Perhaps Ruby aint the ideal language for this.
Ruby’s certainly slow, and while wxRuby’s a decently fast GUI toolkit,
the SWIG wrapping has significant overhead to each method call. That
said, I used Jay McGavren’s Zyps library, which draws a lot of
primitives from scratch on a timed basis, and was able to get pretty
smooth animation (definitely more than 20fps I think). You might find
those wxruby-users threads in Dec 2007 / Jan 2008 of interest.
hth
alex