Graphics commands without Graphics errors

Archives Forums/BlitzMax Bug Reports/Graphics commands without Graphics errors

*(Posted 2008) [#1]
Before anyone says I know this is common sense:

Using Setcolor or any 2d graphics command before using the graphics commands kills Blitz I get the compiling and executing then I get 'unhandled memory exception error' in the output window (with debug off) with it on it tells me 'attempt to access field or method of null object'.

Surely it would be more 'user' friendly if it said 'Error graphics mode not set'.

It seems the null object error is a catch all for all errors where there is no error message.


Dreamora(Posted 2008) [#2]
No it is actually exactly that.

it tries to access the global TGraphics object to operate on it. As graphics is not called it is null -> null object access violation.

You can easily use Try - Catch - EndTry and creategraphics within to check if a given graphics mode was "setable" and react to the creation error yourself instead of assuming it works and assume that BM plays nicely if your app doesn't do its homework and error handling :D


Azathoth(Posted 2008) [#3]
The graphics commands should throw their own exceptions.


*(Posted 2008) [#4]
it should have its own error message IMHO


Dreamora(Posted 2008) [#5]
???
Graphics if failed throws an exception. Catch it and handle it in your own way.
Thats why Try - Catch - EndTry exists after all!

Any 2D operation that is performed on a null object must logically result in a null object access violation (and doing 2D without prior graphics IS accessing null object as explained above)


tonyg(Posted 2008) [#6]
I agree with Edzup and Azathoth.
It would be nice for the error messages to relay the error AND the likely cause. I doubt it will happen though.

@Dreamora, using try/catch/endtry on all possible errors that might be output from Bmax is madness.


Dreamora(Posted 2008) [#7]
No thats called: professional error handling
Or do you believe that all the nice error messages you see in other apps are C++ error messages?

Try - Catch - EndTry is the only way to get a usefull error handling.
BM can not know that you killed a graphics command because the error won't be raised until function xy tries to access the _graphics:TGraphics which is null and that basically can be about anything. graphic command but potentially anything else you added to the module like SetCanvasGraphics etc.

Giving BM the possibility to find the source of the error means that it is slower during the times it does not error ...
Quite a great thing just to satisfy users that don't get the basics of common error handling practices.

If you are too lazy for it, invest in Grey Aliens Framework. It will handle this kind of stuff for you without any extra work for you.


tonyg(Posted 2008) [#8]
I disagree.
If the graphics object/command is not set then it is professional error handling for the application being used to try/catch/whatever or emit a *meaningful* error message.
giving BM the possibility to find the source of the error means that it is slower during the times it does not error ...

I thought that was what debug mode and compiler directives was for... no?


*(Posted 2008) [#9]
Dreamora: Basically your saying that I should 'adjust' all the drawing commands to add the try...whatever to catch errors. Surely it would be simpler to add one boolean variable to the system and when the graphics mode is set make it True, when the graphics commands are called simply check it and if its false just whack out a 'graphics mode not set' error message.


GfK(Posted 2008) [#10]
The error mode is kinda correct, imho.

When you use the Graphics() command, all you're doing is creating a graphics Object to draw images etc onto. If that object doesn't exist (because you haven't created a Graphics object yet), "attempt to access field or method of null object" is a perfectly acceptable and accurate error message.

A quick look in the debugger should help you to identify what the problem is. You're dealing with two objects, for example, a TImage and a TGraphics object. If you have a Null object error, and you know one object (the image) definitely exists, then the other object is logically where the problem is.


Azathoth(Posted 2008) [#11]
I'm saying it would make more sense if something like a TNullGraphicsException was thrown.


tonyg(Posted 2008) [#12]
If it returned the object that was null it would be enough for me. Having said that it wasn't a big deal until the suggestion of 'Professional Error Handling' was raised.


Dreamora(Posted 2008) [#13]
EdzUp: no I'm saying that you should check if the Graphics() call succeeded and if not, handle the error!
As the code order is "predefined" at code time, you surely should be able to do guarantee before calling any drawing command, shouldn't you?
Otherwise you have a serious problem with your code, normally called Spaghetti Code

Azathoth: Bad idea. That would mean that EVERY drawing command would need to check if _graphics <> null.
bye performance!

Whats the problem to just do:
Try
  Graphics(width,height,depth)
Catch(e:object)
  runtimeerror("Error found: " + e.toString() )
endtry

' all drawing commands after this point!

The idea is to check if the graphics creation fails, not to check on every draw if the programmer was just to stupid to put a Graphics before calling it.
Thats pure nonsense as the function call order will not change during compilation so you can guarantee that if graphics initialization succeeded -> it will remain working so continue and draw stuff.
If it didn't succeed -> you must handle the error and do not draw anything.
you do not need any further try - catch - endtry for the graphics post that point! Either the graphics context is created or not, point.

I think you all totally missunderstood what I pointed out.
The drawing stuff does not check for consistency <> null anymore, it would be a total performance overkill to do so.


tonyg(Posted 2008) [#14]
... but then either
a) the user hasn't forgotten the graphics command
or
b) the user has already tried a Max2D command before the try/catch
Obviously the user could load a dummy image and draw it with Try/Catch but, again, it would be enough for them to remember the graphics command.
.
As Edzup states
Before anyone says I know this is common sense:
and it doesn't take long to either not make the mistake or know what to look for.
However, there are enough posts to suggest a few make this mistake probably early on.


Azathoth(Posted 2008) [#15]
Azathoth: Bad idea. That would mean that EVERY drawing command would need to check if _graphics <> null.
bye performance!
Only if its thrown in debug mode.


*(Posted 2008) [#16]
Dreamora: I do agree with you in priciple but im just saying that to people coming to BlitzMax from the other blitz languages the error isnt that explanatory.

Basically its always thrown as soon as setcolor or any of the drawing commands are called and unlike Blitz3d there is no canvas setup to draw to as default.

The main thing here I think it would be good in the debugger to whack out a 'Graphics mode not set' error or something like that. This may throw performance down a bit in the debugger but as soon as its compiled properly there wouldnt be a problem.


Dreamora(Posted 2008) [#17]
Well then you definitely need to read the documentations now on Try, Catch, Throw!

Throw is mainly for release mode.
Debug mode error prevention can be enforced through assert, as they are simply ignored in release, while Throw -> Try - Catch - EndTry are the release time error handling mechanisms that work independently of the scope depth to allow the programmer to handle errors at all, as you otherwise will only get the well known Memory access violation errors of Blitz3D / BlitzPlus.


tonyg:
Users don't move anything. Users get compiled applications. Its the programmer that is in charge to use think about how to handle errors.

a) if he hasn't forgotten it, then it failed -> will be cought by try catch
b) there is no before, its within the try catch and it is the only thing within the try catch. if the generation fails the user will get a usefull error message (if the programmer added one logically)


As mentioned, just copy paste above code and replace your graphics with it. You won't run into the null object error anymore unless you are not even capable of first initializing objects you are working on (thats programmers basics, so I assume that shouldn't be a problem if you post bug reports)


Azathoth(Posted 2008) [#18]
Well then you definitely need to read the documentations now on Try, Catch, Throw!

Throw is mainly for release mode.
Debug mode error prevention can be enforced through assert, as they are simply ignored in release, while Throw -> Try - Catch - EndTry are the release time error handling mechanisms that work independently of the scope depth to allow the programmer to handle errors at all, as you otherwise will only get the well known Memory access violation errors of Blitz3D / BlitzPlus.
BRL seems to disagree as TNullObjectException and TArrayBoundsException only gets thrown in debug mode. It would appear you need to read the documentation yourself.


Dreamora(Posted 2008) [#19]
TArrayBoundsException is only thrown in debug because the module part that throws it isn't even compiled into in release mode. Arrays would be worthless slow if it was compiled into.

Don't know about the nullObjectException, as I don't know what would be throwing it, but I would guess its a pure debug level module part as well.

And I didn't say that try catch can not be used in debug mode. But its main purpose is the release mode usage where you have want to have high performance but still be able to handle errors and try catch throw is the most efficient way to do that (all others enforce polling)


tonyg(Posted 2008) [#20]
@Dreamora, You mentioned GA Framework which catches and handles errors on behalf of the user/customer/programmer. It would be nice if Bmax did the same in this case.
I have never had a graphics command fail on me so the try/catch around it is redundant imo.
I can issue a loadimage/drawimage before the graphics command or within a graphics mode change to cause the problem which the try/catch won't detect.
And, of course, I might not put a graphics command in by mistake.
Still, I won't fall for it, I doubt BRL will act on it and I really don't understand your "professional like me" attitude so I'll get my coat.


Dreamora(Posted 2008) [#21]
Well it will fail if DX7 can not init a 3d window for example (old graphic cards with no 3D windowed hardware acceleration). The other possibilities are when you start out with OpenGL and need to fallback to DX.

and no you can not do it within a graphics mode change.
BM is not parallel so until the mode change has finished, you can not execute anything else. Nor is DX7 multithreaded so while the context is created, DX won't do anything side a side to it.


My main point was / is that people recently start to flood the bug board with things that are no bugs but lazyness on their end as programmers. BM is a full fledged programming language and "handling" that you want to happen is up to you to do. Originally Graphics didn't even throw an exception, that was introduced to allow you to handle the graphics creation error at all. Most just don't do it and run into the problem of null object errors due to their code errors. BM is a programming language that offers a 2D programming framework, not a "I'll do anything for you" 2D engine, in that case TGB / TXB would be the right choice for you most likely.

but yeah, I'm off topic as well.
Made clear what I meant and will leave this thread on its own as it isn't a bug at all.


*(Posted 2008) [#22]
I just intended to draw BRL's attention to the fact, I believe that this sort of thing should be added to the transition page for Blitz3d>>Max or something like that as people coming from Blitz3d may be thrown by the errors that Max comes out with.

This is my last post on the subject but I do believe that this does need some work somewhere.