Как бы я получил ввод с консоли без блокировки?

1

Примечание. Я понимаю, что консоль предназначена для отладки, а игры должны использовать графический интерфейс. Это для тестирования/опыта

Я пишу игру, которая работает со скоростью 60 кадров в секунду. Каждое обновление, я проверяю, ввел ли пользователь команду String. Если это так, оно проходит через, но если нет, то null является paas through, а null игнорируется.

Сканер не может быть и речи, так как hasNext(), метод, используемый для просмотра данных о чтении, может потенциально блокировать и создавать проблемы.

Я пробовал использовать BufferedReader.ready(). Мало того, что у меня есть проблемы (не вернулся true), но я читал, что это не рекомендуется по нескольким причинам.

BufferedReader.available() всегда возвращал 0, что в документации указывает, что InputStream.available() всегда будет возвращать 0, если не переопределить. Вот моя попытка:

class Game {

     public static void main(String[] args) {
          InputReader reader = new InputReader(System.in);
          int timePerLoop = 1000/30;

          Game game = new Game();
          while(true) {
               long start = System.nanoTime();
               game.update(reader.next());
               long end = System.nanoTime();

               long sleepTime = timePerLoop + ((start - end) / 10000000);
               if(sleepTime > 0)
                    try {
                         Thread.sleep(sleepTime);
                    }catch(InterruptedException e) {
                         e.printStackTrace();
                    }
               else
                    Thread.yield();
          }
     }

     public void update(String command) {
          if(commands != null) {
               //handle command
          }

          //update game
     }
}

InputReader.java

public class InputReader {
     private InputStream in;

     public InputReader(InputStream stream) {
          in = stream;
     }

     public String next() {
          String input = null;
          try {
               while(in.available > 0) {
                    if(input == null)
                         input = "";

                    input += (char) in.read();
               }
          }catch(IOException e) {
               e.printStackTrace();
          }
          return input;
     }
}

InputStream сам по себе имеет ту же проблему, что и выше. Я не совсем уверен, какой тип хранит объект в System.in, но с использованием available() дает те же результаты.

Я попытался использовать reader() из System.console(), но console() возвращает значение null. Я прочитал эту тему, и я не смущен почему. Это не способ сделать это.

Цель состоит в том, чтобы проверить поток, чтобы увидеть, содержит ли он данные для чтения, поэтому я могу читать данные, зная, что он не будет блокироваться.

Я не хочу использовать отдельный Thread для обработки ввода пользователя, поэтому, пожалуйста, не рекомендуем и не спрашивайте, почему.

Вход должен быть из консоли. Никакие новые сокеты не должны создаваться в процессе. Я прочитал несколько тем об этом, но ни один из них не ясно сформулировал решение. Это возможно?

  • 0
    ты когда-нибудь работал?
Теги:
console
nonblocking

1 ответ

1

Как вы сами сказали, пользовательский графический интерфейс или дополнительный поток - это правильный способ сделать это. Однако в отсутствие этого вы пытались использовать readLine() например: String inputR = System.console().readLine();

Некоторые изменения в main():

Заменить: InputReader reader = new InputReader(System.in); с: Console c = System.console();

Заменить: game.update(reader.next()); с: game.update(c.readLine());

Редактировать: этот поток также может быть полезным: Java: как получить входные данные из System.console()

  • 0
    System.console() может возвращать ноль, в зависимости от того, как запускается JVM ( System.console () возвращает ноль ). Я действительно узнал, что мой пример работает на компьютере моего друга. Я запускал это со своего телефона (который, хотя он поддерживает консольные приложения, еще не полностью функционален). Короче говоря, это была проблема с JVM, и теперь я понимаю, что мой вопрос относится только к очень конкретной платформе, не подходящей для SO. Спасибо за попытку, хотя :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню