Haxe WebWorkers

253 views
Skip to first unread message

David Mouton

unread,
Nov 14, 2012, 7:47:47 AM11/14/12
to haxe...@googlegroups.com
Hi all,
I want to code with haxe, a little script.
I will use it in a web workers like this:
var myWoker:Worker = new Worker('myHaxeJSScript.js');


My script should have a onmessage function like this
onmessage = function(e){ var t = e.data; postMessage( "Greetings from the worker script! (Your main script said:"+t+")" ); }

I dont know how to do it in Haxe.
a simple public function will looks like that :
com.tamina.Test.onmessage = function() { ... }

Any idea ?

Michel Romecki

unread,
Nov 14, 2012, 8:00:53 AM11/14/12
to haxe...@googlegroups.com
Hi,
I don't know if it's the best thing but you can do something like that in your (Test?) class :
static function __init__(){
    untyped __js__( "onmessage = com.tamina.Test.cb_onMessage;" );
}
...
static function cb_onMessage(){...}


2012/11/14 David Mouton <gradalis...@gmail.com>

clemos

unread,
Nov 14, 2012, 8:20:57 AM11/14/12
to haxe...@googlegroups.com
You might try to add something like this to your Test class:

public static function __init__(){
   untyped __js__("onmessage = com.tamina.Test.onmessage");
}


Now I don't remember if the __init__() method has its own scope or if its content is just injected in the global scope.
The above script assumes the second case.
If it's the first case, then you'll need a reference to the global scope. 
It's usually "window", which would become : 
untyped __js__("window.onmessage = com.tamina.Test.onmessage");
But I don't know if it would also be "window" in the context of a worker.

Since you probably compile your Test class as the main class, for this use case, maybe a better idea would be to add the hack to the static main() method.
This way you can still use Test's method in your app without Worker, and without the hack being injected...

When you have something working, it would probably be a good idea to write a macro or some helper classes to have this hack automatically added when compiling a worker script...
Not sure it's possible, but it would go something roughly like:
--
class MyWorkerScript implements WorkerScript {
  public function new(){}
  public function onMessage(e){ trace("on message triggered"); }
  static function main(){
     WorkerTools.export( new MyWorkerScript() );
  }
}
--
interface WorkerScript {
   public function onMessage( e : WorkerEvent ) : Void;
}
--
class WorkerTools {
   public static function export( script : WorkerScript ){
     untyped __js__("window.onmessage = script.onMessage");
   }
}

Regards,
Clément

David Mouton

unread,
Nov 14, 2012, 3:31:08 PM11/14/12
to haxe...@googlegroups.com
Ok i just tried your code but it's dont realy work.

There is my Full Worker Haxe code :

package com.tamina.planetwars.data;
import js.Dom;
import js.Lib;

/**
 * ...
 * @author d.mouton
 */

class AsbtractPlayer 
{

public function new() 
{
}
public static function __init__():Void{
untyped __js__("onmessage = com.tamina.planetwars.data.AsbtractPlayer.prototype.onmessage");
}
public function onmessage(message:Dynamic):Void {
var t:Dynamic = message.data;
postMessage("message du worker : " + t);
}
public function postMessage(message:Dynamic):Void {
}
}

And this is the builded JS :
onmessage = com.tamina.planetwars.data.AsbtractPlayer.prototype.onmessage;



com
.tamina.planetwars.data.AsbtractPlayer = function() {
};
com
.tamina.planetwars.data.AsbtractPlayer.__name__ = true;
com
.tamina.planetwars.data.AsbtractPlayer.prototype = {
 postMessage
: function(message) {
 
}
 
,onmessage: function(message) {
 
var t = message.data;
 
this.postMessage("message du worker : " + Std.string(t));
 
}
 
,__class__: com.tamina.planetwars.data.AsbtractPlayer
}

Like this, it's not working.
But if i put this  : 
onmessage = function(e){
var t = e.data;
postMessage( "Greetings from the worker script! (Your main script said:"+t+")" );
}
it's work.
I don't realy know how JS works but maby the problem is from the scope of postMessage.

What do you think ?

Michel Romecki

unread,
Nov 14, 2012, 3:47:52 PM11/14/12
to haxe...@googlegroups.com
What do you mean by "it's not working" ? Is there an exception thrown or something like that ?


2012/11/14 David Mouton <gradalis...@gmail.com>

--

David Mouton

unread,
Nov 15, 2012, 3:18:22 AM11/15/12
to haxe...@googlegroups.com
Sorry this is my Main application wich instantiate my Worker:

class IA
{

    private var _woker:Worker;
   
    public function new(IAScriptPath:String)
    {
        _woker = new Worker(IAScriptPath);
        _woker.postMessage("coucou");
    }
   
    private function worker_messageHandler(message:Dynamic):Void {
        Log.trace(message);
    }

   
}

As you can see, if my worker works, my application trace a message.


2012/11/14 Michel Romecki <filt...@gmail.com>

clemos

unread,
Nov 15, 2012, 4:48:36 AM11/15/12
to haxe...@googlegroups.com
Ahem, I'll just advise you to read my message again, 
because it looks like all the suggestions I made have been mixed with other ideas, and finally implemented upside down...

Quickly:
- try moving __js__ stuff to your worker script's main (AbstractPlayer). It makes more sense, and besides, main() is run in the end of the script, not at the beginning, like __init__, which is one of your issues.
- you need to actually instanciate AbstractPlayer in your main(), too : inst = new AbstractPlayer(); __js__("onmessage=inst.onMessage");... Using "prototype" doesn't make any sense here.

Also, as Michel pointed out, anyone (including you) would need more informations than "it doesn't work" (even with a proof that it doesn't work...) to be able to help.
I'm pretty sure that besides not working, your script throws actual errors...

Regards,
Clément

David Mouton

unread,
Nov 16, 2012, 4:53:11 AM11/16/12
to haxe...@googlegroups.com
You're right.
I should have a better look on your message.
After somes changes, it's works perfectly.

Many thanks.

I attach my code to this message.
Know i can simply extend a WorkerScript class ;)
MyIA.zip

clemos

unread,
Nov 16, 2012, 5:21:46 AM11/16/12
to haxe...@googlegroups.com
Hi David,

It may work, but there is quite a lot of dirty tricks in your code ;)
I made a gist to show you what I think would be better:

Regards,
Clément


David Mouton

unread,
Nov 16, 2012, 5:58:51 AM11/16/12
to haxe...@googlegroups.com
Interesting indeed.
But you seem to have forgotten one thing.
Communication from workers to host.
Your Worker should call a postMessage function to send an object to the main application.


2012/11/16 clemos <cl3...@gmail.com>

clemos

unread,
Nov 16, 2012, 6:20:29 AM11/16/12
to haxe...@googlegroups.com
You're right, I just haven't really used Web Workers yet...
How about that :

Regards,
Clément

David Mouton

unread,
Nov 16, 2012, 8:05:59 AM11/16/12
to haxe...@googlegroups.com
There is a mistake :
 new MyWorkerScript().export(); can't work with public inline static function export
I'm trying to replace my implementation by yours and it doesn't work anymore.
Did you try your own code ?


2012/11/16 clemos <cl3...@gmail.com>

clemos

unread,
Nov 16, 2012, 8:33:10 AM11/16/12
to haxe...@googlegroups.com

As a matter of fact, I didn t have time to test it :p
But removing "inline" on "export" may work ;)

Reply all
Reply to author
Forward
0 new messages