Attempt to access field or method of Null object ?

BlitzMax Forums/BlitzMax Beginners Area/Attempt to access field or method of Null object ?

Michel R.(Posted 2013) [#1]
Hello everyone !
I'm creating my first game with Blitzmax and I've encountered a problem in this function:

Function Animation_Hero_Ennemis:Byte()
' ======================
' Animation en début de niveau
' pour placer le héro et les gardes
'
' on fait d'abord apparaitre les gardes
'
Local flg:Byte = True
Local taille:Float = 4.0

If Enemis.Count() Then
For Local i:Int = 1 To 30
If Gestion_Clavier_Joystick() Then
flg = False
Exit
EndIf
Cls
SetScale(taille, taille)
For Local ii:TEnemy = EachIn Enemis
If ii.Update() Then
' Enemis.Remove(i)
End If
Next
taille:-0.1
Local time:TTimer = CreateTimer(30)
Flip
Repeat
Until WaitTimer(time) 'petite tempo >>>>>
StopTimer(time)
Next
EndIf

When I try my program in debug mode, sometimes the program stops in the function (in timer.bmx):

Function WaitTimer( timer:TTimer )
Return timer.Wait() <<<<<< at this line
End Function

with this error:
RUNTIME ERROR:Attempt to access field or method of Null object

I don't understand why because this function is called by the line
"until WaitTimer(time)" and time is created 2 lines up...

Can someone explain me this bug ?
Thanks


matibee(Posted 2013) [#2]
This code runs ok for me:

SuperStrict 

Graphics 800,600
Global frame:Int 

While Not AppTerminate()
Cls
DrawText( frame, 50, 50 )
Local time:TTimer = CreateTimer(30) 
Flip
Repeat
Until WaitTimer(time) 'petite tempo >>>>>
StopTimer(time) 
frame :+ 1
Wend 


But as soon as StopTimer() is commented out, it crashes.

I believe there is a limit to a number of timers your app can create, once that limit is reached CreateTimer will return NULL, which is why WaitTimer(time) fails.

I think it might be down to old timers not getting cleaned up fast enough.

A simpler way would be to drop timers and use a millisecond timer;

local msNow:Int = millisecs()
while millisecs() < msNow + 300
wend 


Or a better way might be to stop using timing tricks altogether and use a vsync limited refresh by using 'Flip 1'.


GfK(Posted 2013) [#3]
I hit the timer limit once, myself. I believe its something like 16.

I now just create a single, 10hz timer (not many people need timing accurate to 1ms), and use that for all timing stuff as you can run any number of pseudo-timers from it. I also reset it at any opportunity, ie between levels, to get around and possible overflow issues... Even though a 10hz timer won't overflow for nigh on a year anyway.


Michel R.(Posted 2013) [#4]
Thanks for your replies.
I thought that StopTimer(time) frees the variable 'time' and the timer created.

I'll try with millisecs().

Thanks again

Michel


matibee(Posted 2013) [#5]
I thought that StopTimer(time) frees the variable 'time' and the timer created.


Yes. In theory. But I think they will continue to exist until the garbage collector deals with them, which is whenever it feels ready. You could force a garbage collect with a call to GCCollect() but it's generally a last resort.