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
							 |