currently in StandardGame, the threads default status is locked, and it only breifly unlocks for a single call (in the run() method)
the only parts that require the locking are the init code, and the update, render, clear calls (3 lines).
(fix) could you please use minimalist locking. if displayFreq returns a value (eg - 60 fps) standardgame tries to enforce it… and the sleep occurs during the lock
(request) could you please unbreak the fps part? make a call setPreferredFPS? (and get)… class variables are preferredFPS, and preferredTicksPerFrame (only calculate on set).
Thanks. I already use a seperate thread timer and have fixed the locking in my game, but it would be good to pass this back up the line.
Hmmm, I may need to re-architect it a bit to better support #1 since there really shouldn't be two places that are "unlocked" since you'd want a consistent place that things occur in the process so you don't get strange screen effects. I'll try to get a look at this, it's a very valid point though.
Please give further details about what you want in #2. I'm not sure I understand what you are asking for.
for 1 you may need to include the inpu system.update call as well (works for me - but I don't have sound… yet)
I suppose the quickest 'hacky' way is to change the unlock / lock so that the Thread.sleep call (and surrounding if statements) are unlocked.
it doesn't make a difference at the moment, because framerate is unbound (zero or less = no limit).
but as the code exists (item 2 - tweak details), if there is a frame rate, it will be locked while sleeping (potential lag issues with mulit threading)
for 2:
in the run method you declare 2 variables. I'm at work, so I cant check… I think preferredFPS (= dislpay.getFrequency()) and preferredTicksPerFrame (calculated).
if the preferredFPS is made a class variable, gets and sets can read/write… and sets can also write preferredTicksPerFrame with the same logic (only recalculated when written to, that way)… the support is already written in (need to filter zero & negative out in the set call - just set to -1).
my implementation ended up being based on the code below.
in essence, an external timer that can be used for drawing, for physics, events, animations… anything.
just makes it real easy to plug stuff with accurate timing.
not too hard to retrofit. chopped the interface (and the stub for overrides), its only onStart(), tick(float), onEnd().
sorry bout the onEvents… too much web dev, not enough sleep.
/*
* Created on 8 Sep 2007
*
*/
package koncept.hs.game.utils;
import com.jme.util.*;
public class TimedMultipleCallable implements Runnable {
private boolean active; //continue loop boolean
private int ticksPerSecond; //preferred updates per second
private int preferredTicksPerUpdate; //calculated ticks count (from updates per second)
private long ticks; //total calls to target.run();
private long tickOverflows; //tracks overflows... SHOULDN'T happen too often
private Timer timer;
private float timePerTick; //time per update
private boolean started;
Runnable / thread, makes no real difference… I prefer runnable (leaves options like Thread Groups open).
It works - as I said, I copied your code to suit my requirements. if you added the TimedMultipleCallable (and found a better name?) and exposed it, there will be no difference anymore.
also - it would mean that the different impl. for no framerame, fixed framerate, etc, become redundant (and since you seem to like championing standardGame, it would fill in for all of them).
Heh - and then I could try and get a StandardPhysicsGame instead of a SimplePhysicsGame into physics…
==> how I did my locking (mostly so that the sleep call is not locked)
initGame() {
lock();
--existing
unlock();
}
tick(float tpt) {
lock();
InputSystem.update(); //TODO - check locking and threading options at a later date
update(tpt);
render(tpt);
clearBuffers();
unlock();
}
Its been fun - but there are just suggestions, and (like everyone) I have my own coding style.
Let me know what your idea is (or when it hits cvs so I can update).
EDIT - heh, I guess you could also add a start() method that created a thread, set its name, started the runnable(this), and returned when started==true (eg - onStart has completed). complete abstraction.
When I have some time I'm going to introduce a flexible solution to the update threading issues. I have a good idea about how to solve it, just not enough time at the moment to implement it.