Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (480)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (546)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Event Thread getting choked...  (Read 2115 times)
0 Members and 1 Guest are viewing this topic.
zahl2001
Guest
« Posted 2004-06-17 20:58:18 »

Hello,

There isn't much going on in the scene of my current project, so the frame rate is quite high.  My program seems to be having a very difficult time getting key events, so I tried calling Thread.sleep(10) in display(), which 'fixed' the problem as far as the key events go, but the frame rate dropped to about 60.  The fact that the FPS took such a hit makes it seem like that wasn't a very responsible approach to the problem.  I had previously assumed that the Animator class embodied some sort of sleep mechanism, but it appears I was wrong. A previous test I made had quite a few polygons, so the frame rate was quite low (14), and in THAT situation the key events came through fine. Is it somehow true that the higher the FPS the harder it is for key/mouse events to be reliably read?

Anyway...suggestions from the knowledgable folks on this board?

And a related question: should I try to find some way to synch the key/mouse events to display? If so, any suggestions on THAT?

Thanks Smiley
Offline DanK

Junior Member




Javver games rock yawel!


« Reply #1 - Posted 2004-06-17 23:56:09 »

The solution to this is to write your own animator, and insert a Thread.yield() statement. There isn't much to writing an Animator, just create a thread with a reference to your GLCanvas and call display() on it. The tricky part to this is when you want to stop the animator you made, because if you try to stop your animator while display is being called, you get errors like some kind of swapping problem (and I seem to recall there was another issue too that was related to fullscreen).

Quote


import net.java.games.jogl.*;
import java.awt.event.*;
public class CustomAnimator implements ,Runnable {
     GLCanvas canvas;
     boolean running = true;
     Thread thread = null;

     public CustomAnimator(GLCanvas canvas) {
           this.canvas = canvas;
           thread = new Thread(this);
     }
     
     public synchronized void start() {
           thread.start();
     }
     
     public synchronized void stop() {
           running = false;
           while (thread != null) {
           //Make sure run completes
                 try {
                       wait();
                 } catch (InterruptedException ie) {
                 }
           }
     }
     
     public void run() {
           canvas.setRenderingThread(thread);
           while (running) {
                 if (canvas != null) {
                       canvas.display();
                 } else {
                       running = false;
                 }
                 Thread.yield();
           }
           synchronized (CustomAnimator.this) {
                 thread = null;
                 CustomAnimator.this.notify();
           }
     }
}


Note: I pulled a lot of my own code out of this to make it a bare bones animator so there might be some compile errors, this will run just like the regular animator, except it yields every loop (stepping aside so that other threads can run if they want). It's possible and easy to change it so that animation stops when the window loses focus or is iconified by implementing WindowListener and keeping a variable like 'paused' and only calling display() when paused is true. There is also an FPSAnimator creeping around the forums too that can be used, personally I think my version is an easier base to work off of.

Offline ribot

Junior Member




Ribot - mobile UI specialist


« Reply #2 - Posted 2004-06-18 05:28:25 »

To save you some time (and hopefully make this into some kind of reference thread), I attach the source of FPSAnimator.  The only thing you may have to change is the package name.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
/*
 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistribution of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
 * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed or intended for use
 * in the design, construction, operation or maintenance of any nuclear
 * facility.
 *
 * Sun gratefully acknowledges that this software was originally authored
 * and developed by Kenneth Bradley Russell and Christopher John Kline.
 */


package common;

import net.java.games.jogl.Animator;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.GLException;

import java.util.Timer;
import java.util.TimerTask;

/**
 * <P> An Animator can be attached to a GLDrawable to drive its
 * display() method in a loop. For efficiency, it sets up the
 * rendering thread for the drawable to be its own internal thread,
 * so it can not be combined with manual repaints of the
 * surface. </P>
 *
 * <P> The Animator currently contains a workaround for a bug in
 * NVidia's drivers (80174). The current semantics are that once an
 * Animator is created with a given GLDrawable as a target, repaints
 * will likely be suspended for that GLDrawable until the Animator is
 * started. This prevents multithreaded access to the context (which
 * can be problematic) when the application's intent is for
 * single-threaded access within the Animator. It is not guaranteed
 * that repaints will be prevented during this time and applications
 * should not rely on this behavior for correctness. </P>
 */


public class FPSAnimator extends Animator {
    private GLDrawable drawable;
    private RenderRunnable runnable = new RenderRunnable();
    private Thread thread;
    private boolean shouldStop;
    private long delay;
    private Timer renderTimer;
    private ExceptionHandler exceptionHandler;

    public FPSAnimator(GLDrawable drawable, int fps) {
        this(drawable, fps, null);
    }

    /** Creates a new Animator for a particular drawable. */
    public FPSAnimator(GLDrawable drawable, int fps, ExceptionHandler exceptionHandler) {
        super(drawable);
        this.exceptionHandler = exceptionHandler;
        this.drawable = drawable;
        this.delay = 1000 / fps;
    }

    /** Starts this animator. */
    public synchronized void start() {
        if (thread != null) {
            throw new GLException("Already started");
        }
        thread = new Thread(runnable);
        thread.start();

        renderTimer = new Timer();
        renderTimer.schedule(new TimerTask() {
            public void run() {
                runnable.nextFrame();
            }
        }, 0, delay);
    }

    /** Stops this animator, blocking until the animation thread has
     finished. */

    public synchronized void stop() {
        shouldStop = true;
        while (shouldStop && thread != null) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
            renderTimer.cancel();
        }
    }

    public boolean isFrameRateLimitEnabled() {
        return runnable.isFrameRateLimitEnabled();
    }

    public void setFrameRateLimitEnabled(boolean frameRateLimit) {
        runnable.setFrameRateLimitEnabled(frameRateLimit);
    }

    private class RenderRunnable implements Runnable {
        private boolean frameRateLimitEnabled = true;

        public boolean isFrameRateLimitEnabled() {
            return frameRateLimitEnabled;
        }

        public void setFrameRateLimitEnabled(boolean frameRateLimit) {
            frameRateLimitEnabled = frameRateLimit;
            nextFrameSync();
        }

        public void nextFrame() {
            if (frameRateLimitEnabled)
                nextFrameSync();
        }

        private synchronized void nextFrameSync() {
            notify();
        }

        public void run() {
            boolean noException = false;
            try {
                // Try to get OpenGL context optimization since we know we
               // will be rendering this one drawable continually from
               // this thread; make the context current once instead of
               // making it current and freeing it each frame.
               drawable.setRenderingThread(Thread.currentThread());

                // Since setRenderingThread is currently advisory (because
               // of the poor JAWT implementation in the Motif AWT, which
               // performs excessive locking) we also prevent repaint(),
               // which is called from the AWT thread, from having an
               // effect for better multithreading behavior. This call is
               // not strictly necessary, but if end users write their
               // own animation loops which update multiple drawables per
               // tick then it may be necessary to enforce the order of
               // updates.
               drawable.setNoAutoRedrawMode(true);

                while (!shouldStop) {
                    noException = false;
                    drawable.display();
                    if (frameRateLimitEnabled) {
                        synchronized (this) {
                            if (frameRateLimitEnabled) {
                                try {
                                    wait();
                                } catch (InterruptedException e) {
                                }
                            }
                        }
                    }
                    noException = true;
                }
            } catch (Exception e) {
                if (exceptionHandler != null)
                    exceptionHandler.handleException(e);
            } finally {
                shouldStop = false;
                drawable.setNoAutoRedrawMode(false);
                try {
                    // The surface is already unlocked and rendering
                   // thread is already null if an exception occurred
                   // during display(), so don't disable the rendering
                   // thread again.
                   if (noException) {
                        drawable.setRenderingThread(null);
                    }
                } finally {
                    synchronized (FPSAnimator.this) {
                        thread = null;
                        FPSAnimator.this.notify();
                    }
                }
            }
        }
    }
}

http://ribot.co.uk - design agency focused on mobile
http://www.retrospecs.co.uk - online vintage eyewear store
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
zahl2001
Guest
« Reply #3 - Posted 2004-06-18 10:16:20 »

Thanks very much for not only responding, but including some code to work with.  I'll try it out this weekend, hopefully.

Thanks again Smiley
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #4 - Posted 2004-06-18 13:50:00 »

>import java.util.Timer;
>import java.util.TimerTask;

Ewww... Lips Sealed

It's like letting a monkey on crack do a brain surgery with a sledge hammer Grin

For accurate (reliable) framecapping you need more precision than those flaky timers provide. So... try the GAGE timer, the 1.4.2_3/4/5 hidden timer or the new timer from 1.5.

3 different frame capping algos can be found in this thread (somewere at the end of page1):
http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=LWJGL;action=display;num=1087392059

Well, it's for lwjgl, but it should be pretty easy to port em.

弾幕 ☆ @mahonnaiseblog
Offline Sylvie

Senior Newbie




Java games rock!


« Reply #5 - Posted 2004-06-18 18:21:22 »

And if anyone is curious about the high-resolution timer implementation, here's a how-to article for writing one for Windows.

http://www.fawcette.com/archives/premier/mgznarch/javapro/2001/08aug01/km0108/km0108-2.asp

Sean
zahl2001
Guest
« Reply #6 - Posted 2004-06-18 23:11:24 »

I have a question about Thread.yield().  The documentation says that the current Thread pauses to allow other Threads to execute, so does this mean that the Thread display() is running in will pause for a length of time sufficient for all of the events which occured during the last cycle of display() to be processed?

Maybe a better way to phrase that would be to say if event X occured during frame X will event X be processed during frame X?

Thanks
Offline DanK

Junior Member




Javver games rock yawel!


« Reply #7 - Posted 2004-06-18 23:30:01 »

I'd assume that event x would be processed at the yield point of code, but there is no gaurentee about that, it's possible for an event to occur during rendering and as far as I know the events could be processed mid-rendering, most likely this behavior is dependant on the OS but like I said, there aren't any gaurentees about which thread is doing what at any time unless you build them in.

zahl2001
Guest
« Reply #8 - Posted 2004-06-19 00:06:36 »

So there shouldn't be issues like " I pressed the so-and-so button, and 10 frames later so-and-so happens?" if I use the CustomAnimator?
Offline DanK

Junior Member




Javver games rock yawel!


« Reply #9 - Posted 2004-06-19 01:19:46 »

That shouldn't happen, it will definitely happen less than using the original animator class. This won't help much for laggy mouse caused by really low frame rate though.

You could test your app by replacing your Thread.sleep(10) with Thread.yield(), your frame rate shouldn't drop unless something pretty serious is going on (your input handling does something long like reading a file in) and your events should still get done. The CustomAnimator class is better than having the yield command in your display(GL gl) method because sleeping in the display method would prevent your scene from rendering until the display method returns, it shouldn't be a noticable difference unless there is a long pause but that would be an issue no matter what point your code pauses at.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
zahl2001
Guest
« Reply #10 - Posted 2004-06-19 16:56:24 »

DanK,

I implemented your CustumAnimator today, and the results are impressive.  Now MY wire frame terrain project performs every bit as good as the ones you pay $50 for at GameStop.

Thanks very much for the code Smiley
Offline sally

Junior Member





« Reply #11 - Posted 2004-06-29 07:44:51 »

I tried to compile FPSAnimator but it gave me an error saying it could not find ExceptionHandler - does anybody know where I could get hold of this ExceptionHandler class?

Txs,

Sally
Offline robdarich

Senior Newbie




Java games rock!


« Reply #12 - Posted 2004-07-03 19:53:09 »

does anybody know where I could get hold of this ExceptionHandler class?


I found these files in the jogl ports to the nehe demos inside the package common.  Here's the index to these jar files:
http://pepijn.fab4.be/nehe/index.html

-rob
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

atombrot (20 views)
2014-08-19 09:29:53

Tekkerue (21 views)
2014-08-16 06:45:27

Tekkerue (21 views)
2014-08-16 06:22:17

Tekkerue (12 views)
2014-08-16 06:20:21

Tekkerue (19 views)
2014-08-16 06:12:11

Rayexar (55 views)
2014-08-11 02:49:23

BurntPizza (37 views)
2014-08-09 21:09:32

BurntPizza (28 views)
2014-08-08 02:01:56

Norakomi (35 views)
2014-08-06 19:49:38

BurntPizza (64 views)
2014-08-03 02:57:17
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!