3
\$\begingroup\$

I am using glfw and let's say I track controllers with a simple struct:

struct Controller {
  int id;
  std::vector<InputListener> listeners;
}
std::vector<Controller> controllers;

And I have setup a callback to detect connection and disconnection events with glfwSetJoystickCallback.

Now every frame I iterate over the controllers and poll their input states to detect button presses etc. But when the GLFW_DISCONNECTED event is triggered, and I try to remove the controller from the vector of controllers, the iteration loop crashes as the iterator becomes invalid.

for(auto it = controllers.begin(); it != controllers.end(); ++it){
  // Poll inputs...
}

void joystick_callback(int joy, int event)
{
    if (event == GLFW_CONNECTED)
    {
        // The joystick was connected
    }
    else if (event == GLFW_DISCONNECTED)
    {
        for(auto it = controllers.begin(); it != controllers.end();){
          if((*it).id == joy){
            it = controllers.erase(it);
            return;
          }
          ++it;
        }
    }
}

I tried protecting controllers with a mutex, but on disconnection, locking the mutex throws an exception because it's double locking, which leads me to believe it's on the same thread.

So how does this execution work then? Does the original loop pause, while the callback takes over, then after it's done the loop resumes execution?

I was able to fix it by adding a disconnected flag to the Controller struct, and then test for it in the loop, which will then remove the controller.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.