146 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
package kha;
 | 
						|
 | 
						|
import haxe.macro.Context;
 | 
						|
import haxe.macro.Expr;
 | 
						|
#if macro
 | 
						|
import kha.internal.AssetsBuilder;
 | 
						|
import sys.io.File;
 | 
						|
#end
 | 
						|
 | 
						|
using haxe.macro.ExprTools;
 | 
						|
 | 
						|
#if (kha_html5 || kha_krom)
 | 
						|
class Worker {
 | 
						|
	#if kha_in_worker
 | 
						|
	public static function notifyWorker(func: Dynamic->Void): Void {
 | 
						|
		#if !macro
 | 
						|
		js.Syntax.code("self").addEventListener("message", function(e) {
 | 
						|
			func(e.data);
 | 
						|
		});
 | 
						|
		#end
 | 
						|
	}
 | 
						|
 | 
						|
	public static function postFromWorker(message: Dynamic): Void {
 | 
						|
		#if !macro
 | 
						|
		js.Syntax.code("self").postMessage(message);
 | 
						|
		#end
 | 
						|
	}
 | 
						|
	#else
 | 
						|
	#if macro
 | 
						|
	static var threads = new Array<String>();
 | 
						|
	#else
 | 
						|
	var worker: js.html.Worker;
 | 
						|
	#end
 | 
						|
 | 
						|
	function new(file: String) {
 | 
						|
		#if !macro
 | 
						|
		worker = new js.html.Worker(file);
 | 
						|
		#end
 | 
						|
	}
 | 
						|
 | 
						|
	@:noCompletion
 | 
						|
	public static function _create(file: String): Worker {
 | 
						|
		return new Worker(file);
 | 
						|
	}
 | 
						|
 | 
						|
	public function notify(func: Dynamic->Void): Void {
 | 
						|
		#if !macro
 | 
						|
		worker.addEventListener("message", function(e) {
 | 
						|
			func(e.data);
 | 
						|
		});
 | 
						|
		#end
 | 
						|
	}
 | 
						|
 | 
						|
	public function post(message: Dynamic): Void {
 | 
						|
		#if !macro
 | 
						|
		worker.postMessage(message);
 | 
						|
		#end
 | 
						|
	}
 | 
						|
 | 
						|
	public static macro function create(expr: Expr) {
 | 
						|
		var name: String = expr.toString();
 | 
						|
		if (threads.indexOf(name) < 0) {
 | 
						|
			threads.push(name);
 | 
						|
		}
 | 
						|
		var threadstring = "";
 | 
						|
		for (thread in threads) {
 | 
						|
			threadstring += thread + "\n";
 | 
						|
		}
 | 
						|
		File.saveContent(AssetsBuilder.findResources() + "workers.txt", threadstring);
 | 
						|
		return Context.parse("kha.Worker._create(\"" + name + ".js\")", Context.currentPos());
 | 
						|
	}
 | 
						|
	#end
 | 
						|
}
 | 
						|
#end
 | 
						|
 | 
						|
#if kha_kore
 | 
						|
import sys.thread.Thread;
 | 
						|
import sys.thread.Tls;
 | 
						|
import kha.Scheduler;
 | 
						|
 | 
						|
private class Message {
 | 
						|
	public final threadId: Int;
 | 
						|
	public final message: Dynamic;
 | 
						|
 | 
						|
	public function new(message: Dynamic) {
 | 
						|
		this.threadId = @:privateAccess Worker.threadId.value;
 | 
						|
		this.message = message;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
class Worker {
 | 
						|
	public static var _mainThread: Thread;
 | 
						|
 | 
						|
	static var notifyFuncs: Array<Dynamic->Void> = [];
 | 
						|
	static var taskId: Int = -1;
 | 
						|
	static var nextThreadId: Int = 0;
 | 
						|
	static var threadId = new Tls<Int>();
 | 
						|
 | 
						|
	var thread: Thread;
 | 
						|
	var id: Int;
 | 
						|
 | 
						|
	function new(thread: Thread, id: Int) {
 | 
						|
		this.thread = thread;
 | 
						|
		this.id = id;
 | 
						|
	}
 | 
						|
 | 
						|
	public static function create(clazz: Class<Dynamic>): Worker {
 | 
						|
		var id = nextThreadId++;
 | 
						|
		return new Worker(Thread.create(function() {
 | 
						|
			threadId.value = id;
 | 
						|
			Reflect.field(clazz, "main")();
 | 
						|
		}), id);
 | 
						|
	}
 | 
						|
 | 
						|
	public function notify(func: Dynamic->Void): Void {
 | 
						|
		notifyFuncs[id] = func;
 | 
						|
		if (taskId != -1)
 | 
						|
			return;
 | 
						|
		taskId = Scheduler.addFrameTask(function() {
 | 
						|
			var message: Message = Thread.readMessage(false);
 | 
						|
			if (message != null) {
 | 
						|
				var func = notifyFuncs[message.threadId];
 | 
						|
				func(message.message);
 | 
						|
			}
 | 
						|
		}, 0);
 | 
						|
	}
 | 
						|
 | 
						|
	public function post(message: Dynamic): Void {
 | 
						|
		thread.sendMessage(message);
 | 
						|
	}
 | 
						|
 | 
						|
	public static function notifyWorker(func: Dynamic->Void): Void {
 | 
						|
		while (true) {
 | 
						|
			var message = Thread.readMessage(true);
 | 
						|
			if (message != null) {
 | 
						|
				func(message);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public static function postFromWorker(message: Dynamic): Void {
 | 
						|
		_mainThread.sendMessage(new Message(message));
 | 
						|
	}
 | 
						|
}
 | 
						|
#end
 |