Game Development Community

T3D 1.2 - onDeleteNotify called after namespace unlinked

by Fyodor -bank- Osokin · in Torque 3D Professional · 06/02/2012 (9:52 am) · 2 replies

Build: Torque 3D 1.2 (and all previous versions, including TGEA 1.7.2+)

Platform: Any

Target: Scripts and SimObject processing

Issues: onDeleteNotify(SimObject *obj) called after namespace of the object is unlinked, so you can't process this object in scripts.

If you want to use the object being deleted in scripts, it will fail. Example:
function GameBase::onUnmount(%this, %obj, %node)
{
   echo(%obj.getClassName());
}
The %obj.getClassName() will fail.
Unknown command 'getClassName'.
  Object (31735)

Prior TGEA 1.8 (as I remember, the namespace linkage has been changed around release of 1.7.2 or 1.8), the SimObject::onRemove() was very simple:
void SimObject::onRemove()
{
   mFlags.clear(Added);
}
and if you want to use namespace linkage, you would need to use custom code (like inside onAdd() and onRemove() in ScriptObject or GUIs).
But now, the namespace linkage is handled automatically in SimObject class.

The object registration process is fine, the "onAdd()" (where linkage is happening) is called at the end of registerObject().
And the unregisterObject() have onRemove() call before processing object's notifies.

Move the calls clearAllNotifications() and processDeleteNotifies() before the onRemove():
void SimObject::unregisterObject()
{
   mFlags.set(Removed);

   clearAllNotifications();

   processDeleteNotifies();

   // Notify object first
   onRemove();

..//skipped
}

#1
06/03/2012 (9:08 am)
Another good spot, bank. :)
#2
08/27/2012 (5:42 am)
Update: I've found a better way to fix this (which also fixes a couple of other issues if using complex scripts with callback).

Move the call to:
unlinkNamespaces();
from SimObject::onRemove()
to
void SimObject::unregisterObject()
right before the removal from the Sim, so the method now should look like this:
void SimObject::unregisterObject()
{
   mFlags.set(Removed);

   // Notify object first
   onRemove();

   // Clear out any pending notifications before
   // we call our own, just in case they delete
   // something that we have referenced.
   clearAllNotifications();

   // Notify all objects that are waiting for delete
   // messages
   if (getGroup())
      getGroup()->removeObject(this);

   processDeleteNotifies();

   unlinkNamespaces();

   // Do removals from the Sim.
   Sim::gNameDictionary->remove(this);
   Sim::gIdDictionary->remove(this);
   Sim::cancelPendingEvents(this);
}