-
Notifications
You must be signed in to change notification settings - Fork 2
Asynchronous versus Synchronous Communication
This is an issue which often cause trouble since there are differences in how OSX communicates between Ruby and the WebDialog's JavaScript.
Here is a short snippet to demonstrate the differences:
Ruby
module Example
def self.call_me
path = File.dirname(__FILE__)
dialog = UI::WebDialog.new()
dialog.set_file( File.join(path, 'async.html') )
dialog.show {
puts "WebDialog.show"
dialog.add_action_callback("callme") { |wd, param|
puts "callme(#{param.inspect})"
}
puts ".execute_script:"
dialog.execute_script('call_me();')
} # show
dialog
end
end
HTML
<!DOCTYPE html>
<html>
<head>
<script>
function call_me() {
for (i = 1; i < 6; i++) {
window.location='skp:callme@HelloWorld'+i;
}
}
</script>
</head>
<body>
<code>Example.call_me</code>
</body>
</html>
Under Windows the communication between JavaScript and Ruby is synchronous.
That means when you call a ruby method using window.location = 'skp:rubyMethod'
, the javascript will wait for the ruby method to complete before proceeding with the next javascript statement.
In the above example the result is:
w = Example.call_me
#<UI::WebDialog:0x10a6317c>
WebDialog.show
.execute_script:
callme("HelloWorld1")
callme("HelloWorld2")
callme("HelloWorld3")
callme("HelloWorld4")
callme("HelloWorld5")
Under OSX it just sends the command and continues with the JavaScript without waiting - making it impossible call sequential callbacks to ruby too quickly as they will override each other.
In the above example the result is:
w = Example.call_me
#<UI::WebDialog:0x10a6317c>
WebDialog.show
.execute_script:
callme("HelloWorld5")
The JavaScript side needs to stack out messages going to Ruby and only dispatch the next message after the Ruby side has confirmed the previous message was received.
TODO: Upload sample code for a message pump.
Calling from Ruby to JavaScript using .execute_script
is synchronous on both platforms. The method will wait for the JavaScript to finish before processing next line of ruby.
So you can do stuff like this:
HTML
<input id="sketchupPump" type="hidden">
JavaScript
function add(n1, n2)
{
document.getElementById('sketchupPump').value = n1 + n2;
}
Ruby
dialog.execute_script('add(2,3);')
value = dialog.get_element_value('sketchupPump')
The add JavaScript function will here take both arguments and add them together and put the value into a hidden input field with the id 'sketchupPump'
.
- http://sketchucation.com/forums/viewtopic.php?f=180&t=13394
- http://sketchucation.com/forums/viewtopic.php?f=180&t=22698
- More threads on this topic exists over at SketchUcation.