Asynchronous Input

Occasionally, a SketchUp plugin will need to accept asynchronous input. For example, it might need to accept messages from another process. Let's examine some possible approaches:

  • WebDialog's callback mechanism accepts asynchronous input, but it's not a general-purpose protocol.

    Note: JavaScript code (eg, in a "proxy" dialog) can accept asynchronous input and use a callback to forward the data to a plugin.

  • If SketchUp Ruby had reliable sockets, a solution could be fashioned out of them. Unfortunately, the closest facilities it offers are open_url and post_url.

  • SketchUp Ruby does support file I/O, so reading a static file (or a named pipe) is easy. However, we still have to deal with the asynchronous part.

Scanning the points above, file I/O seems like the least unreasonable approach. Another process can write messages as files whenever it needs to; the plugin can then access the files at its leisure.

In a conventional Ruby environment, there would be many ways to schedule this access (eg, polling, signals, timers). In SketchUp Ruby, setting up a timer is the only practical solution I have found.

Polling

It's certainly possible to sit in a polling loop, waiting for the file to show up. Unfortunately, this keeps the rest of SketchUp from running. So, the Ruby Console stalls, cmd-Q is ignored, etc. It's tempting to put the polling loop in a thread, but then the code doesn't run at all. In short, polling loops are a big lose.

Signals

Ruby has a trap method, which should be able to catch signals. So, if the other process signals SketchUp after writing the file, the plugin should be able to respond to the signal and read the file. Unfortunately, I haven't been able to get signals to work at all.

Timers

This is the only worthwhile method that I have found. Set up a repeating timer and have it run a block which checks for input files, as:

...
@timer_id = UI.start_timer(0.05, true) do
  paths = Dir.glob(patt)
  paths.each {|path| process_input(path) } unless paths.empty?
end
...
UI.stop_timer(@timer_id) if time_to_quit

Warning: UI.start_timer has a bug in pre-8.0 SketchUp; if seconds is given as a floating point value, any fractional component will be discarded. So, for example, 1.99 would become 1 and 0.05 would become 0.


This wiki page is maintained by Rich Morin, an independent consultant specializing in software design, development, and documentation. Please feel free to email comments, inquiries, suggestions, etc!

Topic revision: r4 - 18 Dec 2011, RichMorin
This site is powered by Foswiki Copyright © by the contributing authors. All material on this wiki is the property of the contributing authors.
Foswiki version v2.1.6, Release Foswiki-2.1.6, Plugin API version 2.4
Ideas, requests, problems regarding CFCL Wiki? Send us email