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 :) |