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扩展一个类,并将该类的实例传递给glfwSetKeyCallback(),但是我没有在实例中执行该函数。 它从静态函数(main)运行。 我不希望将代码从main转移到instanced对象,因为它与我的编码风格冲突,这会让我感到压力,最终我会陷入困境并将其撤消。
我现在的方式是这样的:
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. } }本质上我希望回调函数将静态类级别函数视为一个实例,即使它不是。
您将如何实现这一目标,或者我是否必须采用与上述解决方案相似的紧密耦合?
编辑:我忘了提及,无论如何,我都需要访问GLFWKeyCallback的内部。 让我们假设我不能纯粹通过引用(通过公共或getter / setter)访问这些内部。
解决方案我最终采取了:
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)); } }LWJGL 3 uses a callback system to handle inputs, like so:
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) { } }); } }However, I do not wish to be handling my inputs in the middle of code for another purpose.
I can extend a class with GLFWKeyCallback and pass an instance of that class in to glfwSetKeyCallback(), however I am not executing that function from in an instance. It is running from a static function (main). I do not wish to move the code from main in to an instanced object since it conflicts with my coding style and that will stress me out and I'll cave and undo it eventually.
The way I have it now is like so:
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 } }I really dislike this also, as GLFWKeyCallbackProxy is now implementing part of the game, not just being used by the game. I believe it works against good OOP structure, and it has tight coupling.
Ideally my solution would want to be somewhat equivalent to this hypothetical code:
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. } }Essentially I want the callback functions to treat the static class level functions as though is was an instance, even though it isn't.
How would you go about achieving this, or will I have to resort to some tight coupling like with my solution above?
Edit: I forgot to mention, in whatever solution, I will need to have access to the internals of GLFWKeyCallback. Let's assume that I cannot access those internals purely by reference (through publics or getters/setters).
Solution I ended up taking:
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)); } }最满意答案
我的第一个建议是开始使用“在代码中间处理我的输入以用于其他目的”。
现在,如果你真的不想这样做,那么你可以试试这个:
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 } } }你的内部类可以访问包含类的成员,所以你应该没问题。
但是我强烈建议你考虑的建议是转到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()应该做的第一个(也是唯一的)事情是实例化一个对象并将控制传递给它。
My first recommendation would be to start getting used with "handling my inputs in the middle of code for another purpose".
Now, if you really don't want to do that, then you can try this:
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 } } }Your inner class will have access to the members of the containing class, so you should be fine.
But the recommendation that I would most strongly urge you to consider is to move on to Java 8, where you will be able to do something like this:
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 } }...so invoke() becomes a member method of Main, and everything is beautiful.
Also, one final recommendation, unrelated to the problem at hand: Never write any important code in static main(). The first (and only) thing that main() should do is instantiate an object and pass control to it.
回调到类(非实例)(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扩展一个类,并将该类的实例传递给glfwSetKeyCallback(),但是我没有在实例中执行该函数。 它从静态函数(main)运行。 我不希望将代码从main转移到instanced对象,因为它与我的编码风格冲突,这会让我感到压力,最终我会陷入困境并将其撤消。
我现在的方式是这样的:
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. } }本质上我希望回调函数将静态类级别函数视为一个实例,即使它不是。
您将如何实现这一目标,或者我是否必须采用与上述解决方案相似的紧密耦合?
编辑:我忘了提及,无论如何,我都需要访问GLFWKeyCallback的内部。 让我们假设我不能纯粹通过引用(通过公共或getter / setter)访问这些内部。
解决方案我最终采取了:
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)); } }LWJGL 3 uses a callback system to handle inputs, like so:
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) { } }); } }However, I do not wish to be handling my inputs in the middle of code for another purpose.
I can extend a class with GLFWKeyCallback and pass an instance of that class in to glfwSetKeyCallback(), however I am not executing that function from in an instance. It is running from a static function (main). I do not wish to move the code from main in to an instanced object since it conflicts with my coding style and that will stress me out and I'll cave and undo it eventually.
The way I have it now is like so:
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 } }I really dislike this also, as GLFWKeyCallbackProxy is now implementing part of the game, not just being used by the game. I believe it works against good OOP structure, and it has tight coupling.
Ideally my solution would want to be somewhat equivalent to this hypothetical code:
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. } }Essentially I want the callback functions to treat the static class level functions as though is was an instance, even though it isn't.
How would you go about achieving this, or will I have to resort to some tight coupling like with my solution above?
Edit: I forgot to mention, in whatever solution, I will need to have access to the internals of GLFWKeyCallback. Let's assume that I cannot access those internals purely by reference (through publics or getters/setters).
Solution I ended up taking:
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)); } }最满意答案
我的第一个建议是开始使用“在代码中间处理我的输入以用于其他目的”。
现在,如果你真的不想这样做,那么你可以试试这个:
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 } } }你的内部类可以访问包含类的成员,所以你应该没问题。
但是我强烈建议你考虑的建议是转到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()应该做的第一个(也是唯一的)事情是实例化一个对象并将控制传递给它。
My first recommendation would be to start getting used with "handling my inputs in the middle of code for another purpose".
Now, if you really don't want to do that, then you can try this:
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 } } }Your inner class will have access to the members of the containing class, so you should be fine.
But the recommendation that I would most strongly urge you to consider is to move on to Java 8, where you will be able to do something like this:
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 } }...so invoke() becomes a member method of Main, and everything is beautiful.
Also, one final recommendation, unrelated to the problem at hand: Never write any important code in static main(). The first (and only) thing that main() should do is instantiate an object and pass control to it.
发布评论