Mounting Pooled Object Broken
by Jacob Lynch · in Torque X 2D · 12/11/2009 (1:38 am) · 1 replies
Please let me know if I'm doing something wrong here, but this is what I observed. I mounted a T2DAnimatedSprite cloned from a template onto another T2DAnimatedSprite cloned from a different template at runtime. The first time I do this everything is fine. After reloading the level the code is executed again, but sometimes (most of the time) it doesn't mount properly.
Tracing through the engine code showed that the mounted object is lacking a tick callback for the T2DSceneObject class. This ProcessTick() function in T2DSceneObject is the function that calls the SnapToMount() function when the object is mounted, which is what makes the object look mounted. So after mounting my object it would just stay in one spot on the screen, instead of following the mountee object around as it should.
This occurs because the Clone() function in the TorqueObject class uses the Util.ObjectPooler to create my cloned object being mounted with the TickStarted flag set to true. Since the Util.ObjectPooler is reusing old T2DAnimation objects, sometimes they have the TickStarted flag set to true. When the returned clone object is then mounted, it calls SetTicking(), but since TickStarted is already true, it doesn't add a tick callback for the object. So the ProcessTick() function in T2DSceneObject never gets called for the mounted object, which results in it not following the mountee around.
Note that I'm not checking the Pool or PoolWithComponents option. That seems to be a different type of object pooling. I'm not really clear on this part, but there seems to be two different pools that objects are reused from in the Clone() function.
To get around this I changed the Clone() function in T2DSceneObject to the following code:
Now the TickStarted flag is set to false every time a T2DSceneObject is cloned. I don't know if this has any unintended consequences, but it fixed my problem.
Tracing through the engine code showed that the mounted object is lacking a tick callback for the T2DSceneObject class. This ProcessTick() function in T2DSceneObject is the function that calls the SnapToMount() function when the object is mounted, which is what makes the object look mounted. So after mounting my object it would just stay in one spot on the screen, instead of following the mountee object around as it should.
This occurs because the Clone() function in the TorqueObject class uses the Util.ObjectPooler to create my cloned object being mounted with the TickStarted flag set to true. Since the Util.ObjectPooler is reusing old T2DAnimation objects, sometimes they have the TickStarted flag set to true. When the returned clone object is then mounted, it calls SetTicking(), but since TickStarted is already true, it doesn't add a tick callback for the object. So the ProcessTick() function in T2DSceneObject never gets called for the mounted object, which results in it not following the mountee around.
Note that I'm not checking the Pool or PoolWithComponents option. That seems to be a different type of object pooling. I'm not really clear on this part, but there seems to be two different pools that objects are reused from in the Clone() function.
To get around this I changed the Clone() function in T2DSceneObject to the following code:
public override object Clone()
{
// before we copy components, add any auto-added components
_AddStockComponents();
T2DSceneObject clonedObj = base.Clone() as T2DSceneObject;
clonedObj._SetFlag((TorqueObjectFlags)T2DFlags.TickStartedFlag, false);
return clonedObj;
}Now the TickStarted flag is set to false every time a T2DSceneObject is cloned. I don't know if this has any unintended consequences, but it fixed my problem.
About the author
Torque 3D Owner Henry Shilling
Smokin Skull