Worker Not Working


(Zouhair Elamrani Abou Elassad) #1

HI, i’m trying to implement Workers in my game, i’ve already tested a simple example on a simple AS3 project it’s working great, but once i tried the same thing on my Main class on FlashPunk, i get no response from my worker :

[Frame(factoryClass = "Preloader")]
public class Main extends Engine
{
	
	protected var mainToWorker:MessageChannel;
	protected var workerToMain:MessageChannel;
	protected var worker:Worker;
	
	public function Main():void 
	{
		super(900, 600, 60, false);
		Text.font = "Snig";
	}
	
	override public function init():void 
	{

		
		
		if(Worker.current.isPrimordial){
			//Create worker from our own loaderInfo.bytes
			worker = WorkerDomain.current.createWorker(this.loaderInfo.bytes);
	 
			//Create messaging channels for 2-way messaging
			mainToWorker = Worker.current.createMessageChannel(worker);
			workerToMain = worker.createMessageChannel(Worker.current);
	 
			//Inject messaging channels as a shared property
			worker.setSharedProperty("mainToWorker", mainToWorker);
			worker.setSharedProperty("workerToMain", workerToMain);
	 
			//Listen to the response from Worker
			workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMain);
	 
			//Start worker (re-run document class)
			worker.start();
	 
			//Set an interval that will ask the worker thread to do some math
			setInterval(function(){
				mainToWorker.send("HELLO");
				trace("[Main] HELLO");
			}, 1000);
	 
		} 
		/** 
		 * Start Worker thread 
		 **/
		else {
			//Inside of our worker, we can use static methods to 
			//access the shared messgaeChannel's
			mainToWorker = Worker.current.getSharedProperty("mainToWorker");
			workerToMain = Worker.current.getSharedProperty("workerToMain");
	 
			//Listen for messages from Main
			mainToWorker.addEventListener(Event.CHANNEL_MESSAGE, onMainToWorker);
		}
		
		super.init();
	}
	
	protected function onMainToWorker(event:Event):void {
		var msg:* = mainToWorker.receive();
		//When the main thread sends us HELLO, we'll send it back WORLD
		if (msg == "HELLO") {
			workerToMain.send("WORLD");
		}
	}
	 
	//Receive messages FROM the Worker
	protected function onWorkerToMain(event:Event):void {
		//Trace out whatever message the worker has sent us.
		trace("[Worker] " + workerToMain.receive());
	}
	
}

(Zouhair Elamrani Abou Elassad) #2

I get the error : information=ReferenceError: Error #1065: FlexVersion is not defined, weird i didn’t get this error on the project where it used to work.


(Zouhair Elamrani Abou Elassad) #3

I just noticed that when adding anything to the world, the worker won’t just work, still testing .


(Darrin) #4

So generally speaking you should stay out of the main class when using FlashPunk. The engine is going to organize everything for you. The world is where you will be adding and manipulating entities.

     public static var title:Title;  
	
	public function Main():void 
	{		
		super(600, 800, 30, false);

		FP.console.enable();
		FP.screen.color = 0x000000;
		title = new Title();  // this must be constructed here in the main constructor.		
		 
	}
	
	override public function init():void 
	{
		FP.world = title;
	}

In this example, title world will control all the navigation to the game worlds. Or you could call it menu world etc. Then in title world, I can add(new Entity()), etc.


(Zouhair Elamrani Abou Elassad) #5

Actually that’s what i do, the game is working great except for the worker part, the world is shown in the stage, if i removed all the entities from the world, the worker works, once i add an entity i get the error above.


(Zouhair Elamrani Abou Elassad) #6

This What i changed :

The Main Class :

protected var mainworld:MainWorld;
	
	public function Main():void 
	{
		super(900, 600, 60, false);
		
		mainworld = new MainWorld(this.loaderInfo);
	}
	
	override public function init():void 
	{
		//FP.console.toggleKey = Key.A;
		//FP.console.enable();
		
					
		FP.screen.color = 0xFFFFFF;
		
		FP.world = mainworld;
	
		super.init();
	}

The World :

public function MainWorld(loaderInfo:LoaderInfo) 
	{
		super();
		
		_loaderInfo = loaderInfo;
		
		
	}
	
	override public function begin():void 
	{
		super.begin();
		
		add(new Coin);  // If i removed this, the workers works great.
		
		
		if(Worker.current.isPrimordial){
			//Create worker from our own loaderInfo.bytes
			worker = WorkerDomain.current.createWorker(this._loaderInfo.bytes);
	 
			//Create messaging channels for 2-way messaging
			mainToWorker = Worker.current.createMessageChannel(worker);
			workerToMain = worker.createMessageChannel(Worker.current);
	 
			//Inject messaging channels as a shared property
			worker.setSharedProperty("mainToWorker", mainToWorker);
			worker.setSharedProperty("workerToMain", workerToMain);
	 
			//Listen to the response from Worker
			workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMain);
	 
			//Start worker (re-run document class)
			worker.start();
	 
			//Set an interval that will ask the worker thread to do some math
			setInterval(function(){
				mainToWorker.send("HELLO");
				trace("[Main] HELLO");
			}, 1000);
	 
		} 
		/** 
		 * Start Worker thread 
		 **/
		else {
			//Inside of our worker, we can use static methods to 
			//access the shared messgaeChannel's
			
			mainToWorker = Worker.current.getSharedProperty("mainToWorker");
			workerToMain = Worker.current.getSharedProperty("workerToMain");
	 
			//Listen for messages from Main
			mainToWorker.addEventListener(Event.CHANNEL_MESSAGE, onMainToWorker);
		}
	}
	
	protected function onMainToWorker(event:Event):void {
		var msg:* = mainToWorker.receive();
		//When the main thread sends us HELLO, we'll send it back WORLD
		if (msg == "HELLO") {
			workerToMain.send("WORLD");
		}
	}
	 
	//Receive messages FROM the Worker
	protected function onWorkerToMain(event:Event):void {
		//Trace out whatever message the worker has sent us.
		trace("[Worker] " + workerToMain.receive());
	}

