LWJGL 3 - closureError concerning garbage collection

Started by h1, December 10, 2014, 03:49:41

Previous topic - Next topic

h1

Hello,
I'm new to lwjgl and especially to version 3. Currently I'm porting my game code from v.2.9.1 to 3 and I have had no problems except the handling of all callbacks in conjunction with the mouse inputs. For now everything works fine though after my programm runns certain seconds. Whenever I use a glfwSetMouseButtonCallback or a glfwSetCursorPosCallback in my code I get the following error when calling the glfwPollEvents() method:

   org.lwjgl.system.libffi.ClosureError: Callback failed because the closure instance has been garbage collected.
   at org.lwjgl.glfw.GLFW.glfwPollEvents(Native Method)


I also use glfwSetWindowCloseCallback and glfwSetKeyCallback without issues.
Any hints how i can solve this behaviour?

-h1

SHC

Have you stored the CallBack instances in the main class? If you haven't stored them, then that is the source of the error.

// Class-level variables for storing handles
private static GLFWWindowSizeCallback winSizeCallback;
private static GLFWKeyCallback        winKeyCallback;
private static GLFWWindowPosCallback  winPosCallback;
private static GLFWCursorPosCallback  winCurPosCallback;
private static GLFWErrorCallback      errorCallback;

After you made the instances of the callbacks, you have to set the callbacks using glfwSet**Callback() functions.

// Yes, I do use Java 8 Lambdas
glfwSetWindowSizeCallback(window, winSizeCallback = GLFWWindowSizeCallback((win, w, h) ->
{
    Display.width = width;
    Display.height = height;

    resized = true;
}));

glfwSetKeyCallback(window, winKeyCallback = GLFWKeyCallback((win, key, scanCode, action, mods) ->
        Keyboard.setKey(key, action == GLFW_PRESS)));

glfwSetWindowPosCallback(window, winPosCallback = GLFWWindowPosCallback((win, xPos, yPos) ->
{
    Display.posX = xPos;
    Display.posY = yPos;
}));

glfwSetCursorPosCallback(window, winCurPosCallback = GLFWCursorPosCallback((win, xPos, yPos) ->
{
    mouseX = (int) xPos;
    mouseY = (int) yPos;
}));

Finally before calling glfwDestroyWindow(), release the callbacks using the release() method on the callback objects. Hope this helps.

xsupermetroidx

I ran into the same issue. To clarify on what the above poster said, this issue is caused by the "special" nature of how the callbacks operate using native code. The supplied APIs internally store no reference to the callback object you pass them (which is something that would be impossible in standard Java code). This is why you need to keep your own references to the callback objects... so that Java doesn't think they should be GCed when no references remain.