Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParticlePlayer::stop not working correctly #64

Closed
lilligreen opened this issue May 7, 2013 · 4 comments
Closed

ParticlePlayer::stop not working correctly #64

lilligreen opened this issue May 7, 2013 · 4 comments

Comments

@lilligreen
Copy link
Contributor

@lilligreen lilligreen commented May 7, 2013

Here is what I have found:

The default call ParticlePlayer.stop() - getIsPlaying always returns true, no callback issued
stop(false, false) - ok
stop(false, true) - ok
stop(true, true) - getIsPlaying always true, no callback, effect is not killed

@MichPerry-GG
Copy link
Contributor

@MichPerry-GG MichPerry-GG commented May 8, 2013

Could you post a little more sample code and which assets you use? Need a full reproduction case to test and fix on our end.

@lilligreen
Copy link
Contributor Author

@lilligreen lilligreen commented May 8, 2013

The issue is here in ParticlePlayer.cc:

void ParticlePlayer::stop( const bool waitForParticles, const bool killEffect )
{
// Finish if we're not playing and there's no kill command.
if ( !mPlaying && !killEffect )
return;

// Fetch emitter count.
const U32 emitterCount = mEmitters.size();

// Are we waiting for particles to end?
if ( waitForParticles )
{
// Yes, so pause all the emitters.
for ( U32 emitterIndex = 0; emitterIndex < emitterCount; ++emitterIndex )
{
// Fetch the emitter.
mEmitters[emitterIndex]->setPaused( true );
}

// Set waiting for particles.
mWaitingForParticles = true;

// Flag as waiting for deletion if killing effect.
if ( killEffect )
mWaitingForDelete = true;

return;
}

// No, so free all particles.
for ( U32 emitterIndex = 0; emitterIndex < emitterCount; ++emitterIndex )
{
mEmitters[emitterIndex]->freeAllParticles();
}

// Reset the age.
mAge = 0.0f;

// Flag as stopped and not waiting.
mPlaying = mWaitingForParticles = mWaitingForDelete = false;

// Turn off paused.
mPaused = false;

// Set safe deletion.
setSafeDelete(true);

// Perform the callback.
if( isMethod( "onStopParticlePlayer" ) )
Con::executef( this, 1, "onStopParticlePlayer" );

// Flag for immediate deletion if killing.
if ( killEffect )
safeDelete();
}

The waitForParticles bool needs to be handled differently, when it is true the return is skipping half the function. If this was TorqueScript I would have provided a solution, but I am not yet comfortable tinkering with C++ source.

@lilligreen
Copy link
Contributor Author

@lilligreen lilligreen commented May 8, 2013

Sorry, forgot to include a sample test case. Here is a really quick toy. You can use the reset button in the sandbox to start and stop the player.

function TestToy::create( %this )
{
// Load the particle.
TestToy.Player = new ParticlePlayer();
TestToy.Player.Particle = "ToyAssets:bonfire";

// Add the player to the scene.
SandboxScene.add(TestToy.Player);
}


//-----------------------------------------------------------------------------

function TestToy::destroy( %this )
{
}

//-----------------------------------------------------------------------------

function TestToy::reset( %this )
{
// Toggle the player play/stop state.
echo(TestToy.Player.getIsPlaying());
if (TestToy.Player.getIsPlaying())
{
TestToy.Player.stop(true, true);
echo("stopped");
}else
{
TestToy.Player.play();
echo("playing");
} 
}

With full metrics on, you can see the player is stopped but not deleted. Plus it will not play again.

@capnlove
Copy link
Contributor

@capnlove capnlove commented Jul 1, 2013

Fixed in #84

The problem was relatively simple.

ParticlePlayer.stop(), when called with the 'WaitforParticles' argument set to true, paused each emitter.
This was fixed by unpausing all Emitters when ParticlePlayer.play() is called.

As for the ParticlePlayer's stop issue which was happening when both 'WaitforParticles' and 'KillEffect' were set to true, the problem was that if a ParticleEmitter's lifemode was set to INFINITE (the default), it never got to the part of code which handled the deletion of the emitter.

@capnlove capnlove closed this Jul 1, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants