124 lines
2.7 KiB
Haxe
124 lines
2.7 KiB
Haxe
package kernel.ps;
|
|
|
|
import kernel.turtle.TurtleMutex;
|
|
import kernel.ps.ProcessManager.PID;
|
|
import kernel.ui.WindowContext;
|
|
import kernel.ui.WindowManager;
|
|
import haxe.ds.ReadOnlyArray;
|
|
|
|
using tink.CoreApi;
|
|
|
|
typedef HandleConfig = {
|
|
?args:Array<String>,
|
|
?onWrite:Callback<String>,
|
|
?onExit:Callback<Bool>,
|
|
}
|
|
|
|
class ProcessHandle {
|
|
public var args(get, null):ReadOnlyArray<String>;
|
|
|
|
private final pid:PID;
|
|
private final config:HandleConfig;
|
|
private final closeFuture:Future<Bool>;
|
|
private var closeFutureResolev:Bool->Void;
|
|
private final windowContexts:Array<WindowContext> = [];
|
|
private final cbLinks:Array<CallbackLink> = [];
|
|
private final deferFuncs:Array<Void->Void> = [];
|
|
private var hasExited:Bool = false;
|
|
|
|
@:allow(kernel.ps.ProcessManager)
|
|
private function new(config:HandleConfig, pid:PID) {
|
|
this.config = config;
|
|
this.pid = pid;
|
|
|
|
this.closeFuture = new Future<Bool>((trigger) -> {
|
|
this.closeFutureResolev = trigger;
|
|
return null;
|
|
});
|
|
|
|
if (this.config.onExit != null) {
|
|
this.closeFuture.handle(this.config.onExit);
|
|
}
|
|
}
|
|
|
|
public function onExit():Future<Bool> {
|
|
return this.closeFuture;
|
|
}
|
|
|
|
public function close(success:Bool = true):Void {
|
|
this.hasExited = true;
|
|
this.dispose();
|
|
|
|
EndOfLoop.endOfLoop(() -> {
|
|
this.closeFutureResolev(success);
|
|
});
|
|
ProcessManager.removeProcess(this.pid);
|
|
}
|
|
|
|
public function write(message:String):Void {
|
|
if (this.hasExited)
|
|
return;
|
|
if (this.config.onWrite != null) {
|
|
this.config.onWrite.invoke(message);
|
|
}
|
|
}
|
|
|
|
public function writeLine(message:String):Void {
|
|
this.write(message + "\n");
|
|
}
|
|
|
|
public function createBufferdWindowContext():WindowContext {
|
|
var ctx = WindowManager.createNewContext();
|
|
this.windowContexts.push(ctx);
|
|
return ctx;
|
|
}
|
|
|
|
public function createStatelessWindowContext():{ctx:WindowContext, setRenderFunc:(() -> Void)->Void, requestRender:() -> Void} {
|
|
var ctx = WindowManager.createNewStatelessContext();
|
|
this.windowContexts.push(ctx.ctx);
|
|
return ctx;
|
|
}
|
|
|
|
public function getWindowContexts():ReadOnlyArray<WindowContext> {
|
|
return this.windowContexts;
|
|
}
|
|
|
|
private function dispose() {
|
|
for (link in this.cbLinks) {
|
|
link.cancel();
|
|
}
|
|
|
|
for (func in this.deferFuncs) {
|
|
func();
|
|
}
|
|
}
|
|
|
|
public function getPid():PID {
|
|
return this.pid;
|
|
}
|
|
|
|
public function addCallbackLink(link:CallbackLink) {
|
|
this.cbLinks.push(link);
|
|
}
|
|
|
|
public function addDeferFunc(func:Void->Void) {
|
|
this.deferFuncs.push(func);
|
|
}
|
|
|
|
public function get_args():ReadOnlyArray<String> {
|
|
return this.config.args;
|
|
}
|
|
|
|
public function claimTurtleMutex():Bool {
|
|
if (TurtleMutex.claim(this.pid)) {
|
|
this.addDeferFunc(() -> {
|
|
TurtleMutex.release(this.pid);
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|