(Darrin) #7

Actually I don’t think you are. Here is a title world following my main. Note it extends FP world and adds all the buttons.

package  
{
import entities.Buoy;
import net.flashpunk.graphics.Image;
import net.flashpunk.Sfx;
import net.flashpunk.World;
import net.flashpunk.FP;	
import entities.SplashBubble;
import entities.SplashBubbleManager;
import utilities.StandardText;
import Logo;
import constants.Difficulty;

//import levels.*;

/**
 * ...
 * @author Darrin
 */

public class Title extends World
{
	private var splashBubbleManager:SplashBubbleManager;
	private var btnEasy:ButtonTitle;
	private var btnMedium:ButtonTitle;
	private var btnHard:ButtonTitle;
	private var btnExtreme:ButtonTitle;		
	private var titleHUD:TitleHUD;
	private var bMusicStarted:Boolean = false; 
	
	public static var highScore:int = 0;
	
	private var about:About;
			
	public function Title() 
	{	
		
		add( new Logo(Main.art.getBitmap("LOGO").bitmapData, 90, 50));
		btnEasy = new ButtonTitle(Main.art.getBitmap("BTNEASY").bitmapData, 400, 230);
		add(btnEasy);
		btnMedium = new ButtonTitle(Main.art.getBitmap("BTNMEDIUM").bitmapData, 400, 300);
		add(btnMedium );			
		btnHard = new ButtonTitle(Main.art.getBitmap("BTNHARD").bitmapData, 400, 370);
		add(btnHard);
		btnExtreme = new ButtonTitle(Main.art.getBitmap("BTNEXTREME").bitmapData, 400, 440);
		add(btnExtreme);
		splashBubbleManager = new SplashBubbleManager(this);
		add(new TitleHUD());
		add(new ButtonSound());
		about = new About();
		add(about);	
		
	}
	
	override public function update():void 
	{
	
		super.update(); // this has to be at the top
		
		if (!bMusicStarted){
			SoundManager.theme();
			bMusicStarted = true;
		}
		
		if (btnEasy.click()) {
			FP.world = new Play(Difficulty.EASY);

			//removeAll();			
		}
		if (btnMedium.click()) {
			FP.world = new Play(Difficulty.MEDIUM);

			//removeAll();			
		}
		if (btnHard.click()) {
			FP.world = new Play(Difficulty.HARD);

			//removeAll();			
		}

		if (btnExtreme.click()) {
			FP.world = new Play(Difficulty.EXTREME);

			//removeAll();			
		}

		

		
	}
	
	
}

}


(Darrin) #8

So FlashPunk controls most things for you. It handles the main game loop. So whatever is in the update() gets called once per frame whether it is an active world or entity in that world. For your side scroll game you probably need very few if any native flash class imports. Try to use either world or entities only. For subby I don’t use any native flash imports for my play and entities.


(Zouhair Elamrani Abou Elassad) #9

Sorry @Darrin for the late reply, i’ve been working on my game like a monster, just wanted you to know that in the Coin entity, i’m using no native Flash imports, and thank you bu the way for sharing some of your code, i just want to know if you used the AS3 Worker class in your Title World or any of the Play world, because that’s what seems to cause me issues, i tried to find en example of using the Worker with the World class and adding some entities but nothing so far.


(Darrin) #10

So that is not part of the flash punk frame work so you won’t need it.


(Zouhair Elamrani Abou Elassad) #11

I see, in fact i’m reading some entities coordinates from a file and i wanted to that in the background cuz the UI is blocked for like a second when i read from it, that’s when i did some research and i found the AS3 Worker.


(Jacob Albano) #12

Flashpunk doesn’t have anything built in for this purpose so Workers are a viable alternative. Unfortunately I don’t have any experience using them so I can’t give you any hints of my own – I can, however, tell you for certain that Flashpunk doesn’t do anything that would get in the way of you using them.

Have you gotten anything like this working in a test app? Maybe you can compare and contrast the two projects. Searching for the error you got might also help.


(Zouhair Elamrani Abou Elassad) #13

Yes, Actually this is working on simple AS3 project, and when it comes to FlashPunk, it only works when i don’t add entities to the world.


(Jacob Albano) #14

Assuming that you’re not missing some other piece of this puzzle, this is the only thing I can think of:

Based on your code, it looks like Workers have some sort of restriction in place when it comes to sharing data between threads. What’s probably happening is that your worker and Flashpunk aren’t allowed to access the world at the same time. Instead of adding entities to the world directly, try filling up an array with them and adding the whole array when the worker finishes.


(Zouhair Elamrani Abou Elassad) #15

I see what you mean, i will try that and see what it will gives ^^.