Removing all vent particles immediately

@soin08, thank you for these insights. Very helpful!

@Raye welcome!  :slight_smile:

Nice to know you’re using CBEffects. Fortunately, you won’t have to worry about this, because it’s built-in in the CBEffects ‘vent.clean()’ function.

[lua]

vent:stop()

vent:clean()

[/lua]

To completely destroy the vent, you’ll need the destroy command. You’ll run into problems if you only nil out the vent, because each vent has a display group attached to it:

[lua]

vent:destroy() – Calls stop(), clean(), and removes all required objects

[/lua]

Sorry about the docs not being clearer :slight_smile:

  • C

Thank you for your response, Caleb. vent:destroy() throws me an error in the latest version of CBEffects. Please try this example:

local CBE = require("CBEffects.Library") local vent = CBE.newVent { preset = "burn" } vent:start() local function onScreenTap() vent:destroy(); end Runtime:addEventListener("tap", onScreenTap)

Whoops! Should be fixed now.

  • C

Awesome :slight_smile:  Thanks, Caleb!

HOLD ON. Just tried it in my app - still gives me the same error…  :unsure:

Are you sure you’re not tapping more than once?

  • C

Never mind, it works great. Back then I tried it in my app and it would crash, must’ve been because _destroy _was called more than once somewhere else in the code. Sorry for misleading, Caleb.

  • Ilya

No problem :slight_smile:

  • C

I downloaded CBEffects today (5 Jul 2014). Since I had some problems with destroying vents so I searched the forum for this problem and found this thread. When tried soin08’s small example above it throws the following error:

File: CBEffects/cbe\_core/vent\_core/core.lua Line: 147 Attempt to index upvalue 'p' (a nil value)

When I immediately touch the screen, everything is fine. But when I wait a little longer (maybe when the first particle has died?) I get the error.

@Raye, I had the same problem in the latest version and thought the bug had not been fixed but than I tried to use a flag to make sure that the onTap event fires only once and it worked, which means there is no bug.

@soin08

Ok, I added a flag. And I still got the same error (most of the time, not always). So I added some print statements, to see whats going on.

-------------------------------------------------------------------------------- -- main.lua -------------------------------------------------------------------------------- display.setStatusBar(display.HiddenStatusBar) -------------------------------------------------------------------------------- -- Create Sample Effect -------------------------------------------------------------------------------- local CBE = require("CBEffects.Library") local isDestroyed = false local vent = CBE.newVent {     preset = "burn" } vent:start() local function onScreenTap()    print("onScreenTap() - isDestroyed -\> " .. tostring(isDestroyed))    if isDestroyed == false then       print("vent = " .. tostring(vent) )       vent:destroy()       isDestroyed = true       print("vent destroyed - isDestroyed -\> " .. tostring(isDestroyed))       print("vent = " .. tostring(vent) )    end end Runtime:addEventListener("tap", onScreenTap)

Sometimes it works, but sometimes I get the error as mentioned above. As far as I can tell from the console output the vent:destroy() is called only once. Or am I wrong?

@Raye, you’re right… I too get that error sometimes. You can use my solution until this gets fixed. Or could it be a Corona bug? Let’s see what Caleb (the creator of the amazing CBEffects) thinks about it.

For me it works fine like 9 times out of 10 on avarage.

@sonoi08 Phew, I’m glad you get the error, too.  :lol:

As far as have looked at the code the p._kill() function tries to kill a p that has a nil value. I put a

if p == nil then return end

at the beginning of p._kill() but I don’t know if this good programming practice in Corona/Lua.

I’m relative new to Corona and Lua. In the Examples/Tuts/Docs I have never seen practices that an object is checked if it is nil before deleting/working on it. But I know this practice from other programming languages.

Ok, let’s see if Caleb can help.

@Raye, such practicies do exist in Lua. For example in this topic @Roaminggamer talks about how you can determine wheter a displayObject has been removed to safely use the _onComplete _function passed to the transition. I use a different method btw.

@soin08 Ah thank you. Your technique with storing the transitions in a table and cancel is even more elegant.

Right now the hardest part for me in Corona developing is to really clean up a complex scene with (OOP objects and inheritance objects) when it comes to transition to a different scene. It is rather frustrating: the ingame works really nice, but such a thing like simple transition to the menu (or an pause overlay) really bothers me.

Thanks for alerting me of this, it should be fixed now.

Explanation? CBEffects uses internally a structure called a VS-T (I can’t remember what it stands for; it had a meaning months ago when I created it :slight_smile: ), which allows you to mark objects for removal from it. Then, whenever you want, you can clear those objects. Kind of like a delayed table.remove.

Anyhow and anyhoo, when a particle is ._kill()-ed, it’s marked for removal in the VS-T particle container. CBEffects clears the particle container every few frames, so there are “dead” particle references in there most of the time. When you call vent:destroy(), CBEffects iterates through all particles in that container and calls ._kill() on them - including the ones that have been marked for removal already. Obviously, if the container hasn’t been cleared at that instant, it tries to ._kill() particles that are already “dead”, which creates that error. I just uploaded a fix that clears the particle container right before iterating through them, so it’s fixed.

  • C

@Caleb Tested and working! Cool! Thank you for this fast fix and explanation and this great module at all.

No problem :slight_smile:

  • C