java - 回调到类(非实例)

标签 java oop callback lwjgl

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 移至实例化对象,因为它与我的编码风格相冲突,这会给我带来压力,我最终会屈服并撤消它。

我现在的方式是这样的:

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 的内部结构。假设我无法纯粹通过引用(通过 public 或 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));
    }

}

最佳答案

我的第一个建议是开始习惯“出于其他目的在代码中间处理我的输入”。

现在,如果您真的不想这样做,那么您可以尝试以下操作:

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的一个成员方法,一切都变得美好了。

此外,还有一个与当前问题无关的最后建议:永远不要在静态 main() 中编写任何重要代码。 main() 应该做的第一件事(也是唯一的事情)是实例化一个对象并将控制权传递给它。

关于java - 回调到类(非实例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28369753/

相关文章:

ios - 静态变量如何在实例方法中工作 - 单例

java - Spymemcached,操作和连接工厂中的超时差异

java - 从 MySQL 加载数据库表

java - servlet-HTTP 状态 500 内部服务器错误

java - 如何在 Java 中正确实现泛型接口(interface)

iphone - 处理何时回调已释放的委托(delegate)?

java - 泛型 <? super >通配符

ruby - mixin 是否应该对它们的包含类做出假设?

UIButton 点击​​时的 IOS 回调

android - Facebook registerCallBack 方法未启动