2015-02-06 5 views
1

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(), однако я не выполняю эту функцию из экземпляра. Он работает от статической функции (основной). Я не хочу переводить код с основного на объект, потому что он конфликтует с моим стилем кодирования, и это будет подчеркивать меня, и я в конце концов вырублю его и отменим.

так, как я сейчас, как так:

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 в настоящее время реализует часть игры, а не просто используется в игре. Я считаю, что он работает против хорошей структуры ООП, и он имеет плотную связь.

В идеале мое решение хотело бы быть несколько эквивалент этой гипотетической код:

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. 
    } 

} 

По существу я хочу функцию обратного вызова для лечения статических функций уровня класса как будто был случай, даже если он ISN» т.

Как бы вы это сделали, или мне нужно прибегнуть к какой-то жесткой связи, как с моим решением выше?

Редактировать: Я забыл упомянуть, в любом решении мне понадобится доступ к внутренностям GLFWKeyCallback. Предположим, что я не могу получить доступ к этим внутренним элементам исключительно по ссылке (через общественность или геттеры/сеттеры).

Решение Я в конечном итоге принятие:

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)); 
    } 

} 

ответ

0

Моя первая рекомендация будет начать привыкают с «обработки мои входы в середине кода для другой цели».

Теперь, если вы действительно не хотите, чтобы сделать это, то вы можете попробовать это:

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 
    } 
} 

... так взывать() становится метод участника Main, и все красиво.

Кроме того, одна заключительная рекомендация, не связанная с проблемой: никогда не записывайте важный код в static main(). Первая (и единственная) вещь, которую должен выполнять main(), - это создать экземпляр объекта и передать ему контроль.

+0

Это хорошая идея, я предпочитаю, что до сих пор, и я, вероятно, могу жить с этим. Я бы предпочел, чтобы это не было в классе, так как это не было чем-то, что предназначалось для повторного использования или замены, и т. Д. Я не хочу принуждать это исключительно через синглеты/некоторые шаблоны. Но я полагаю, что я могу быть во власти языковых ограничений. Большое спасибо.Я продолжу ждать других предложений в течение небольшого времени. – Weldon

+0

Да, конечно, непременно дождаться, чтобы увидеть, что говорят другие, в StackOverflow есть много блестящих людей. –

+0

(Я только что видел ваши правки). Ну, ядро ​​Java 8 будет работать только в том случае, если 'GLFWKeyCallback' был интерфейсом с одним методом, поэтому оказывается, что он не применяется в этом конкретном случае. –

Смежные вопросы