Game Development Community

[Solution] Scene::onTamlPostRead fails with SceneControllers

by William Lee Sims · in Torque 2D Professional · 11/22/2013 (3:19 pm) · 0 replies

If your Scene is saved out with SceneControllers, it will not read them back on a load.

The offending code was this:
// Do we have any controllers?
    if ( pControllerNode != NULL )
    {
        // Yes, so fetch the scene controllers.
        SimSet* pControllerSet = getControllers();

        // Fetch children controller nodes.
        const TamlCustomNodeVector& controllerChildren = pControllerNode->getChildren();

        // Iterate controllers.
        for( TamlCustomNodeVector::const_iterator controllerNodeItr = controllerChildren.begin(); controllerNodeItr != controllerChildren.end(); ++controllerNodeItr )
        {
            // Is the node a proxy object?
            if ( !pControllerNode->isProxyObject() )
            {
                // No, so warn.
                Con::warnf("Scene::onTamlPostRead() - Reading scene controllers but node '%s'is not an object.", pControllerNode->getNodeName() );

                continue;
            }

            // Add the proxy object.
            SimObject* pProxyObject = pControllerNode->getProxyObject<SimObject>(false);

            // Is it a scene controller?
            if ( dynamic_cast<SceneController*>( pProxyObject ) == NULL )
            {
                // No, so warn.
                Con::warnf("Scene::onTamlPostRead() - Reading scene controllers but node '%s'is not a scene controller.", pControllerNode->getNodeName() );

                // Delete the object.
                pProxyObject->deleteObject();

                continue;
            }

            // Add to scene controllers.
            pControllerSet->addObject( pProxyObject );
        }
    }

It looked suspicious that there was an iterator over the children but that the iterator was never used. I modified the code to looks like this:
// Iterate controllers.
        for( TamlCustomNodeVector::const_iterator controllerNodeItr = controllerChildren.begin(); controllerNodeItr != controllerChildren.end(); ++controllerNodeItr )
        {
            // Is the node a proxy object?
            if ( !(*controllerNodeItr)->isProxyObject() ) // <--- This Line
            {
                // No, so warn.
                Con::warnf("Scene::onTamlPostRead() - Reading scene controllers but node '%s'is not an object.", (*controllerNodeItr)->getNodeName() ); // <--- This Line

                continue;
            }

            // Add the proxy object.
            SimObject* pProxyObject = (*controllerNodeItr)->getProxyObject<SimObject>(false); // <--- This Line

            // Is it a scene controller?
            if ( dynamic_cast<SceneController*>( pProxyObject ) == NULL )
            {
                // No, so warn.
                Con::warnf("Scene::onTamlPostRead() - Reading scene controllers but node '%s'is not a scene controller.", (*controllerNodeItr)->getNodeName() ); // <--- This Line

                // Delete the object.
                pProxyObject->deleteObject();

                continue;
            }

            // Add to scene controllers.
            pControllerSet->addObject( pProxyObject );
        }

This fixed my problem, but it'd be great if the original author could take a look at this and make sure it makes sense.

I'm in the middle of a 100 changes, so I can't get this in anytime soon. As soon as I get a chance, I'll test this better, trying to make sure it makes sense, and then I'll get it into dev.