Kha
Kha copied to clipboard
Improve 'end before you begin' throws
The "end before you begin" throw is great - but if there is any other exception in between g.begin()/g.end() calls, the console will get bombed with "end before you begin" throws every frame, obscuring the original exception.
https://github.com/Kode/Kha/blob/master/Sources/kha/graphics4/Graphics2.hx#L1073
Also maybe move that code between some #if kha_debug or something? Or would that not be worth it?
It's an if for every begin/end call, i don't think it's worth it to wrap that tbh.
I know this is a pretty old thread but..
Continuing along Disar's thread of thought, I think something like the following would be pretty nice to have (assuming here that kha debug compile is compatible with the debug haxe compilation flag).
index 7390d666..388792be 100644
--- a/Sources/kha/graphics4/Graphics2.hx
+++ b/Sources/kha/graphics4/Graphics2.hx
@@ -1024,13 +1024,17 @@ class Graphics2 extends kha.graphics2.Graphics {
}
override public function begin(clear: Bool = true, clearColor: Color = null): Void {
- if (current == null) {
- current = this;
- }
- else {
+ #if debug
+ if (current != this) {
throw "End before you begin";
}
-
+ #end
+
+ if (current != null) {
+ current.flush();
+ current.g.end();
+ }
+ current = this;
g.begin();
if (clear) this.clear(clearColor);
setProjection();
@@ -1048,15 +1052,15 @@ class Graphics2 extends kha.graphics2.Graphics {
}
public override function end(): Void {
- flush();
- g.end();
-
- if (current == this) {
- current = null;
- }
- else {
+ #if debug
+ if (current != this) {
throw "Begin before you end";
}
+ #end
+
+ current.flush();
+ current.g.end();
+ current = null;
}
private function drawVideoInternal(video: kha.Video, x: Float, y: Float, width: Float, height: Float): Void {
We could even have this bit:
if (current != null) {
current.flush();
current.g.end();
}
inside an #else block for just a little bit less overhead on debug builds.
You don't need "I know it's an old thread" excuses for open issues, absolutely feel free to help fixing all of them 😅
With Macro it is possible to ensure begin and end are always called.
khage have this thing (with more abstraction too) : https://github.com/wighawag/kha3d_examples/blob/master/tutorial08/Sources/Empty.hx#L110
Not sure if khage works with Haxe 4 but Haxe 4 might even have better way to do it.
But that's too restrictive me thinks, things might involve some conditionals.
With Macro it is possible to ensure begin and end are always called.
You don't even really need a macro for this, can do something like
frame.usingG4(g -> {
g.clear(...);
g.draw(...);
});
The anon function there is nicely inlined because it's an immediately-invoked function (see my post from 2017 ^^).
IMHO, that's pretty redundant. If all draw calls were happening at one place anyway,
frame.usingG4(g -> {
g.clear(...);
g.draw(...);
});
this takes exactly the same amount of effort to write as:
var g = frame.g4;
g.begin()
g.clear(...);
g.draw(...);
g.end();
I still stand firmly by my fix, which keeps everything mostly the same while addressing both the original issue, while also a) getting rid of "end before you begin" & "begin before you end throws" in release builds and b) automatically calls begin/end, just in case something goes wrong.
IMHO, it is also important to note here that automatically calling before/end should be a fallback in case something unexpected and bad happens, not something to rely on...
Although, that kind of inline-ability does have some of the nice vibes something like cascaded function calls or chaining have... I still don't think it should be part of the core Graphics2 class. Maybe part of GraphicsExtensions?