Mem leack in my particle emittor code.
BlitzMax Forums/BlitzMax Beginners Area/Mem leack in my particle emittor code.
| ||
Strict
Graphics 1024,768,16,0
Global particle_count:Int = 0
Global maxparticles:Int = 100
Global direction:Int = Rand(0,360)
Global mx:Int, my:Int
SeedRnd MilliSecs()
SetMaskColor 255,0,255
AutoMidHandle True
Global particles:TImage = LoadImage("particle.png",MASKEDIMAGE)
SetImageFont Null
Global particle_list:TList = CreateList()
Type particle
Field x:Int, y:Int, d:Int, s:Int
Function create()
If MouseDown( KEY_MOUSELEFT)
Local p:particle = New particle
p.x = mx
p.y = my
p.d = Rand(0,360)
p.s = Rand(4,20)
ListAddLast particle_list,(p)
EndIf
End Function
Method draw()
For Local p:particle = EachIn particle_list
DrawImage particles,p.x,p.y,0
Next
End Method
Function update()
For Local p:particle = EachIn particle_list
p.x = Sin(p.d) * p.s + p.x
p.y = Cos(p.d) * p.s + p.y
Next
End Function
Function destroy()
For Local p:particle = EachIn particle_list
If p.x > 1030 Or p.x < -2
p = Null
EndIf
If p.y > 780 Or p.y < -2
p = Null
EndIf
Next
End Function
End Type
Repeat
Cls
mx = MouseX()
my = MouseY()
particle.create()
For Local p:particle = EachIn particle_list
p.draw()
Next
particle.update()
particle.destroy()
FlushMem
Flip
Until KeyHit(KEY_ESCAPE)
I have a destroy function in my type. I call it then call flushmem but it still seems that it doesnt release the or destroy instances. Any ideas? |
| ||
| I dont think you are understanding how the garbage collector works. Yes, setting the programs only reference to a tpe to null will free it - but you must lose all methods of accessing the particle. The problem is that you are getting a reference from another source and then nullifying it. this does nothing. There is still a reference within the linked list to it. Solution is to replace the code in destroy with: particle_list.clear you could nullify the list, flushmem and recreate but this is way cleaner |
| ||
| Because particle.update() and particle.destroy() should be in the For ... EachIn loop you defined above - in the code's current state, you don't know what "particle" is referring to. By the way, there's some bad programming practice you've got there! I feel there should be no tests or loops in your type's functions - those should be handled in your main loop. I can't see how your code's managing to create the particles in the first place - you're calling the create method on an object called 'particle' which hasn't been instantiated. Funny that! Ryan |
| ||
| Hi Bot Builder. I've already tried particle.clear in my destroy function but all this does is remove all instances even if they have not left the screen borders. i.e. if one particle leaves the screen they all get cleared then the list begins again. This is not what I want to happen. If one leaves the screen I want just that one particle to be removed and flushed. Not all of them. How can I fix my code to allow this? |
| ||
| Hi Ryan. I'll try what you said. Thanks :) |
| ||
Amon, this works...
Strict
Graphics 1024,768,16,0
Global particle_count:Int = 0
Global maxparticles:Int = 100
Global direction:Int = Rand(0,360)
Global mx:Int, my:Int
SeedRnd MilliSecs()
SetMaskColor 255,0,255
AutoMidHandle True
Global particles:TImage = LoadImage("particle.png",MASKEDIMAGE)
SetImageFont Null
Type particle
Global particle_list:TList
Field x:Int, y:Int, d:Int, s:Int
Function create()
If particle_list = Null particle_list = CreateList()
If MouseDown( KEY_MOUSELEFT)
Local p:particle = New particle
p.x = mx
p.y = my
p.d = Rand(0,360)
p.s = Rand(4,20)
ListAddLast particle_list,(p)
EndIf
End Function
Method draw()
For Local p:particle = EachIn particle_list
DrawImage particles,p.x,p.y,0
Next
End Method
Function update()
For Local p:particle = EachIn particle_list
p.x = Sin(p.d) * p.s + p.x
p.y = Cos(p.d) * p.s + p.y
Next
End function
Method destroy()
If x > 1030 Or x < -2 Or y > 780 Or y < -2
ListRemove(particle_list,Self)
EndIf
Rem
If p.y > 780 Or p.y < -2
p = Null
EndIf
End Rem
End Method
End Type
Repeat
Cls
mx = MouseX()
my = MouseY()
particle.create()
If particle.particle_list
For Local p:particle = EachIn particle.particle_list
p.draw()
Next
EndIf
particle.update()
If particle.particle_list
For Local p:particle = EachIn particle.particle_list
p.destroy()
Next
EndIf
FlushMem
DrawText MemAlloced(),0,0
Flip
Until KeyHit(KEY_ESCAPE)
You have to remove the particle from the list rather than making the type instance null. I changed the code to have the loop in the mainloop which, I think, is better. I didn't change any of the others though. <edit> I also changed the coord check to one line as I was getting errors. |
| ||
| instead of "p=null" do "ListRemove particle_list,p" The list contains a pointer to the particle. That is what keeps it alive |
| ||
| It works now. Thanks Coorae and all :) |