You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
2.4 KiB
132 lines
2.4 KiB
10 years ago
|
package mightypork.gamecore.core;
|
||
|
|
||
|
|
||
|
import java.util.Deque;
|
||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||
|
|
||
|
import mightypork.gamecore.graphics.Renderable;
|
||
|
import mightypork.utils.annotations.Stub;
|
||
|
import mightypork.utils.eventbus.clients.BusNode;
|
||
|
import mightypork.utils.eventbus.events.UpdateEvent;
|
||
|
import mightypork.utils.logging.Log;
|
||
|
import mightypork.utils.math.timing.Profiler;
|
||
|
import mightypork.utils.math.timing.TimerDelta;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Delta-timed game loop with task queue etc.
|
||
|
*
|
||
|
* @author Ondřej Hruška (MightyPork)
|
||
|
*/
|
||
10 years ago
|
public class BasicMainLoop extends BusNode implements MainLoop {
|
||
|
|
||
10 years ago
|
/**
|
||
|
* Max time spent on main loop tasks per cycle (s)
|
||
|
*/
|
||
|
protected double MAX_TIME_TASKS = 1 / 30D;
|
||
10 years ago
|
|
||
10 years ago
|
/**
|
||
|
* Max delta time (s) per frame.<br>
|
||
|
* If delta is larger than this, it's clamped to it.
|
||
|
*/
|
||
|
protected double MAX_DELTA = 1 / 20D;
|
||
10 years ago
|
|
||
10 years ago
|
private final Deque<Runnable> tasks = new ConcurrentLinkedDeque<>();
|
||
|
private TimerDelta timer;
|
||
|
private Renderable rootRenderable;
|
||
|
private volatile boolean running = true;
|
||
10 years ago
|
|
||
|
|
||
10 years ago
|
@Override
|
||
|
public void setRootRenderable(Renderable rootRenderable)
|
||
|
{
|
||
|
this.rootRenderable = rootRenderable;
|
||
|
}
|
||
10 years ago
|
|
||
|
|
||
10 years ago
|
@Override
|
||
|
public void start()
|
||
|
{
|
||
|
timer = new TimerDelta();
|
||
10 years ago
|
|
||
10 years ago
|
while (running) {
|
||
|
App.gfx().beginFrame();
|
||
10 years ago
|
|
||
10 years ago
|
double delta = timer.getDelta();
|
||
|
if (delta > MAX_DELTA) {
|
||
|
Log.f3("(timing) Clamping delta: was " + delta + " s, MAX_DELTA = " + MAX_DELTA + " s");
|
||
|
delta = MAX_DELTA;
|
||
|
}
|
||
10 years ago
|
|
||
10 years ago
|
// dispatch update event
|
||
|
App.bus().sendDirect(new UpdateEvent(delta));
|
||
10 years ago
|
|
||
10 years ago
|
// run main loop tasks
|
||
|
Runnable r;
|
||
|
final long t = Profiler.begin();
|
||
10 years ago
|
|
||
10 years ago
|
while ((r = tasks.poll()) != null) {
|
||
|
Log.f3(" * Main loop task.");
|
||
|
r.run();
|
||
10 years ago
|
|
||
10 years ago
|
if (Profiler.end(t) > MAX_TIME_TASKS) {
|
||
|
Log.f3("! Time's up, postponing task to next cycle.");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
10 years ago
|
|
||
|
// halt if tasks terminated the app.
|
||
|
if (!running) break;
|
||
|
|
||
10 years ago
|
beforeRender();
|
||
10 years ago
|
|
||
10 years ago
|
if (rootRenderable != null) {
|
||
|
rootRenderable.render();
|
||
|
}
|
||
10 years ago
|
|
||
10 years ago
|
afterRender();
|
||
10 years ago
|
|
||
10 years ago
|
App.gfx().endFrame();
|
||
|
}
|
||
|
}
|
||
10 years ago
|
|
||
|
|
||
10 years ago
|
/**
|
||
|
* Called before render
|
||
|
*/
|
||
|
@Stub
|
||
|
protected void beforeRender()
|
||
|
{
|
||
|
//
|
||
|
}
|
||
10 years ago
|
|
||
|
|
||
10 years ago
|
/**
|
||
|
* Called after render
|
||
|
*/
|
||
|
@Stub
|
||
|
protected void afterRender()
|
||
|
{
|
||
|
//
|
||
|
}
|
||
10 years ago
|
|
||
|
|
||
10 years ago
|
@Override
|
||
|
public void destroy()
|
||
|
{
|
||
|
running = false;
|
||
|
}
|
||
10 years ago
|
|
||
|
|
||
10 years ago
|
@Override
|
||
|
public synchronized void queueTask(Runnable task, boolean skipQueue)
|
||
|
{
|
||
|
if (skipQueue) {
|
||
|
tasks.addFirst(task);
|
||
|
} else {
|
||
|
tasks.addLast(task);
|
||
|
}
|
||
|
}
|
||
10 years ago
|
|
||
10 years ago
|
}
|