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