removeInputListener() crash
by Michael Smith · in Torque 2D Beginner · 10/20/2013 (11:38 pm) · 2 replies
I am getting a crash when I call SandboxWindow.removeInputListener() during an OnTouchUp callback. Am I using this the right way?
I am using the current Master branch. I am running this the Sandbox as a module called Swing.
Some context: I have a sprite object to which I assign the class "Fingertip". It follows a users finger as the user drags it around the screen. I do not want it processing extra input callbacks so I add it as an input listener when it is active and remove it when it is inactive. Here is the intended life cycle:
1 The fingertip sits idle off the play area until the user touches the screen.
2 A script object gets an OnTouchDown call and attaches a target joint to the fingertip and adds itself as an input listener.
3 The fingertip tracks the touch position by updating the target joint in response to onTouchMoved calls.
4 When the user removes the touch the fingertip object receives an onTouchUp call. It deletes the joint, moves itself offstage, and removes itself as an input listener.
The trouble is that when it tells SandboxWindow to remove it as in input listener Torque crashes. The crash occurs as the onTouchUp call exits.
Do I need to schedule it instead of just calling it at this time in the execution? If so, what is the syntax of that schedule call?
I am using the current Master branch. I am running this the Sandbox as a module called Swing.
Some context: I have a sprite object to which I assign the class "Fingertip". It follows a users finger as the user drags it around the screen. I do not want it processing extra input callbacks so I add it as an input listener when it is active and remove it when it is inactive. Here is the intended life cycle:
1 The fingertip sits idle off the play area until the user touches the screen.
2 A script object gets an OnTouchDown call and attaches a target joint to the fingertip and adds itself as an input listener.
3 The fingertip tracks the touch position by updating the target joint in response to onTouchMoved calls.
4 When the user removes the touch the fingertip object receives an onTouchUp call. It deletes the joint, moves itself offstage, and removes itself as an input listener.
The trouble is that when it tells SandboxWindow to remove it as in input listener Torque crashes. The crash occurs as the onTouchUp call exits.
Swing.FingertipController = new ScriptObject()
{ class = SwingFingertipController; };
function SwingFingertipController::initialize( %this )
{
SandboxWindow.addInputListener( %this );
}
function SwingFingertipController::onTouchDown(%this, %touchID, %worldPosition)
{
%numTouches = getWordCount( %touchID );
if( !isObject( fingertip0 ))
{
echo( "SwingFingertipController::onTouchDown error: no fingertip0 object" );
return;
}
for( %i = 0; %i < %numTouches; %i++)
{
%currentID = getWord(%touchID, %i);
// Assign ID to a fingertip
for( %j = 0; %j < $SwingNumFingertips; %j++ )
{
%nextFingertip = "fingertip" @ %i;
%position = getWords(%worldPosition, (2 * %i), (2 * %i + 1));
if( %nextFingertip.assignTouch(%currentID, %position ) ) // Fingertip::assignTouch returns true if the assignment is accepted,
// or false if the fingertip already has an assignment
{
break;
}
} // If end of loop is reached without assigning a touch to a fingertip object then the touch is effectively ignored
}
}
//-----------------------------------------------------------------------------
function Fingertip::assignTouch(%this, %touchID, %position)
{
if( %this.amAssigned == true )
{ return false; }
%this.amAssigned = true;
%this.myTouchID = %touchID;
%this.setPosition( %position.x, %position.y );
%myScene = %this.getScene();
%maxForce = 100; // A magic number
%this.myJointID = %myScene.createTargetJoint( %this, %position.x, %position.y, %maxForce );
if( %this.myJointID == -1 )
{ echo( "Fingertip::assignTouch error: unable to create joint" ); }
SandboxWindow.addInputListener( %this );
return true;
}
function Fingertip::onTouchUp(%this, %touchID, %worldPosition)
{
if( %this.amAssigned == false )
{
echo( "Fingertip::onTouchUp error: unassigned fingertip receiving events" );
return;
}
%numTouches = getWordCount( %touchID );
for( %i = 0; %i < %numTouches; %i++)
{
%currentID = getWord(%touchID, %i);
if( %this.myTouchID $= %currentID )
{
// Break contact
%this.amAssigned = false;
%this.myTouchID = -1;
%this.setPosition( 20, 20 ); // Exit stage left
%this.setLinearVelocity( 0, 0 );
%myScene = %this.getScene();
%myScene.deleteJoint( %this.myJointID );
%this.myJointID = -1;
// Turn off input listening while inactive.
SandboxWindow.removeInputListener( %this ); // Causes a crash!
}
}
} // CRASH HERE!Do I need to schedule it instead of just calling it at this time in the execution? If so, what is the syntax of that schedule call?
About the author
Bible translator by day-- game programmer by night
#2
10/22/2013 (6:30 am)
I usually use an EventManager so that I can post the removal event to delete the object using an agent outside of the callback. Scheduling works for most things, but don't even think about trying to delete an object in its own class callbacks.... lol
Michael Smith
function Fingertip::onTouchUp(%this, %touchID, %worldPosition) { .... // Turn off input listening while inactive. //SandboxWindow.removeInputListener( %this ); // Crashes in this context %this.schedule(1, stopListening); // Schedule call instead .... } function Fingertip::stopListening(%this) { SandboxWindow.removeInputListener( %this ); // Does not crash in this context }