Javascript event loop/message pump for Google Sketchup plugin - javascript

I'm working on a plugin for Google Sketchup that is written using the Ruby API. Within this API is a WebDialog class which one can use to render HTML and move data between the WebDialog and the Ruby side of the plugin code. I'm using this class to build a UI for my plugin.
Data is sent from the WebDialog to the Ruby side asynchronously. Due to subpar documentation I was not initially aware of this and now that I'm a ways into my plugin it's began to create some problems for me. Specifically: when multiple successive calls are made from the WebDialog to the Ruby side, only the last call is executed. So, I clearly need to devise some sort of "bridge" which will prevent calls from the WebDialog to the Ruby side from getting lost -- which is, I think, basically an "event loop" or "message pump" system.
My problem is that I haven't a good idea of how to do this. What I'm hoping is that someone can provide me with some sort of resource that lays out a framework for how such a system should work -- what sort of checks are needed, the sequence in which they're performed, etc. I know this can be a terrifically complex task, but I only need something basic: basically, a way of making Javascript stop when I send a request to Ruby, not proceeding until I get the data I need back, and dealing with any potential errors that may crop up.
Any help would be very much appreciated!

I've spent a great deal of time with the WebDialog class. I planned to write such a pump, but I found that I could do it differently with more reliable results.
( My WebDialog findings: http://forums.sketchucation.com/viewtopic.php?f=180&t=23445 )
Alternative Method
SketchUp > JavaScript
My alternative method was that I didn't try to push data from the WebDialog to Ruby. But instead had Ruby pump the WebDialog because Webdialog.execute_script is synchronous.
I send a command to the WebDialog with a query. The Javascript then processes this and put the result into a hidden INPUT element which I then use ´WebDialog.get_element_value` to fetch the content of.
All of this I wrapped up into a wrapper method the will process the return value and convert it into appropriate Ruby objects. http://www.thomthom.net/software/sketchup/tt_lib2/doc/TT/GUI/Window.html#call_script-instance_method
The outline is:
Make a call ( .execute_script ) to clear the hidden INPUT element
Make the actual call which JS will process and put the return value into the hidden INPUT
Use .get_element_value to fetch the hidden INPUT value
All this is synchronous.
Javascript Pump
Javascript > SketchUp
If you really need to pump information from JS, then I think you need to do something like this:
JS: push messages into a message queue
JS: Send a message to SU that there is messages
SU: When the callback notifies about new messages, query JS for the next message and continue until there are no more messages. This should work as it'd be similar method as described earlier.
The concept would be to store up your messages and then hand over control to the SketchUp side which can pump it synchronously.
(Untested theory.)

Related

Javascript UI rendering techniques

I'm building an AJAX 'web application' where, once the UI is loaded, calls to the server are for 'data exchange' only. As a result a lot of UI manipulation will be done using Javascript. Lets say the Javascript retrieves some data consisting of multiple fields from the server using AJAX. To put it on the screen I can think of multiple approaches -
Call methods like createElement() and appendChild() to build an interface to display the retrieved data
Populate the .innerHTML for the container element then for every data field lookup a container in the newly added HTML and populate it. The data that goes into .innerHTML could be stored in a JS variable or contained in a hidden node, or fetched using a seperate AJAX call.
Have the interface stored in a hidden node. Clone it (using cloneNode()) and put it in the actual container (using appendChild()) and then populate it with fields like in method 2.
and there are probably more ways.
Could you share pros, cons and possible gotachas in these approaches from cross-browser support, performance and coding complexity point of views?
Somewhat related question: Is client-side UI rendering via Javascript a good idea?
Thanks.
ok, let's start off:
Use toolkits
First you would want to invest time learning a JS toolkit. While others suggest native JS is good (which it really is), but you would not want to waste time on building apps that don't work cross-browser or spend too much time testing it. People in the community have invested their time in doing that for you. Show some love to the open community and use their product. I personally use jQuery, but there are others like Dojo and YUI.
But still use native JS whenever possible. It's still faster.
Structure your code
After a toolkit, you need some structure. BackboneJS will take care of that. It's to structure your code so that your code is reusable and well.. won't end up as spaghetti on your screen. Other tools like RequireJS are also useful for those scripts that need other scripts to run.
Templates: From strings to elements
Then, with that, you now have a toolkit but you still need to build the interface. It's better if you use a templating engine like Mustache or Handlebars. These render templates for your UI from strings (yes, plain strings of HTML). Just send over your template data from the server, store it in your app (in a variable or browser localstorage), and reuse it as necessary. No need for cloning hidden nodes!
Don't touch that DOM
As for approaching the DOM, you should touch the DOM only when necessary. DOM is slow, manipulating it is he** slow! that means you should avoid unnecessary animations, avoid excessive element append and remove, as well as changing styles. Check this article about avoiding too much reflow and repaints. Face it, the user won't event notice the round corners of your boxes, or the gradient background and don't even care if you did a slide animation or a fade-out. What they want is to get the job done and not adore the fireworks display.
Also, remove anything that isn't on screen. You might end up having 20% content on screen, and 80% off screen - a waste of memory.
Cache: fetch once, store, use infinitely for later
Now, your app is getting heavy and you want to shave off some HTTP requests. You can do this by caching. I usually use caching mostly on the templates so that every new UI, you don't need to load again from the server. You can do this by storing stuff in an object. you can go a little further and use the browser's localStorage when available.
Caching isn't all for the network. Let's say you have some complex calculations you want to use later, or some text from an unfinished form, use the cache for that too.
Avoid HTTP requests (or at least lighten them up)
While lightening up your app by using AJAX, you will inevitably be tempted to use AJAX just about anywhere - don't abuse it. Often times i see people who aggressively poll the server (every half-second or less). This not only strains the server (too many requests), but also the browser (wasting processing cycles) and the network (bandwidth). There are several practices done these days to avoid added HTTP requests:
Image Spriting - The art of placing a lot of images into one image and using background-position to change the image. Surely beats 100 individual HTTP requests
Use JSON for textual data - AJAX was meant to use XML.. then came along JSON that was a fat-free, platform-independent format of strucured data.
Do not return HTML-formatted data - With exemption of templates, which are HTML strings, you should never return HTML-formatted data over the wire. Have JS do JSON+templates on the client-side instead.
I'm building a similar app (Lightweight CMS)
In my view the approach you take will be dependent on the complexity of data that you are sending from the server > manipulating on the client side > and returning back to the server and db.
The cms that I'm working on is very basic and does not require heavy-duty manupulation on the client side. TinyMCE is as far as it will go.
Initially I was building the client admin area by echoing <input> from php and then collecting the data by parsing the DOM, converting to JSON and AJAX it back to the server (I found this code very helpful)
That of course required the user to hit "save" after editing or adding new data.
I later on decided that I needed something even more responsive and simpler than that so I'm now re-implementing everything for Jeditable which AJAXes the data as soon as the client hits "OK" on that particular field. No "main save" required.
To conclude it's really an area that is pretty uncharted. I mean, it appears to me that people in the industry do not like to blur that line between back-end and front-end and find "one solution" that will do the entire DB>SERVER>CLIENT>SERVER>DB operation.
I'd love to see how you solved your problem.
Just my 2 cents.

Attaching an event to MySQL from Node.js (or other)

I am designing an application that will run in a browser and have alerts pushed to it. I've already decided that to handle the mass of connections and all the so called reverse AJAX part of it with Node.js and Socket.io. This looks great to avoid constant polling and give me a real-time app except for one thing, how do I go about getting information out of a mysql database in real time?
I am envisioning something like an event handler whereby I can say something like on a row being inserted give me the data. I know this can be done with triggers but not how to do it.
Is there a good way to do this?
P.S. If I have to use something other than Node.js then this is no problem.
Thanks,
Gareth
what if you try to use sys_exec(), UDF functions ? you'll be able to reach the node.js via mysql's triggers and some external script..
-- The mysql's Trigger fires a script (php or perl or whatever ) which contains your javascript node-client things.
Cheers

How to update variable dynamically within Rails app

I am writing my first Rails app using the twitter gem. I'm simply retrieving search results and trying to cycle through them individually every 5 seconds or so.
My thought was to create a variable and have this variable represent the array index and simply update this variable dynamically with Javascript (every 5 seconds or so). What's the best way to achieve this on the client-side? AJAX? Javascript?
Does this make sense? I will be glad to provide more context if helpful. Thanks.
Sounds you're trying to build a "recent tweets" marquee of some sort. Without knowing your requirements, you could try simply loading the ten most recent tweets in Rails, putting them in ten hidden divs, and then using jQuery just to cycle through the different tweets on the page.
If it is a requirement to "update" the most recent tweets without the user refreshing the page, then yes, you'd probably need an AJAX call.
It's hard to tell what you think you're asking: by the time your JavaScript is executing the server is no longer involved.
If you want to update some sort of count on the server side and persist it in a meaningful way, you can do so via Ajax.
What are you actually trying to do, though?
Ruby runs on the server while JavaScript (usually) runs on the client.
The Ruby generates an HTML document (perhaps with embedded JS) and the server delivers it to the client.
At that stage the Ruby has finished executing. The only way to do anything further with Ruby would be to make a new HTTP request to the server. This could be done by following a link, submitting a form, setting location.href, using XMLHttpRequest or numerous other techniques.
This would cause the Ruby program to be executed again (or a different one to be executed) which would do whatever it did with the input data.
You cannot simply "set a variable" on the server from the client.
In my particular case, I used ruby's .to_json method to convert the data and then manipulated it with javascript. This gave me the flexibility to loop through the data pretty seamlessly. Atleast it seemed to work for my particular situation. Thanks for the help guys!

Is it possible to complete the loop from browser->java->c++->java->browser?

I've got a question about data flow that is summarized best by the image below:
I've got the data path from the UI (WaveMaker) down to the hardware working perfectly. The question I have is whether I'm missing something in the connection from the Java Service to Wavemaker.
I'm trying to provide information back to Wavemaker from the HW. The specifics of shared memory and semaphore signaling are worked out already. Where I'm running into a problem is how to get the data from the Java Service back to WaveMaker, when it hasn't specifically requested it. My plan was to generate events when the Java Service returned, but another engineer here insists that it won't work, since there's no direct call from Wavemaker and we don't want to poll.
What I proposed was to call the function after the page loaded, allow the blocking to occur at the .so level, as shown below, and then handle the return string when the call returned. We would then call the function again. That has the serious flaw of blocking out interaction with the user interface.
Another option put forth would be to use a hidden control, somehow pass it into Java, and invoke an event on it from Java, which could then be made to execute a script to update the UI with the HW response. That keeps the option of using threads alive, and possibly resolves the issue. Is there some more elementary way of getting information from Java->JavaScript->UI without it having been asked for?

What is the right way to make a new XMLHttpRequest from an RJS response in Ruby on Rails?

I'm trying to come closer to a solution for the problem of my previous question.
The scheme I would like to try is following:
User requests an action from RoR controller.
Action makes some database queries, makes some calculations, sets some session variable(s) and returns some RJS code as the response. This code could either
update a progress bar and make another ajax request.
display the final result (e.g. a chart grahic) if all the processing is finished
The browser evaluates the javascript representation of the RJS. It may make another (recursive? Is recursion allowed at all?) request, or just display the result for the user.
So, my question this time is: how can I embed a XMLHttpRequest call into rjs code properly?
Some things I'd like to know are:
Should I create a new thread to avoid stack overflow. What rails helpers (if any) should I use?
Have anybody ever done something similar before on Rails or with other frameworks?
Is my idea sane?
You may find RJS information harder to come by these days, I think unobtrusive JavaScript has gained more mindshare in the Rails community. What you're describing is certainly possible. My suggestion is to spend a little time learning AJAX with jQuery. Here are some steps you might take: 1) make a GET request to controller action, 2) do something, respond with JSON, 3) in your success handler code client side, determine if you need to call the server again.
Check the Railscast on jQuery, here is the transcription
http://asciicasts.com/episodes/136-jquery
jQuery $.get() or $.getJSON
http://api.jquery.com/jQuery.get/
Rails' respond_to block, check out the "wants.js" code here
http://www.mckinneystation.com/2009/07/13/rails-respond_to-made-it-too-easy/
You could respond with your Ruby object serialized as JSON:
render :json => #thing.to_json
Using $.getJSON() will deserialize the response into a JavaScript object, so you easily access properties with the dot syntax. e.g. (pseudo-code):
$.getJSON('/url-to-thing.js', function(thing) {
if( thing.status != 'done' ) { /* call function again */ }
});
In this way, the function would stop being called once the 'thing' is 'done.' Getting comfortable with the responsibilities of the client and server parts can be daunting initially but will pay off in the long run by allowing you to develop far more dynamic and interactive web applications.

Categories