回调到 Class(非实例)
Callback to Class (non-instance)
LWJGL 3 使用回调系统来处理输入,如下所示:
public class Main
{
...
public static void main(String[] args)
{
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
}
});
}
}
但是,我不希望出于其他目的在代码中间处理我的输入。
我可以使用 GLFWKeyCallback 扩展 class 并将该 class 的一个实例传递给 glfwSetKeyCallback(),但是我没有在实例中执行该函数。它是来自静态函数 (main) 的 运行。我不希望将代码从 main 移到实例对象中,因为它与我的编码风格冲突,这会让我感到压力,最终我会放弃并撤消它。
我现在的样子是这样的:
public class Main
{
private static GLFWKeyCallbackProxy glfwKeyCallbackProxy;
public static void main(String[] args)
{
glfwSetKeyCallback(window, glfwKeyCallbackProxy);
}
}
public class GLFWKeyCallbackProxy extends GLFWKeyCallback
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
我也很不喜欢这个,因为 GLFWKeyCallbackProxy 现在正在实现游戏的一部分,而不仅仅是被游戏使用。我相信它不利于良好的 OOP 结构,并且它具有紧密耦合。
理想情况下,我的解决方案希望在某种程度上等同于以下假设代码:
public class Main extends GLFWKeyCallback
{
public static void main(String[] args)
{
glfwSetKeyCallback(window, ???);
}
@Override
public static void invoke(long window, int key, int scancode, int action, int mods)
{
// This function now resides along side the code dealing with the rest of the game.
}
}
本质上,我希望回调函数将静态 class 级函数视为一个实例,即使它不是。
您将如何实现这一目标,或者我是否必须像上面的解决方案一样采用紧密耦合?
编辑:我忘了说,在任何解决方案中,我都需要访问 GLFWKeyCallback 的内部结构。假设我不能完全通过引用访问这些内部结构(通过公共或 getters/setters)。
我最终采用的解决方案:
public class Game
{
static long window;
public static void keyboardInvoke(long window, int key, int scancode, int action, int mods)
{
}
public static void mouseInvoke(long window, int button, int action, int mods)
{
}
public static void main(String[] args)
{
glfwSetKeyCallback(window, GLFWKeyCallback(Game::keyboardInvoke));
glfwSetMouseButtonCallback(window, GLFWMouseButtonCallback(Game::mouseInvoke));
}
}
我的第一个建议是开始使用 "handling my inputs in the middle of code for another purpose"。
现在,如果你真的不想那样做,那么你可以试试这个:
public class Main
{
public static void main(String[] args)
{
glfwSetKeyCallback(window, new GLFWKeyCallbackProxy());
}
class GLFWKeyCallbackProxy extends GLFWKeyCallback
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
}
您的内部 class 将可以访问包含 class 的成员,所以您应该没问题。
但我最强烈建议您考虑的建议是继续学习 Java 8,您可以在其中执行以下操作:
public class Main
{
public static void main(String[] args)
{
glfwSetKeyCallback( window, Main::invoke );
}
void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
...这样invoke()就变成了Main的成员方法,一切都美好了
此外,还有一个与手头问题无关的最后建议:永远不要在 static main() 中编写任何重要代码。 main() 应该做的第一件事(也是唯一一件事)是实例化一个对象并将控制权传递给它。
LWJGL 3 使用回调系统来处理输入,如下所示:
public class Main
{
...
public static void main(String[] args)
{
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
}
});
}
}
但是,我不希望出于其他目的在代码中间处理我的输入。
我可以使用 GLFWKeyCallback 扩展 class 并将该 class 的一个实例传递给 glfwSetKeyCallback(),但是我没有在实例中执行该函数。它是来自静态函数 (main) 的 运行。我不希望将代码从 main 移到实例对象中,因为它与我的编码风格冲突,这会让我感到压力,最终我会放弃并撤消它。
我现在的样子是这样的:
public class Main
{
private static GLFWKeyCallbackProxy glfwKeyCallbackProxy;
public static void main(String[] args)
{
glfwSetKeyCallback(window, glfwKeyCallbackProxy);
}
}
public class GLFWKeyCallbackProxy extends GLFWKeyCallback
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
我也很不喜欢这个,因为 GLFWKeyCallbackProxy 现在正在实现游戏的一部分,而不仅仅是被游戏使用。我相信它不利于良好的 OOP 结构,并且它具有紧密耦合。
理想情况下,我的解决方案希望在某种程度上等同于以下假设代码:
public class Main extends GLFWKeyCallback
{
public static void main(String[] args)
{
glfwSetKeyCallback(window, ???);
}
@Override
public static void invoke(long window, int key, int scancode, int action, int mods)
{
// This function now resides along side the code dealing with the rest of the game.
}
}
本质上,我希望回调函数将静态 class 级函数视为一个实例,即使它不是。
您将如何实现这一目标,或者我是否必须像上面的解决方案一样采用紧密耦合?
编辑:我忘了说,在任何解决方案中,我都需要访问 GLFWKeyCallback 的内部结构。假设我不能完全通过引用访问这些内部结构(通过公共或 getters/setters)。
我最终采用的解决方案:
public class Game
{
static long window;
public static void keyboardInvoke(long window, int key, int scancode, int action, int mods)
{
}
public static void mouseInvoke(long window, int button, int action, int mods)
{
}
public static void main(String[] args)
{
glfwSetKeyCallback(window, GLFWKeyCallback(Game::keyboardInvoke));
glfwSetMouseButtonCallback(window, GLFWMouseButtonCallback(Game::mouseInvoke));
}
}
我的第一个建议是开始使用 "handling my inputs in the middle of code for another purpose"。
现在,如果你真的不想那样做,那么你可以试试这个:
public class Main
{
public static void main(String[] args)
{
glfwSetKeyCallback(window, new GLFWKeyCallbackProxy());
}
class GLFWKeyCallbackProxy extends GLFWKeyCallback
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
}
您的内部 class 将可以访问包含 class 的成员,所以您应该没问题。
但我最强烈建议您考虑的建议是继续学习 Java 8,您可以在其中执行以下操作:
public class Main
{
public static void main(String[] args)
{
glfwSetKeyCallback( window, Main::invoke );
}
void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
...这样invoke()就变成了Main的成员方法,一切都美好了
此外,还有一个与手头问题无关的最后建议:永远不要在 static main() 中编写任何重要代码。 main() 应该做的第一件事(也是唯一一件事)是实例化一个对象并将控制权传递给它。