| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | package iron; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class App { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static dynamic function w(): Int { return kha.System.windowWidth(); } | 
					
						
							|  |  |  | 	public static dynamic function h(): Int { return kha.System.windowHeight(); } | 
					
						
							|  |  |  | 	public static dynamic function x(): Int { return 0; } | 
					
						
							|  |  |  | 	public static dynamic function y(): Int { return 0; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static var onResets: Array<Void->Void> = null; | 
					
						
							|  |  |  | 	static var onEndFrames: Array<Void->Void> = null; | 
					
						
							|  |  |  | 	static var traitInits: Array<Void->Void> = []; | 
					
						
							|  |  |  | 	static var traitUpdates: Array<Void->Void> = []; | 
					
						
							|  |  |  | 	static var traitLateUpdates: Array<Void->Void> = []; | 
					
						
							| 
									
										
										
										
											2025-06-01 23:14:43 +00:00
										 |  |  | 	static var traitFixedUpdates: Array<Void->Void> = []; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	static var traitRenders: Array<kha.graphics4.Graphics->Void> = []; | 
					
						
							|  |  |  | 	static var traitRenders2D: Array<kha.graphics2.Graphics->Void> = []; | 
					
						
							|  |  |  | 	public static var framebuffer: kha.Framebuffer; | 
					
						
							|  |  |  | 	public static var pauseUpdates = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	#if lnx_debug | 
					
						
							|  |  |  | 	static var startTime: Float; | 
					
						
							|  |  |  | 	public static var updateTime: Float; | 
					
						
							|  |  |  | 	public static var renderPathTime: Float; | 
					
						
							|  |  |  | 	public static var endFrameCallbacks: Array<Void->Void> = []; | 
					
						
							|  |  |  | 	#end | 
					
						
							| 
									
										
										
										
											2025-06-01 23:14:43 +00:00
										 |  |  | 	static var last = 0.0; | 
					
						
							|  |  |  | 	static var time = 0.0; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	static var lastw = -1; | 
					
						
							|  |  |  | 	static var lasth = -1; | 
					
						
							|  |  |  | 	public static var onResize: Void->Void = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function init(done: Void->Void) { | 
					
						
							|  |  |  | 		new App(done); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function new(done: Void->Void) { | 
					
						
							|  |  |  | 		done(); | 
					
						
							|  |  |  | 		kha.System.notifyOnFrames(render); | 
					
						
							| 
									
										
										
										
											2025-06-02 04:11:02 +00:00
										 |  |  | 		kha.Scheduler.addTimeTask(update, 0, iron.system.Time.step); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function reset() { | 
					
						
							|  |  |  | 		traitInits = []; | 
					
						
							|  |  |  | 		traitUpdates = []; | 
					
						
							|  |  |  | 		traitLateUpdates = []; | 
					
						
							| 
									
										
										
										
											2025-06-01 23:14:43 +00:00
										 |  |  | 		traitFixedUpdates = []; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 		traitRenders = []; | 
					
						
							|  |  |  | 		traitRenders2D = []; | 
					
						
							|  |  |  | 		if (onResets != null) for (f in onResets) f(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static function update() { | 
					
						
							|  |  |  | 		if (Scene.active == null || !Scene.active.ready) return; | 
					
						
							| 
									
										
										
										
											2025-06-02 04:11:02 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		iron.system.Time.update(); | 
					
						
							| 
									
										
										
										
											2025-08-14 20:26:33 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		if (lastw == -1) { | 
					
						
							|  |  |  | 			lastw = App.w(); | 
					
						
							|  |  |  | 			lasth = App.h(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (lastw != App.w() || lasth != App.h()) { | 
					
						
							|  |  |  | 			if (onResize != null) onResize(); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				if (Scene.active != null && Scene.active.camera != null) { | 
					
						
							|  |  |  | 					Scene.active.camera.buildProjection(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		lastw = App.w(); | 
					
						
							|  |  |  | 		lasth = App.h(); | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2025-06-02 16:21:25 +00:00
										 |  |  | 		if (pauseUpdates) return; | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		#if lnx_debug | 
					
						
							|  |  |  | 		startTime = kha.Scheduler.realTime(); | 
					
						
							|  |  |  | 		#end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Scene.active.updateFrame(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 04:11:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		time += iron.system.Time.delta; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (time >= iron.system.Time.fixedStep) { | 
					
						
							|  |  |  | 			for (f in traitFixedUpdates) f(); | 
					
						
							|  |  |  | 			time -= iron.system.Time.fixedStep; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 		var i = 0; | 
					
						
							|  |  |  | 		var l = traitUpdates.length; | 
					
						
							|  |  |  | 		while (i < l) { | 
					
						
							|  |  |  | 			if (traitInits.length > 0) { | 
					
						
							|  |  |  | 				for (f in traitInits) { | 
					
						
							|  |  |  | 					traitInits.length > 0 ? f() : break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				traitInits.splice(0, traitInits.length); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			traitUpdates[i](); | 
					
						
							|  |  |  | 			// Account for removed traits | 
					
						
							|  |  |  | 			l <= traitUpdates.length ? i++ : l = traitUpdates.length; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		i = 0; | 
					
						
							|  |  |  | 		l = traitLateUpdates.length; | 
					
						
							|  |  |  | 		while (i < l) { | 
					
						
							|  |  |  | 			traitLateUpdates[i](); | 
					
						
							|  |  |  | 			l <= traitLateUpdates.length ? i++ : l = traitLateUpdates.length; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (onEndFrames != null) for (f in onEndFrames) f(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#if lnx_debug | 
					
						
							|  |  |  | 		iron.object.Animation.endFrame(); | 
					
						
							|  |  |  | 		for (cb in endFrameCallbacks) cb(); | 
					
						
							|  |  |  | 		updateTime = kha.Scheduler.realTime() - startTime; | 
					
						
							|  |  |  | 		#end | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static function render(frames: Array<kha.Framebuffer>) { | 
					
						
							|  |  |  | 		var frame = frames[0]; | 
					
						
							|  |  |  | 		framebuffer = frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 04:11:02 +00:00
										 |  |  | 		iron.system.Time.render(); | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (Scene.active == null || !Scene.active.ready) { | 
					
						
							|  |  |  | 			render2D(frame); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#if lnx_debug | 
					
						
							|  |  |  | 		startTime = kha.Scheduler.realTime(); | 
					
						
							|  |  |  | 		#end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (traitInits.length > 0) { | 
					
						
							|  |  |  | 			for (f in traitInits) { | 
					
						
							|  |  |  | 				traitInits.length > 0 ? f() : break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			traitInits.splice(0, traitInits.length); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Scene.active.renderFrame(frame.g4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (f in traitRenders) { | 
					
						
							|  |  |  | 			traitRenders.length > 0 ? f(frame.g4) : break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		render2D(frame); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#if lnx_debug | 
					
						
							|  |  |  | 		renderPathTime = kha.Scheduler.realTime() - startTime; | 
					
						
							|  |  |  | 		#end | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static function render2D(frame: kha.Framebuffer) { | 
					
						
							|  |  |  | 		if (traitRenders2D.length > 0) { | 
					
						
							|  |  |  | 			frame.g2.begin(false); | 
					
						
							|  |  |  | 			for (f in traitRenders2D) { | 
					
						
							|  |  |  | 				traitRenders2D.length > 0 ? f(frame.g2) : break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			frame.g2.end(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Hooks | 
					
						
							|  |  |  | 	public static function notifyOnInit(f: Void->Void) { | 
					
						
							|  |  |  | 		traitInits.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeInit(f: Void->Void) { | 
					
						
							|  |  |  | 		traitInits.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function notifyOnUpdate(f: Void->Void) { | 
					
						
							|  |  |  | 		traitUpdates.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeUpdate(f: Void->Void) { | 
					
						
							|  |  |  | 		traitUpdates.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function notifyOnLateUpdate(f: Void->Void) { | 
					
						
							|  |  |  | 		traitLateUpdates.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeLateUpdate(f: Void->Void) { | 
					
						
							|  |  |  | 		traitLateUpdates.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-01 23:14:43 +00:00
										 |  |  | 	public static function notifyOnFixedUpdate(f: Void->Void) { | 
					
						
							|  |  |  | 		traitFixedUpdates.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeFixedUpdate(f: Void->Void) { | 
					
						
							|  |  |  | 		traitFixedUpdates.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | 	public static function notifyOnRender(f: kha.graphics4.Graphics->Void) { | 
					
						
							|  |  |  | 		traitRenders.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeRender(f: kha.graphics4.Graphics->Void) { | 
					
						
							|  |  |  | 		traitRenders.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function notifyOnRender2D(f: kha.graphics2.Graphics->Void) { | 
					
						
							|  |  |  | 		traitRenders2D.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeRender2D(f: kha.graphics2.Graphics->Void) { | 
					
						
							|  |  |  | 		traitRenders2D.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function notifyOnReset(f: Void->Void) { | 
					
						
							|  |  |  | 		if (onResets == null) onResets = []; | 
					
						
							|  |  |  | 		onResets.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeReset(f: Void->Void) { | 
					
						
							|  |  |  | 		onResets.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function notifyOnEndFrame(f: Void->Void) { | 
					
						
							|  |  |  | 		if (onEndFrames == null) onEndFrames = []; | 
					
						
							|  |  |  | 		onEndFrames.push(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public static function removeEndFrame(f: Void->Void) { | 
					
						
							|  |  |  | 		onEndFrames.remove(f); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |