projectdelphai/JAdventure — pull request #2 by projectdelphai (2014-01-10 06:33:28+00:00)
Title: Rerouting stdout to a messenger queue thread

Alright, so pretty big commit here that I'm submitting for approval. There was some comments recently about making a swing frame for the game and I've been thinking about having some remote playing stuff going on (kind of like a telnet MUD situation) and I was thinking about how to go about this. I noticed that a pretty big problem is that all game responses are being send out through System.out.println (stdout and stderr) rather than through a unified placed. Nothing is wrong with that, but if we ever decided to do something different later on, it could become a problem to track down all the responses. This I thought was a pretty nice alternative to the current situation.

Basically there is a Messenger class that runs as a separate thread. It's a BlockingQueue so it's just a list of objects. You add on an object and when Messenger notices that there are objects in the queue, it takes that object and does whatever you want to it. Just to keep things simple for now, I had it take the object (always a string right now) and print it out through stdout. So, honestly, from a player perspective, nothing has changed (at least that was the goal).

However, from a developer point of view, you can now do anything with the output by changing that one line in Messenger. You could route it through a Socket or send it to a gui window or post it to a web interface through some sort of API. I was thinking that we could have command-line options to do different things. So depending on how you want to play you could set it to client/server mode or terminal mode or web mode.

Now to the actual implementation. Setting up the thread and queue itself wasn't as hard as I thought it would be. JAdventure.java starts sets up the thread and queue before starting up the game. The problem was passing the queue variable to every class that needs it. The only real way that I could figure out how to do it was to send it as a argument method that is assigned in the constructor. I tried to find ways to minimize the passing of queue, but I think I got it down. Now to submit an output string, instead of writing

System.out.println(string);

you have to do

queue.offer(string)

I know that the standard is to use queue.put(string), however using put() requires that you encapsulate each line in a try/catch statement for interruptedException. However offer doesn't need it because it never calls interruptedException. It isn't a problem because interruptedException is only called when the queue is full and I haven't set the queue to have a capacity limit so that exception should never be called. I think I mostly caught all the possible bugs, but there may be other places that I missed (it's kinda hard to find bugs when the ouput is the exact same as before :)). Just let me know, and I'll try and fix them.

So I think this is a pretty good idea. Not necessarily in terms of new features but as a basis for future features. Please let me know if there's a problem with the design or just with the idea in general.

note: That fourth commit (1b32bcb) was made by me when I noticed it while making the queue feature. Not really relevant to the queue feature itself. I realized that it wasn't important to this pull request so made the change in master separate from this branch (as seen by the merge acfc816) but I guess I forgot to remove the commit from the branch. That's why the fourth and fifth commit are the exact same.