app crashes if I call removeEventHandler

classic Classic list List threaded Threaded
2 messages Options
bclay bclay
Reply | Threaded
Open this post in threaded view
|

app crashes if I call removeEventHandler

I am trying to get the geodetic location of a point where the user clicks the left mouse button.  The code below is initiated by calling CaptureCursorLocation.  That sets up a callback that waits for the user to click the left button anywhere on the map.  After they click the button SetCursorLocation is called to pass the location up to the parent. For the most part that works except that I cannot stop the callback.  When I call removeEventHandler(mCursorLocationhandler); the application crashes as soon as it returns from frame().  The error message in Visual Studio is the familier "Expression List iterator is not incrementable.  The stack trace only shows that it was in osg157-osgViewerd.  If I don't call the removeEventHandler there is no crash but it keeps going through the callback as would be expected.

Is there some other way to get a user selected location to dynamically place things on the map?

Bruce


the OsgEarthWindow header includes the following line

        osg::ref_ptr<osgGA::EventHandler >mCursorLocationhandler;

this callback is in the top of the OsgEarthWindow.cpp file

struct GetCursorLocationCallback : public osgGA::GUIEventHandler
{
        GetCursorLocationCallback(OsgEarthWindow *parentWindow, osgEarth::MapNode *mapNode)
        {
                mParentWindow = parentWindow;
                mMapNode = mapNode;
        }

        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
        {
                if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH  && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
                {
                        int mouseX = ea.getX();
                        float mouseY = ea.getY();

                        osg::Vec3d world;
                        if (mMapNode->getTerrain()->getWorldCoordsUnderMouse(aa.asView(), ea.getX(), ea.getY(), world))
                        {
                                osgEarth::GeoPoint mapPoint;
                                mapPoint.fromWorld(mMapNode->getMapSRS(), world);

                                double latitude = mapPoint.y();
                                double longitude = mapPoint.x();
                                double altitude = mapPoint.z();

                                mParentWindow->SetCursorLocation(latitude, longitude, altitude);

                        ea.setHandled(true);
                        }

// aa.requestRedraw();
                        return true;
                }
                return false;
        }

        OsgEarthWindow *mParentWindow;
        osgEarth::MapNode *mMapNode;

};



///////////////////////////////////////////////////////////////////////////////
int OsgEarthWindow::CaptureCursorLocation()
{
        int status = -1;

        mCursorLocationhandler = new GetCursorLocationCallback(this, mMapNode);

        if (mCursorLocationhandler != NULL)
        {
                mOsgViewer->addEventHandler(mCursorLocationhandler);

                status = 0;
        }
        return(status);
}

///////////////////////////////////////////////////////////////////////////////
void OsgEarthWindow::SetCursorLocation(double latitude, double longitude, double altitude)
{
        if (mCursorLocationhandler != NULL)
        {
                mOsgViewer->removeEventHandler(mCursorLocationhandler);

// mCursorLocationhandler->unref();

// mCursorLocationhandler = NULL;

                mNewCursorLocationSet = true;
        }
}

///////////////////////////////////////////////////////////////////////////////
void OsgEarthWindow::GetCursorLocation(double &latitude, double &longitude,
                                        double &altitude, bool &newLocation)
{
        mCursorLatitude = latitude;
        mCursorLongitude = longitude;
        mCursorAltitude = altitude;

        mNewCursorLocationSet = false;
}

gaoyj gaoyj
Reply | Threaded
Open this post in threaded view
|

Re: app crashes if I call removeEventHandler

It is recommended to handle deletion events in the update callback.