151 lines
4.4 KiB
Java
151 lines
4.4 KiB
Java
package electrosphere.engine.time;
|
|
|
|
import org.lwjgl.glfw.GLFW;
|
|
|
|
import electrosphere.engine.EngineState;
|
|
|
|
/**
|
|
* Service that keeps track of time for main thread activities.
|
|
*/
|
|
public class Timekeeper {
|
|
|
|
//the time a single simulation frame should simulate for (this is fixed)
|
|
double simFrameTime = 0.0;
|
|
|
|
//the time that the system started (0 if using glfw reference, current system time if using java reference)
|
|
double engineStartTime = 0.0;
|
|
|
|
//the system time at the last call to update()
|
|
double currentTime = 0.0;
|
|
|
|
//accumulates time between current frame and next frame
|
|
double frameAccumulator = 0.0;
|
|
|
|
//the number of frames that have elapsed
|
|
long numberOfSimFramesElapsed = 0;
|
|
|
|
//the number of times the render pipeline has rendered a frame
|
|
public long numberOfRenderedFrames = 0;
|
|
|
|
//the raw (not simulation) frametime of the most recent frame
|
|
double mostRecentRawFrametime = 0;
|
|
|
|
//The maximum amount of time that can overflow (ie cause more than one sim frame/render frame) before the sim frames are tossed out
|
|
static double overflowMax = 20;
|
|
|
|
//the maximum number of simulation frames that can happen in a row before the main loop immediately skips more
|
|
public static final int SIM_FRAME_HARDCAP = 3;
|
|
|
|
//step interval time size (for physics)
|
|
public static final float ENGINE_STEP_SIZE = 0.01f;
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Gets the time since the engine started from the system
|
|
* @return The time (in seconds)
|
|
*/
|
|
private double getTime(){
|
|
if(EngineState.EngineFlags.HEADLESS){
|
|
return System.currentTimeMillis() - engineStartTime;
|
|
} else {
|
|
return GLFW.glfwGetTime();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inits the timekeeper
|
|
* @param simFrameTime The amount of time that a frame should take
|
|
*/
|
|
public void init(double simFrameTime){
|
|
this.simFrameTime = simFrameTime;
|
|
if(EngineState.EngineFlags.HEADLESS){
|
|
engineStartTime = System.currentTimeMillis();
|
|
}
|
|
currentTime = getTime();
|
|
}
|
|
|
|
/**
|
|
* Updates the timekeeper to track last frametime, etc
|
|
*/
|
|
public void update(){
|
|
//calculate frametime, set current time
|
|
double newTime = getTime();
|
|
double frameTime = newTime - currentTime;
|
|
mostRecentRawFrametime = frameTime;
|
|
if(frameTime > overflowMax){
|
|
frameTime = overflowMax;
|
|
}
|
|
currentTime = newTime;
|
|
//add to accumulator
|
|
frameAccumulator += frameTime;
|
|
}
|
|
|
|
/**
|
|
* Tries to pull a single frametime out of the accumulator
|
|
* If the accumulator holds at least a frametime's worth of time, the function returns true
|
|
* If the accumulator has not accumulated a simframetime's worth of time, the function returns false
|
|
* @return True if the accumulator has at least a simulation frame's amount of time inside it
|
|
*/
|
|
public boolean pullFromAccumulator(){
|
|
boolean rVal = false;
|
|
if(frameAccumulator >= simFrameTime){
|
|
rVal = true;
|
|
frameAccumulator -= simFrameTime;
|
|
numberOfSimFramesElapsed++;
|
|
}
|
|
return rVal;
|
|
}
|
|
|
|
/**
|
|
* Gets the amount of time a single simulation frame should take
|
|
* @return The time
|
|
*/
|
|
public double getSimFrameTime(){
|
|
return this.simFrameTime;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of simulation frames that have elapsed
|
|
* @return the number of frames
|
|
*/
|
|
public long getNumberOfSimFramesElapsed(){
|
|
return numberOfSimFramesElapsed;
|
|
}
|
|
|
|
/**
|
|
* The number of rendered frames that have elapsed
|
|
* @return the frame number
|
|
*/
|
|
public long getNumberOfRenderFramesElapsed(){
|
|
return numberOfRenderedFrames;
|
|
}
|
|
|
|
/**
|
|
* Gets the most recent raw frametime
|
|
* @return the frametime
|
|
*/
|
|
public double getMostRecentRawFrametime(){
|
|
return mostRecentRawFrametime;
|
|
}
|
|
|
|
/**
|
|
* Gets the current time of the renderer since the engine started
|
|
* @return The current time
|
|
*/
|
|
public double getCurrentRendererTime(){
|
|
return currentTime;
|
|
}
|
|
|
|
/**
|
|
* The number of frames we're simulating this cycle
|
|
* @return The number of frames we're simulating this cycle
|
|
*/
|
|
public long getDeltaFrames(){
|
|
//this should always return 1. We're always simulating 1 frame per run of the loop in main
|
|
return 1;
|
|
}
|
|
|
|
}
|