gearsWorkerPool.sendMessage ( "JS Worker has been called" , sender);
Workers don't actually have access to $wnd as far as I know (or
anything DOM for that matter)
the code should actually be executing in its own virgin context really.
As a reference, I'm using gwt-google-apis gears module as well
On Jun 15, 2007, at 4:46 PM, Ray Cromwell wrote:
>
> I haven't used gears, but am I missing something?
>
> Where is gearsWorkerPool defined? If it is a global from an
> included <SCRIPT> element, you need to write it as
> $wnd.gearsWorkerPool
>
> -Ray
I don't know if the actual js attached with the original post, so
here it is:
(function(){
var $wnd = window;
var $doc = $wnd.document;
var $moduleName, $moduleBase;
var _, package_com_google_gwt_core_client_ =
'com.google.gwt.core.client.', package_com_google_gwt_lang_ =
'com.google.gwt.lang.', package_com_grcs_worker_client_ =
'com.grcs.worker.client.', package_java_lang_ = 'java.lang.';
function nullMethod(){
}
function java_lang_Object(){
}
_ = java_lang_Object.prototype = {};
_.java_lang_Object_typeName = package_java_lang_ + 'Object';
_.java_lang_Object_typeId = 0;
function com_google_gwt_core_client_JavaScriptObject(){
}
_ = com_google_gwt_core_client_JavaScriptObject.prototype = new
java_lang_Object();
_.java_lang_Object_typeName = package_com_google_gwt_core_client_ +
'JavaScriptObject';
_.java_lang_Object_typeId = 5;
function com_grcs_worker_client_Worker_
$onModuleLoad__Lcom_grcs_worker_client_Worker_2(this$static){
this$static.init__();
}
function com_grcs_worker_client_Worker_init__(){
gearsWorkerPool.onmessage = new function(msg, sender){
return this.onMessage__Ljava_lang_String_2I(msg, sender);
}
();
}
function com_grcs_worker_client_Worker_onMessage__Ljava_lang_String_2I
(msg, sender){
this.sendMessage__Ljava_lang_String_2I('Worker has been called.',
sender);
}
function
com_grcs_worker_client_Worker_sendMessage__Ljava_lang_String_2I(msg,
sender){
gearsWorkerPool.sendMessage(msg, sender);
}
function com_grcs_worker_client_Worker(){
}
_ = com_grcs_worker_client_Worker.prototype = new java_lang_Object();
_.init__ = com_grcs_worker_client_Worker_init__;
_.onMessage__Ljava_lang_String_2I =
com_grcs_worker_client_Worker_onMessage__Ljava_lang_String_2I;
_.sendMessage__Ljava_lang_String_2I =
com_grcs_worker_client_Worker_sendMessage__Ljava_lang_String_2I;
_.java_lang_Object_typeName = package_com_grcs_worker_client_ +
'Worker';
_.java_lang_Object_typeId = 0;
function java_lang_String_$clinit__(){
java_lang_String_$clinit__ = nullMethod;
{
java_lang_String__1_1initHashCache__();
}
}
function java_lang_String__1_1initHashCache__(){
java_lang_String_$clinit__();
java_lang_String_hashCache = {};
}
_ = String.prototype;
_.java_lang_Object_typeName = package_java_lang_ + 'String';
_.java_lang_Object_typeId = 9;
var java_lang_String_hashCache = null;
function init(){
com_grcs_worker_client_Worker_
$onModuleLoad__Lcom_grcs_worker_client_Worker_2(new
com_grcs_worker_client_Worker());
}
function gwtOnLoad(errFn, modName, modBase){
$moduleName = modName;
$moduleBase = modBase;
if (errFn)
try {
init();
}
catch (e) {
errFn(modName);
}
else {
init();
}
}
var com_google_gwt_lang_Cast_typeIdArray = [{}, {2:1}, {2:1}, {2:1},
{2:1}, {1:1}, {2:1}, {2:1}, {2:1}, {3:1}];
if (com_grcs_worker_Worker) {
var __gwt_initHandlers =
com_grcs_worker_Worker.__gwt_initHandlers;
com_grcs_worker_Worker.onScriptLoad(gwtOnLoad);
}
})();
So you're saying you got it working? :-)
Having been through some muckery with the 1.4 startup changes breaking
the GWTJSF code, I'm a bit concerned that your technique -- though
cool -- is a bit exposed to the implementation details of the GWT
startup sequence. But your success with mocking window and
window.document indicates that maybe it's not too bad. As long as the
GWT compiler doesn't expect or require any preexisting variables
beyond those two, it's probably fine, and what else could it want,
really?
Cheers!
Rob
Actually at this moment startup is a bit tweaky ...
The startup sequence is solid, no problem there, since the code is
loaded via a XHR, there is no ambiguity about startup.
The remaining issues are:
1) workers really need to stay away from anything in the DOM class,
and also the GWT class would require a more robust mockup of window
and document. It would be awesome if the compiler could whine if a
Worker entry point used code that attempted to do any DOM modification.
2) I need a new kind of selection script. one that can be fed to eval
() and return the strongname for the particular platform. If none of
the used code performs deferred binding, or internationalization,
then there should only be one permutation, but if something causes
additional permutations there's no way to get ahold of them.
I'm currently working towards a WorkerUtility that allows creating a
worker simply by doing something like:
int workerId = WorkerUtil.loadModule("com.my.module.MyModule");
Actually, this may not work so well since the process of loading the
module is really asynchronous, and trying to shoehorn it into a
synchronous call is ugly at best.
But that'd require the new selection script ... Scott any ideas on
this one?
-jason
Here's what I've come up with so far for using GWT code directly in Gears workers ...first a code snippet:
wp.createWorkerFromModule( WORKER_MODULE , new PrimeWorkerCallback());
This is all it takes to load a GWT module into a Gears Worker once a worker pool has been created.So, how would it work?First create the module that you want to use as a worker, but instead of implementing an EntryPoint, implement a subclass of EntryPoint called Worker.Worker would expose init() and onMessage(String msg, int sender) methods that could be implemented to give the worker functionality.Then in the main module, the worker pool could be created, and a new worker loaded based upon the module name.So, would it actually work?What did it really take to do that?1) I first needed to create a new type of entry point that would properly register onmessage handlers and such, so I created the "Worker" entry point. it finalizes the onModuleLoad() method, and exposes two new methods ( init() and onMessage() ) that could be used by the worker.
2) I needed to extend WorkerPool so that it could load files using XHR. (Initially I just loaded the javascript payload directly, but that was a bit of a hassle, so I needed a way to create a selection script that could identify which javascript file the particular browser should be loading. see #3). So, the WorkerPool looks for a file named [MODULE_NAME]- gg.js, and tries to load it using XHR. once the file is loaded, it evaluates the script which hopefully returns the strong name of the actual javascript payload. with this URL, WorkerPool performs a second XHR to fetch the worker script (which is simply one of the *.cache.js files). then it wraps that script in a try/catch block (for more verbose error handling), mocks up a window and document object, and creates a [MODULE_NAME] object (usually created by the selection script). the [MODULE_NAME] object has a method that will actually initialize the module when it is fed to the worker. Finally the whole thing is fed off to the WorkerPool's regular createWorkerFromString(); method. Once the WorkerPool returns with a worker ID, a callback is fired to notify the original caller that the worker is ready. Since loading a worker from a module involves 2 XHRs, it is not possible or even desirable to perform this step as a synchronous operation.
3) The selection script is really the most hackish part of the process at this point. Since I was after the instant gratification, I simply modified the SelectionScriptTemplat-xs.js file (Thanks for pointing that out to me Scott). basically I stripped it down, and made it just evaluate to a string. This is the part that could really use some more polishing up on, it is ugly, and fragile at this point since there is no error checking about attempting to access the window or document objects.4) once both projects (the parent module, and the worker module) have been compiled, the *.cache.js, and -xs.nocache.js (renamed to -gg.nocache.js) files need to be copied from the worker module's output directory to the final deployment location. all of the regular files required for deployment are copied from the parent's output directory to the deployment location.Now what?First anyone interested should have a look at the code that I tossed together and decide if this is even the correct way to solve the problem. (I'm attempting to attach the files to this mail, if the forum strips the files, feel free to contact me directly)If it is, then it might be nice to have a much cleaner selection script generator (maybe a compiler switch could be used to tell it that the module is going to be a gears worker). It might also be nice to continue to support resource injection for workers (at least for javascript libraries), so perhaps the selection script could return an array of URLs (this is a topic that could certainly use some discussion)?Then the actual WorkerPool and associated interfaces could be cleaned up, and submitted back to gwt-google-apis.-jason