1

should a game loop in a java program always run in the event dispatch thread? Because my keylisteners are running in the AWT event thread and I want the key events to be processed in the same thread as the rest of the game to avoid thread based bugs. If I don't run the game loop in the event thread can I use an ArrayBlockingQueue to send events from the event handler to the game loop? Is there a better solution? thanks

Maybe something like this?

ConcurrentLinkedQueue<AWTEvent> eventQueue = new ConcurrentLinkedQueue<AWTEvent>(); 

JFrame frame = new JFrame() {
    @override
    protected void processEvent(AWTEvent e) {
        if(e instanceof InputEvent) eventQueue.add(e);
        else super.processEvent(e);
    }
}

//game loop
while(true) {
    while(!eventQueue.isEmpty()) frame.super.processEvent(eventQueue.poll());
    ...
}

edit: Thank you, I think I now know how to do this. I'm gonna do it like this

import java.util.concurrent.ConcurrentLinkedQueue;
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;

public class QueueTest {

    static ConcurrentLinkedQueue<AWTEvent> eventQueue = new ConcurrentLinkedQueue<AWTEvent>(); 

    public static void main(String[] args) {
        final JPanel panel = new JPanel() {
            @Override
            protected void processEvent(AWTEvent e) {
                eventQueue.add(e);
            }
            {
                enableEvents(  AWTEvent.MOUSE_EVENT_MASK
                             | AWTEvent.MOUSE_MOTION_EVENT_MASK
                             | AWTEvent.KEY_EVENT_MASK);
            }
        };
        final JFrame frame = new JFrame();
        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentShown(ComponentEvent e) {
                panel.requestFocusInWindow();
            }
        });
        frame.add(panel);
        panel.setPreferredSize(new Dimension(800,600));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        while(true) {
            while(!eventQueue.isEmpty()) System.out.println(eventQueue.poll()+"\n");
        }
    }
}
Tesseract
  • 8,049
  • 2
  • 20
  • 37

2 Answers2

1

I'm not a game programmer so your question prompted some research :) You cannot run the game loop in the event dispatch thread because it is in a loop of its own servicing user input. You're application would essentially freeze up and not respond to any further input events. Your game loop should be a separate thread with a thread-safe queue for game events - the queue should be non-blocking because you want the game loop to continue even if there has been no user input. Any rendering you need to do as a result of input will probably have to be put back on the event queue - swing provides SwingUtilities for this although not sure which environment you are in.

I'll probably get slammed by experienced games developers now.

barry
  • 201
  • 1
  • 4
  • Actually, I decided not to tell the OP the same thing because I'm not experienced in game programming. But I think it's safe to say he can't put the "game loop" on the event queue, hopefully no one will argue with that. – arcy Mar 10 '12 at 03:51
1

I had a similar problem in the game engine I wrote.

In the end I had to have a separate thread for my game engine loop. When AWT events were fired I had to store them, and fire them during the next logical update within the game loop.

This was my solution however, I believe that the 'easiest' thing for events is to actually poll them! :)

AlanFoster
  • 8,156
  • 5
  • 35
  • 52