Vince
Vince

Reputation: 15146

How would I receive input from console without blocking?

Note: I understand that the console is for debugging and games should use GUI. This is for testing/experience

I'm writing a game that runs at 60fps. Every update, I check to see if the user has entered a String command. If so, it gets passed through, but if not, null is paas through, and the null is ignored.

Scanner is out of the question, since hasNext(), the method used to see if there is data to read, can potentially block and causes problems.

I've tried using BufferedReader.ready(). Not only did I have problems (never returned true), but I've read that it's not recommended for a few reasons.

BufferedReader.available() always returned 0, which in the documentation, it state's that InputStream.available() will always return 0 unless overriden. Here is my attempt:

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 by itself has the same problem as above. I'm not completely sure what type the object stored in System.in, but using available() yields the same results.

I've tried using the reader() from System.console(), but console() returns null. I've read into the subject, and I am not confused why. This is not the way to do it.

The goal is to check the stream to see if it contains data to read, so I can read the data knowing it won't block.

I do not want to use a separate Thread to handle user input, so please don't recommend or ask why.

The input has to be from the console. No new sockets are to be created in the process. I have read a few topics about it, but none of them clearly states a solution. Is this possible?

Upvotes: 1

Views: 4082

Answers (1)

sorifiend
sorifiend

Reputation: 6307

As you have said yourself, a custom GUI or an additional thread is the correct way to do this. However in absence of that, have you tried using readLine() for example: String inputR = System.console().readLine();

Some alterations to main():

Replace: InputReader reader = new InputReader(System.in); with: Console c = System.console();

Replace: game.update(reader.next()); with: game.update(c.readLine());

Edit: This thread could also be helpful: Java: How to get input from System.console()

Upvotes: 1

Related Questions