Skip to content

Instantly share code, notes, and snippets.

@akjava
Created September 11, 2014 09:30
Show Gist options
  • Save akjava/27008a12975c4a27a376 to your computer and use it in GitHub Desktop.
Save akjava/27008a12975c4a27a376 to your computer and use it in GitHub Desktop.
GWTWebWorker Sample
<?xml version="1.0" encoding="UTF-8"?>
<!--
When updating your version of GWT, you should also update this DTD reference,
so that your app can take advantage of the latest GWT module capabilities.
-->
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN"
"http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd">
<module rename-to='gwtwebworkerssample'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.clean.Clean'/>
<!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/> -->
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<inherits name='com.google.gwt.webworker.WebWorker'/>
<!-- Specify the app entry point class. -->
<entry-point class='com.akjava.gwt.webworkers.client.GWTWebWorkersSample'/>
<!-- Specify the paths for translatable code -->
<source path='client'/>
<source path='shared'/>
<set-property name="user.agent" value="safari"/>
</module>
package com.akjava.gwt.webworkers.client;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.ImageData;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.webworker.client.MessageEvent;
import com.google.gwt.webworker.client.MessageHandler;
import com.google.gwt.webworker.client.MessagePort;
import com.google.gwt.webworker.client.Worker;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class GWTWebWorkersSample implements EntryPoint {
@Override
public void onModuleLoad() {
final VerticalPanel root=new VerticalPanel();
RootPanel.get().add(root);
Button helloBt=new Button("Hello",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
//relative on modulebase
Worker worker=Worker.create("/test1.js");
worker.setOnMessage(new MessageHandler() {
@Override
public void onMessage(MessageEvent event) {
Window.alert(event.getDataAsString());
}
});
worker.postMessage("Hello");
}
});
root.add(helloBt);
final Canvas canvas=Canvas.createIfSupported();
canvas.getContext2d().fillRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
root.add(canvas);
Button pixelBt=new Button("Gray",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
//relative on modulebase
Worker worker=Worker.create("/gray.js");
final ImageData imageData=canvas.getContext2d().getImageData(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
worker.setOnMessage(new MessageHandler() {
@Override
public void onMessage(MessageEvent event) {
log(imageData);
log(event.getDataAsJavaScriptObject());
ImageData newData=event.getDataAsJavaScriptObject().cast();
canvas.getContext2d().putImageData(newData, 0, 0);
log(event.getPorts().get(0));
}
});
JsArray<MessagePort> ports=JavaScriptObject.createArray().cast();
MessagePort array=DataBuffer.create(imageData);
ports.push(array);
//worker.postMessage(w,ports);
log(""+imageData.getData().getLength());
worker.postMessage(imageData,ports);//
//worker.postMessage(convert(imageData),ports);//no copy
log(""+imageData.getData().getLength());
}
});
root.add(pixelBt);
final Canvas imageCanvas=Canvas.createIfSupported();
imageCanvas.setSize("400px", "400px");
FileUpload upload=new FileUpload();
upload.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
JsArray<Blob> blobs=toFile(event.getNativeEvent());
String url=DownloadURL.get().createObjectURL(blobs.get(0));
final ImageElement image=Document.get().createImageElement();
image.setSrc(url);
images=0;
imageCanvas.getContext2d().drawImage(image, 0, 0);
new Timer(){
@Override
public void run() {
final long s=System.currentTimeMillis();
//blob url need load?
imageCanvas.setWidth(image.getWidth()+"px");
imageCanvas.setHeight(image.getHeight()+"px");
imageCanvas.setCoordinateSpaceWidth(image.getWidth());
imageCanvas.setCoordinateSpaceHeight(image.getHeight());
imageCanvas.getContext2d().drawImage(image, 0, 0);
for(int i=0;i<50;i++){
final ImageData imageData=imageCanvas.getContext2d().getImageData(0, 0, imageCanvas.getCoordinateSpaceWidth(), imageCanvas.getCoordinateSpaceHeight());
if(useWorker){
Worker worker=Worker.create("/grayscale.js");
worker.setOnMessage(new MessageHandler() {
@Override
public void onMessage(MessageEvent event) {
ImageData newData=event.getDataAsJavaScriptObject().cast();
imageCanvas.getContext2d().putImageData(newData, 0, 0);
images++;
if(images==50){
log("time:"+(System.currentTimeMillis()-s));
}
root.add(new Image(imageCanvas.toDataUrl()));
}
});
JsArray<MessagePort> ports=JavaScriptObject.createArray().cast();
MessagePort array=DataBuffer.create(imageData);
ports.push(array);
worker.postMessage(imageData,ports);//
}else{
for(int y=0;y<imageData.getHeight();y++){
for(int x=0;x<imageData.getWidth();x++){
int value=(int) (0.299*imageData.getRedAt(x, y) + 0.587*imageData.getGreenAt(x, y) + 0.114*imageData.getBlueAt(x, y));
imageData.setRedAt(value, x, y);
imageData.setGreenAt(value, x, y);
imageData.setBlueAt(value, x, y);
}
}
imageCanvas.getContext2d().putImageData(imageData, 0, 0);
images++;
if(images==50){
log("time:"+(System.currentTimeMillis()-s));
}
root.add(new Image(imageCanvas.toDataUrl()));
}
}
}}.schedule(500);
//it's time to web worker
}
});
root.add(imageCanvas);
root.add(upload);
FileUpload uploadTest=new FileUpload();
uploadTest.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
JsArray<Blob> blobs=toFile(event.getNativeEvent());
String url=DownloadURL.get().createObjectURL(blobs.get(0));
final ImageElement image=Document.get().createImageElement();
image.setSrc(url);
images=0;
imageCanvas.getContext2d().drawImage(image, 0, 0);//for load
new Timer(){
@Override
public void run() {
//blob url need load?
imageCanvas.setWidth(image.getWidth()+"px");
imageCanvas.setHeight(image.getHeight()+"px");
imageCanvas.setCoordinateSpaceWidth(image.getWidth());
imageCanvas.setCoordinateSpaceHeight(image.getHeight());
imageCanvas.getContext2d().drawImage(image, 0, 0);
final ImageData imageData=imageCanvas.getContext2d().getImageData(0, 0, imageCanvas.getCoordinateSpaceWidth(), imageCanvas.getCoordinateSpaceHeight());
Context2d ctx=imageCanvas.getContext2d();
final long s=System.currentTimeMillis();
for(int i=0;i<10;i++){
/*
* ImageData newData=ctx.createImageData(imageData); //just copy w&h 30ms-45ms
for(int j=0;j<imageData.getData().getLength();j++){
newData.getData().set(j, imageData.getData().get(j));//maybe slow copy,use native //wao 1400ms
}
*/
ImageData newData=copy(ctx, imageData);//50ms extremly first
if(i==0){
imageData.setAlphaAt(1, 0, 0);//check cloned?
log(""+newData.getAlphaAt(0, 0));
}
}
log("time:"+(System.currentTimeMillis()-s));
/*
for(int i=0;i<imageData.getData().getLength();i++){
newData.getData().set(i, imageData.getData().get(i));//maybe slow copy,use native
}
*/
}
}.schedule(500);
//it's time to web worker
}
});
root.add(uploadTest);
}
int images=0;
boolean useWorker=false;
public static native final ImageData copy(Context2d ctx,ImageData src)/*-{
var dst = ctx.createImageData(src.width, src.height);
dst.data.set(src.data);
return dst;
}-*/;
public static class DownloadURL extends JavaScriptObject{
protected DownloadURL(){}
public native final String createObjectURL(JavaScriptObject object)/*-{
return this.createObjectURL(object);
}-*/;
public native final void revokeObjectURL(String url)/*-{
this.revokeObjectURL(url);
}-*/;
public static native final DownloadURL get()/*-{
return window.webkitURL || window.URL;
}-*/;
}
public static class Blob extends JavaScriptObject{
protected Blob(){}
}
public static final native JsArray<Blob> toFile(NativeEvent event)/*-{
return event.target.files;
}-*/;
public static native JavaScriptObject convert(ImageData imageData) /*-{
return {data:imageData.data.buffer,width:imageData.width,height:imageData.height};
}-*/;
public static native void log(String object) /*-{
console.log(object);
}-*/;
public static native void log(JavaScriptObject object) /*-{
console.log(object);
}-*/;
//this is not so good
public static class DataBuffer extends MessagePort{
protected DataBuffer(){}
public static native DataBuffer create(ImageData imageData) /*-{
return imageData.data.buffer;
}-*/;
}
}
@akjava
Copy link
Author

akjava commented Sep 11, 2014

need add these on Worker.java

/* added my self**/
public final native void postMessage(JavaScriptObject message) /-{
this.postMessage(message);
}-
/;
/** added my self
/
public final native void postMessage(JavaScriptObject message,JsArray ports) /
-{
this.postMessage(message,ports);
}-*/;

//MessageEvent.java
public final native JavaScriptObject getDataAsJavaScriptObject() /-{
return this.data;
}-
/;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment