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: ArrayVoid> = null; static var onEndFrames: ArrayVoid> = null; static var traitInits: ArrayVoid> = []; static var traitUpdates: ArrayVoid> = []; static var traitLateUpdates: ArrayVoid> = []; static var traitRenders: ArrayVoid> = []; static var traitRenders2D: ArrayVoid> = []; 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: ArrayVoid> = []; #end 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); kha.Scheduler.addTimeTask(update, 0, iron.system.Time.delta); } public static function reset() { traitInits = []; traitUpdates = []; traitLateUpdates = []; traitRenders = []; traitRenders2D = []; if (onResets != null) for (f in onResets) f(); } static function update() { if (Scene.active == null || !Scene.active.ready) return; if (pauseUpdates) return; #if lnx_debug startTime = kha.Scheduler.realTime(); #end Scene.active.updateFrame(); 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 // Rebuild projection on window resize 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(); } static function render(frames: Array) { var frame = frames[0]; framebuffer = frame; iron.system.Time.update(); 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); } 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); } }