Added Base Application you can extend from and some small changes
This commit is contained in:
parent
33eea0e28b
commit
306f20cd88
|
@ -0,0 +1,183 @@
|
||||||
|
package speiger.src.coreengine.application;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
|
import java.util.function.ObjLongConsumer;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.assets.AssetManager;
|
||||||
|
import speiger.src.coreengine.assets.reloader.ResourceReloader;
|
||||||
|
import speiger.src.coreengine.rendering.gui.GuiManager;
|
||||||
|
import speiger.src.coreengine.rendering.gui.base.DebugOverlay;
|
||||||
|
import speiger.src.coreengine.rendering.input.Keyboard;
|
||||||
|
import speiger.src.coreengine.rendering.input.Mouse;
|
||||||
|
import speiger.src.coreengine.rendering.input.camera.Camera;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.WindowProvider;
|
||||||
|
import speiger.src.coreengine.rendering.shader.ProjectionBuffer;
|
||||||
|
import speiger.src.coreengine.rendering.shader.ShaderTracker;
|
||||||
|
import speiger.src.coreengine.rendering.textures.TextureManager;
|
||||||
|
import speiger.src.coreengine.rendering.utils.Cursor;
|
||||||
|
import speiger.src.coreengine.utils.counters.timers.FPSTimer;
|
||||||
|
import speiger.src.coreengine.utils.eventbus.EventBus;
|
||||||
|
import speiger.src.coreengine.utils.helpers.FileUtils;
|
||||||
|
import speiger.src.coreengine.utils.profiler.GPUProfiler;
|
||||||
|
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||||
|
import speiger.src.coreengine.utils.profiler.Profiler;
|
||||||
|
|
||||||
|
public abstract class Application
|
||||||
|
{
|
||||||
|
protected FPSTimer timer;
|
||||||
|
protected ApplicationExecutor executor = new ApplicationExecutor(this);
|
||||||
|
protected IProfiler clientProfiler = new Profiler("Client Thread");
|
||||||
|
protected IProfiler gpuProfiler = new GPUProfiler("GPU", clientProfiler);
|
||||||
|
protected boolean showProfilingInfo = true;
|
||||||
|
protected WindowProvider provider = new WindowProvider();
|
||||||
|
protected Window mainWindow;
|
||||||
|
protected Camera camera;
|
||||||
|
protected EventBus eventBus = new EventBus();
|
||||||
|
|
||||||
|
protected ResourceReloader reloader = new ResourceReloader();
|
||||||
|
protected AssetManager assetManager;
|
||||||
|
protected ProjectionBuffer projectionBuffer;
|
||||||
|
protected GuiManager uiManager;
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
GLFWErrorCallback.createPrint(System.err).set();
|
||||||
|
if(!GLFW.glfwInit()) throw new IllegalStateException("OpenGL can't be loaded");
|
||||||
|
provider.init();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mainWindow = createWindow(provider);
|
||||||
|
mainWindow.finishWindow();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
System.err.println("Could not create a Window!");
|
||||||
|
e.printStackTrace();
|
||||||
|
if(mainWindow != null) mainWindow.destroy();
|
||||||
|
provider.destroy();
|
||||||
|
System.exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Thread.currentThread().setName("Client Thread");
|
||||||
|
File file = FileUtils.getBase();
|
||||||
|
file = file.getName().endsWith(".jar") ? file : new File("bin/main");
|
||||||
|
internalInit(file);
|
||||||
|
init(file);
|
||||||
|
executor.start(mainWindow);
|
||||||
|
mainWindow.destroy();
|
||||||
|
reloader.deleteResources();
|
||||||
|
destroy();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void internalInit(File file)
|
||||||
|
{
|
||||||
|
assetManager = reloader.addReloadableResource(new AssetManager(file), true);
|
||||||
|
ShaderTracker.INSTANCE.init(assetManager);
|
||||||
|
TextureManager.INSTANCE.init(assetManager);
|
||||||
|
reloader.addReloadableResource(ShaderTracker.INSTANCE);
|
||||||
|
reloader.addReloadableResource(TextureManager.INSTANCE);
|
||||||
|
camera = new Camera(mainWindow);
|
||||||
|
if(initUI()) uiManager = BaseUIManager.create(this);
|
||||||
|
Keyboard.INSTANCE.init(eventBus, mainWindow);
|
||||||
|
Mouse.INSTANCE.init(eventBus, mainWindow, camera);
|
||||||
|
reloader.addReloadableResource(Cursor.INSTANCE, true);
|
||||||
|
mainWindow.addListener(camera.getFrustrum(), true);
|
||||||
|
projectionBuffer = new ProjectionBuffer(camera, mainWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getMainWindowName();
|
||||||
|
public void addExtraTickRates(IntConsumer ticks) {};
|
||||||
|
public void addExtraTimers(ObjLongConsumer<String> profiler) {};
|
||||||
|
public boolean initUI() { return true; }
|
||||||
|
public DebugOverlay createCustomDebug() { return null; }
|
||||||
|
public abstract Window createWindow(WindowProvider provider) throws Exception;
|
||||||
|
public abstract void init(File file);
|
||||||
|
public abstract void update();
|
||||||
|
public abstract void render(float particalTicks);
|
||||||
|
public abstract void destroy();
|
||||||
|
|
||||||
|
protected final void updateInternal()
|
||||||
|
{
|
||||||
|
if(uiManager != null)
|
||||||
|
{
|
||||||
|
clientProfiler.start("UI");
|
||||||
|
uiManager.onFixedUpdate();
|
||||||
|
clientProfiler.stop();
|
||||||
|
}
|
||||||
|
clientProfiler.start("Input");
|
||||||
|
camera.onInput();
|
||||||
|
Mouse.update();
|
||||||
|
clientProfiler.stop();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void renderInternal(float particalTicks)
|
||||||
|
{
|
||||||
|
render(particalTicks);
|
||||||
|
if(uiManager != null)
|
||||||
|
{
|
||||||
|
gpuProfiler.start("UI");
|
||||||
|
uiManager.render(particalTicks);
|
||||||
|
gpuProfiler.stop();
|
||||||
|
}
|
||||||
|
gpuProfiler.start("camera");
|
||||||
|
camera.update(particalTicks);
|
||||||
|
gpuProfiler.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssetManager getAssetManager()
|
||||||
|
{
|
||||||
|
return assetManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceReloader getReloader()
|
||||||
|
{
|
||||||
|
return reloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Window getMainWindow()
|
||||||
|
{
|
||||||
|
return mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Camera getCamera()
|
||||||
|
{
|
||||||
|
return camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventBus getEventBus()
|
||||||
|
{
|
||||||
|
return eventBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectionBuffer getProjectionBuffer()
|
||||||
|
{
|
||||||
|
return projectionBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FPSTimer getTimer()
|
||||||
|
{
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuiManager getUiManager()
|
||||||
|
{
|
||||||
|
return uiManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IProfiler getClientProfiler()
|
||||||
|
{
|
||||||
|
return clientProfiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IProfiler getGPUProfiler()
|
||||||
|
{
|
||||||
|
return gpuProfiler;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package speiger.src.coreengine.application;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
||||||
|
import speiger.src.collections.objects.queues.ObjectPriorityQueue;
|
||||||
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
|
import speiger.src.coreengine.rendering.utils.AllocationTracker;
|
||||||
|
import speiger.src.coreengine.rendering.utils.GLStamper;
|
||||||
|
import speiger.src.coreengine.rendering.utils.GLStamper.GLStamp;
|
||||||
|
import speiger.src.coreengine.rendering.utils.GLUtils;
|
||||||
|
import speiger.src.coreengine.utils.counters.averager.TimeAverager;
|
||||||
|
import speiger.src.coreengine.utils.counters.timers.FPSTimer;
|
||||||
|
import speiger.src.coreengine.utils.counters.timers.FrameSyncer;
|
||||||
|
import speiger.src.coreengine.utils.counters.timers.TimerTarget;
|
||||||
|
import speiger.src.coreengine.utils.helpers.FileUtils;
|
||||||
|
import speiger.src.coreengine.utils.helpers.TextUtil;
|
||||||
|
import speiger.src.coreengine.utils.io.GameLog;
|
||||||
|
import speiger.src.coreengine.utils.io.GameLog.LogLevel;
|
||||||
|
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||||
|
|
||||||
|
public class ApplicationExecutor
|
||||||
|
{
|
||||||
|
public static final DecimalFormat FORMATTER = new DecimalFormat("###");
|
||||||
|
FPSTimer timer = new FPSTimer();
|
||||||
|
TimerTarget fps = timer.getFPS();
|
||||||
|
TimerTarget ups = timer.getUPS();
|
||||||
|
FrameSyncer sync = new FrameSyncer();
|
||||||
|
|
||||||
|
TimeAverager gpuTime = new TimeAverager();
|
||||||
|
ObjectPriorityQueue<GLStamp> stamps = new ObjectArrayFIFOQueue<>();
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
long frame = 0L;
|
||||||
|
|
||||||
|
Application owner;
|
||||||
|
|
||||||
|
public ApplicationExecutor(Application owner)
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
owner.timer = timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IProfiler gpu()
|
||||||
|
{
|
||||||
|
return owner.gpuProfiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(Window window)
|
||||||
|
{
|
||||||
|
createTimeHacker();
|
||||||
|
timer.init();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while(window.shouldRun()) loop(window);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
GameLog.error("Client Has Crashed", e, LogLevel.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loop(Window window)
|
||||||
|
{
|
||||||
|
GLStamp stamp = GLStamper.INSTANCE.createStamp("MainStamp").start();
|
||||||
|
stamps.enqueue(stamp);
|
||||||
|
gpu().start("Client").start("Update");
|
||||||
|
window.update();
|
||||||
|
for(long f = timer.getDelta();f >= ups.getTargetNS();f = timer.consumeDelta())
|
||||||
|
{
|
||||||
|
ups.tick();
|
||||||
|
owner.updateInternal();
|
||||||
|
builder.setLength(0);
|
||||||
|
builder.append(owner.getMainWindowName());
|
||||||
|
if(owner.showProfilingInfo) addDebugInfo(builder);
|
||||||
|
window.setTitle(builder.toString());
|
||||||
|
}
|
||||||
|
gpu().next("Render");
|
||||||
|
render(timer.getParticalTime());
|
||||||
|
gpu().next("Trackers");
|
||||||
|
boolean end = timer.update();
|
||||||
|
stamp.stop();
|
||||||
|
AllocationTracker.INSTANCE.update();
|
||||||
|
GLUtils.onFrameEnded();
|
||||||
|
gpu().next("Window").start("V-Sync");
|
||||||
|
window.finishFrame();
|
||||||
|
if(window.isCPULimited()) sync.sync(fps.getTargetTicks());
|
||||||
|
gpu().next("Input");
|
||||||
|
window.gatherInputs();
|
||||||
|
gpu().stop().stop().stop().onFrameEnded(end);
|
||||||
|
while(!stamps.isEmpty() && stamps.first().isFinished())
|
||||||
|
{
|
||||||
|
stamp = stamps.dequeue();
|
||||||
|
gpuTime.addEntry(stamp.getResult());
|
||||||
|
stamp.release();
|
||||||
|
}
|
||||||
|
frame++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void render(float particalTicks)
|
||||||
|
{
|
||||||
|
gpu().start("Prep");
|
||||||
|
fps.tick();
|
||||||
|
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
|
||||||
|
gpu().stop();
|
||||||
|
owner.renderInternal(particalTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createTimeHacker()
|
||||||
|
{
|
||||||
|
Thread thread = new Thread(() -> {
|
||||||
|
while (true){
|
||||||
|
try {Thread.sleep(2147483647L);}
|
||||||
|
catch (InterruptedException e){}
|
||||||
|
}
|
||||||
|
}, "Time Fixer Thread");
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addDebugInfo(StringBuilder builder)
|
||||||
|
{
|
||||||
|
builder.append("(");
|
||||||
|
builder.append(fps.getTicks()).append(":").append(ups.getTicks());
|
||||||
|
owner.addExtraTickRates(T -> builder.append(":").append(T));
|
||||||
|
builder.append(",").append(getMemoryUsage());
|
||||||
|
builder.append(",").append("CPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getCPUAllocatedBytes()));
|
||||||
|
builder.append(",").append("GPU-A: "+FileUtils.convertBytes(AllocationTracker.INSTANCE.getGPUAllocatedBytes()));
|
||||||
|
builder.append(",").append(TextUtil.convertTime(timer.getUsage(), "Client:", FORMATTER));
|
||||||
|
builder.append(",").append(TextUtil.convertTime(gpuTime.getAverage(), "GPU:", FORMATTER));
|
||||||
|
owner.addExtraTimers((N, T) -> builder.append(",").append(TextUtil.convertTime(T, N, FORMATTER)));
|
||||||
|
builder.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMemoryUsage()
|
||||||
|
{
|
||||||
|
Runtime time = Runtime.getRuntime();
|
||||||
|
long aviable = time.totalMemory();
|
||||||
|
return "Memory:"+((aviable - time.freeMemory()) >> 20)+"MB/"+(aviable >> 20)+"MB";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package speiger.src.coreengine.application;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.rendering.gui.GuiManager;
|
||||||
|
import speiger.src.coreengine.rendering.gui.base.DebugOverlay;
|
||||||
|
import speiger.src.coreengine.rendering.models.UniformBuffer;
|
||||||
|
import speiger.src.coreengine.utils.collections.FlagHolder;
|
||||||
|
import speiger.src.coreengine.utils.profiler.EmptyProfiler;
|
||||||
|
import speiger.src.coreengine.utils.profiler.IProfiler;
|
||||||
|
|
||||||
|
public class BaseUIManager extends GuiManager
|
||||||
|
{
|
||||||
|
Application application;
|
||||||
|
|
||||||
|
public BaseUIManager(Application application)
|
||||||
|
{
|
||||||
|
super(application.mainWindow, application.eventBus);
|
||||||
|
this.application = application;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseUIManager create(Application app)
|
||||||
|
{
|
||||||
|
return new BaseUIManager(app) {
|
||||||
|
@Override
|
||||||
|
public DebugOverlay createOverlay()
|
||||||
|
{
|
||||||
|
DebugOverlay overlay = app.createCustomDebug();
|
||||||
|
return overlay != null ? overlay : new InternalDebugOverlay();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IProfiler getGPUProfiler()
|
||||||
|
{
|
||||||
|
return application.gpuProfiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IProfiler getCPUProfiler()
|
||||||
|
{
|
||||||
|
return application.clientProfiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IProfiler getServerProfiler()
|
||||||
|
{
|
||||||
|
return EmptyProfiler.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UniformBuffer getOrthoMatrixBuffer()
|
||||||
|
{
|
||||||
|
return application.projectionBuffer.getOrthoViewMatrixBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DebugOverlay createOverlay()
|
||||||
|
{
|
||||||
|
DebugOverlay overlay = application.createCustomDebug();
|
||||||
|
return overlay != null ? overlay : new InternalDebugOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InternalDebugOverlay extends DebugOverlay
|
||||||
|
{
|
||||||
|
public static final int UPDATING = 1;
|
||||||
|
public static final int RENDERING = 2;
|
||||||
|
FlagHolder flags = new FlagHolder(RENDERING);
|
||||||
|
@Override
|
||||||
|
public void toggleUI() { flags.flipFlag(RENDERING); }
|
||||||
|
@Override
|
||||||
|
public void toggleUpdate() { flags.flipFlag(UPDATING); }
|
||||||
|
@Override
|
||||||
|
public void toggleDebug() {}
|
||||||
|
@Override
|
||||||
|
public boolean toggleFPS() { return false; }
|
||||||
|
@Override
|
||||||
|
public boolean isUpdating() { return flags.isFlagSet(UPDATING); }
|
||||||
|
@Override
|
||||||
|
public boolean isRendering() { return flags.isFlagSet(RENDERING); }
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,7 +55,7 @@ public class AllocationTracker
|
||||||
return cpuAllocation.getAverage();
|
return cpuAllocation.getAverage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getGPUAllocationBytes()
|
public long getGPUAllocatedBytes()
|
||||||
{
|
{
|
||||||
return gpuAllocation.getAverage();
|
return gpuAllocation.getAverage();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue