浏览代码

multidriver / multiwindow support on hl

Nicolas Cannasse 1 年之前
父节点
当前提交
d306da1910
共有 5 个文件被更改,包括 72 次插入14 次删除
  1. 1 0
      h3d/Engine.hx
  2. 1 1
      h3d/impl/Driver.hx
  3. 14 10
      hxd/System.hl.hx
  4. 53 3
      hxd/Window.hl.hx
  5. 3 0
      hxd/Window.hx

+ 1 - 0
h3d/Engine.hx

@@ -115,6 +115,7 @@ class Engine {
 
 
 	public inline function setCurrent() {
 	public inline function setCurrent() {
 		CURRENT = this;
 		CURRENT = this;
+		window.setCurrent();
 	}
 	}
 
 
 	public function init() {
 	public function init() {

+ 1 - 1
h3d/impl/Driver.hx

@@ -10,7 +10,7 @@ typedef Texture = { t : js.html.webgl.Texture, width : Int, height : Int, intern
 typedef Query = {};
 typedef Query = {};
 #elseif hlsdl
 #elseif hlsdl
 typedef GPUBuffer = sdl.GL.Buffer;
 typedef GPUBuffer = sdl.GL.Buffer;
-typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int, bias : Float, startMip : Int };
+typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int, bias : Float, startMip : Int #if multidriver, driver : Driver #end };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 #elseif usegl
 #elseif usegl
 typedef GPUBuffer = haxe.GLTypes.Buffer;
 typedef GPUBuffer = haxe.GLTypes.Buffer;

+ 14 - 10
hxd/System.hl.hx

@@ -58,17 +58,14 @@ class System {
 		loopFunc = f;
 		loopFunc = f;
 	}
 	}
 
 
-	static function mainLoop() : Bool {
+	static function mainLoop() {
 		// process events
 		// process events
 		#if usesys
 		#if usesys
-		if( !haxe.System.emitEvents(@:privateAccess hxd.Window.inst.event) )
-			return false;
+		haxe.System.emitEvents(@:privateAccess hxd.Window.dispatchEvent);
 		#elseif hldx
 		#elseif hldx
-		if( !dx.Loop.processEvents(@:privateAccess hxd.Window.inst.onEvent) )
-			return false;
+		dx.Loop.processEvents(@:privateAccess hxd.Window.dispatchEvent);
 		#elseif hlsdl
 		#elseif hlsdl
-		if( !sdl.Sdl.processEvents(@:privateAccess hxd.Window.inst.onEvent) )
-			return false;
+		sdl.Sdl.processEvents(@:privateAccess hxd.Window.dispatchEvent);
 		#end
 		#end
 
 
 		// loop
 		// loop
@@ -87,7 +84,6 @@ class System {
 			hl.Profile.event(-2); // resume
 			hl.Profile.event(-2); // resume
 			#end
 			#end
 		}
 		}
-		return true;
 	}
 	}
 
 
 	public static function start( init : Void -> Void ) : Void {
 	public static function start( init : Void -> Void ) : Void {
@@ -128,6 +124,14 @@ class System {
 		timeoutTick();
 		timeoutTick();
 		haxe.Timer.delay(runMainLoop, 0);
 		haxe.Timer.delay(runMainLoop, 0);
 	}
 	}
+	
+	static function isAlive() {
+		#if usesys
+		return true;
+		#else
+		return hxd.Window.hasWindow();
+		#end
+	}
 
 
 	static function runMainLoop() {
 	static function runMainLoop() {
 		#if (haxe_ver >= 4.1)
 		#if (haxe_ver >= 4.1)
@@ -138,7 +142,7 @@ class System {
 		#if ( target.threaded && (haxe_ver >= 4.2) && heaps_unsafe_events)
 		#if ( target.threaded && (haxe_ver >= 4.2) && heaps_unsafe_events)
 		var eventRecycle = [];
 		var eventRecycle = [];
 		#end
 		#end
-		while( true ) {
+		while( isAlive() ) {
 			#if !heaps_no_error_trap
 			#if !heaps_no_error_trap
 			try {
 			try {
 				hl.Api.setErrorHandler(reportError); // set exception trap
 				hl.Api.setErrorHandler(reportError); // set exception trap
@@ -156,7 +160,7 @@ class System {
 				@:privateAccess haxe.MainLoop.tick();
 				@:privateAccess haxe.MainLoop.tick();
 				#end
 				#end
 
 
-				if( !mainLoop() ) break;
+				mainLoop();
 			#if !heaps_no_error_trap
 			#if !heaps_no_error_trap
 			} catch( e : Dynamic ) {
 			} catch( e : Dynamic ) {
 				hl.Api.setErrorHandler(null);
 				hl.Api.setErrorHandler(null);

+ 53 - 3
hxd/Window.hl.hx

@@ -39,11 +39,14 @@ private class NativeDroppedFile extends hxd.DropFileEvent.DroppedFile {
 //@:coreApi
 //@:coreApi
 class Window {
 class Window {
 
 
+	static var WINDOWS : Array<Window> = [];
+
 	var resizeEvents : List<Void -> Void>;
 	var resizeEvents : List<Void -> Void>;
 	var eventTargets : List<Event -> Void>;
 	var eventTargets : List<Event -> Void>;
 	var dropTargets : List<DropFileEvent -> Void>;
 	var dropTargets : List<DropFileEvent -> Void>;
 	var dropFiles : Array<hxd.DropFileEvent.DroppedFile>;
 	var dropFiles : Array<hxd.DropFileEvent.DroppedFile>;
 
 
+	public var id : Int;
 	public var width(get, never) : Int;
 	public var width(get, never) : Int;
 	public var height(get, never) : Int;
 	public var height(get, never) : Int;
 	public var mouseX(get, never) : Int;
 	public var mouseX(get, never) : Int;
@@ -113,6 +116,10 @@ class Window {
 		final dxFlags = if (!fixed) dx.Window.RESIZABLE else 0;
 		final dxFlags = if (!fixed) dx.Window.RESIZABLE else 0;
 		window = new dx.Window(title, width, height, dx.Window.CW_USEDEFAULT, dx.Window.CW_USEDEFAULT, dxFlags);
 		window = new dx.Window(title, width, height, dx.Window.CW_USEDEFAULT, dx.Window.CW_USEDEFAULT, dxFlags);
 		#end
 		#end
+		WINDOWS.push(this);
+		#if multidriver
+		id = window.id;
+		#end
 	}
 	}
 
 
 	public dynamic function onClose() : Bool {
 	public dynamic function onClose() : Bool {
@@ -123,6 +130,14 @@ class Window {
 		return null;
 		return null;
 	}
 	}
 
 
+	public function close() {
+		if( !WINDOWS.remove(this) )
+			return;
+		#if (multidriver && (hlsdl || hldx))
+		window.destroy();
+		#end
+	}
+
 	public function event( e : hxd.Event ) : Void {
 	public function event( e : hxd.Event ) : Void {
 		for( et in eventTargets )
 		for( et in eventTargets )
 			et(e);
 			et(e);
@@ -305,7 +320,7 @@ class Window {
 
 
 		startMouseX = curMouseX;
 		startMouseX = curMouseX;
 		startMouseY = curMouseY;
 		startMouseY = curMouseY;
-		
+
 		return mouseMode = v;
 		return mouseMode = v;
 	}
 	}
 
 
@@ -363,6 +378,8 @@ class Window {
 				event(new Event(EOver));
 				event(new Event(EOver));
 			case Leave:
 			case Leave:
 				event(new Event(EOut));
 				event(new Event(EOut));
+			case Close:
+				return onCloseEvent();
 			default:
 			default:
 			}
 			}
 		case MouseDown if (!hxd.System.getValue(IsTouch)):
 		case MouseDown if (!hxd.System.getValue(IsTouch)):
@@ -474,7 +491,7 @@ class Window {
 			#end
 			#end
 			eh = new Event(ERelease, e.mouseX, e.mouseY);
 			eh = new Event(ERelease, e.mouseX, e.mouseY);
 			eh.touchId = e.fingerId;
 			eh.touchId = e.fingerId;
-		
+
 		#elseif hldx
 		#elseif hldx
 		case KeyDown:
 		case KeyDown:
 			eh = new Event(EKeyDown);
 			eh = new Event(EKeyDown);
@@ -515,14 +532,23 @@ class Window {
 			for ( dt in dropTargets ) dt(event);
 			for ( dt in dropTargets ) dt(event);
 			dropFiles = null;
 			dropFiles = null;
 		#end
 		#end
+		#if !hlsdl // hlsdl post both Close+Quit
 		case Quit:
 		case Quit:
-			return onClose();
+			return onCloseEvent();
+		#end
 		default:
 		default:
 		}
 		}
 		if( eh != null ) event(eh);
 		if( eh != null ) event(eh);
 		return true;
 		return true;
 	}
 	}
 
 
+	function onCloseEvent() {
+		var ret = onClose();
+		if( ret )
+			close();
+		return ret;
+	}
+
 	static function initChars() : Void {
 	static function initChars() : Void {
 
 
 		inline function addKey(sdl, keyCode) {
 		inline function addKey(sdl, keyCode) {
@@ -801,8 +827,32 @@ class Window {
 		return "";
 		return "";
 	}
 	}
 
 
+	public function setCurrent() {
+		inst = this;
+		#if hlsdl
+		window.renderTo();
+		#end
+	}
+
 	static var inst : Window = null;
 	static var inst : Window = null;
 	public static function getInstance() : Window {
 	public static function getInstance() : Window {
 		return inst;
 		return inst;
 	}
 	}
+
+	public static function hasWindow() {
+		return WINDOWS.length > 0;
+	}
+
+	static function dispatchEvent( e ) {
+		#if multidriver
+		if( false ) @:privateAccess WINDOWS[0].onEvent(e); // typing
+		for( w in WINDOWS )
+			if( e.windowId == w.id )
+				return w.onEvent(e);
+		return true;
+		#else
+		return inst.onEvent(e);
+		#end
+	}
+
 }
 }

+ 3 - 0
hxd/Window.hx

@@ -114,6 +114,9 @@ class Window {
 	public function setCursorPos( x : Int, y : Int, emitEvent : Bool = false ) : Void {
 	public function setCursorPos( x : Int, y : Int, emitEvent : Bool = false ) : Void {
 		throw "Not implemented";
 		throw "Not implemented";
 	}
 	}
+	
+	public function setCurrent() {
+	}
 
 
 	static var inst : Window = null;
 	static var inst : Window = null;
 	public static function getInstance() : Window {
 	public static function getInstance() : Window {