Refactor Context and GameRunner

This commit is contained in:
2021-03-11 20:06:46 +01:00
parent 7c6824284a
commit 03a9253ca3
10 changed files with 82 additions and 85 deletions

View File

@@ -4,9 +4,12 @@ import com.bartlomiejpluta.base.api.game.camera.Camera;
import com.bartlomiejpluta.base.api.game.entity.Entity;
import com.bartlomiejpluta.base.api.game.gui.base.GUI;
import com.bartlomiejpluta.base.api.game.image.Image;
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
import com.bartlomiejpluta.base.api.game.screen.Screen;
public interface Context {
GameRunner getGameRunner();
Screen getScreen();
Camera getCamera();

View File

@@ -1,7 +1,13 @@
package com.bartlomiejpluta.base.api.game.runner;
import com.bartlomiejpluta.base.api.game.context.Context;
import com.bartlomiejpluta.base.api.game.screen.Screen;
import com.bartlomiejpluta.base.api.internal.gc.Disposable;
public interface GameRunner {
public interface GameRunner extends Disposable {
void init(Context context);
void input(Screen screen);
void update(float dt);
}

View File

@@ -1,7 +1,4 @@
package com.bartlomiejpluta.base.engine.util.profiling.fps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
package com.bartlomiejpluta.base.api.util.profiler;
import java.util.LinkedList;
import java.util.List;
@@ -12,16 +9,13 @@ import static java.util.function.Function.identity;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
@Slf4j
@Component
public class LogFPSMonitor implements FPSMonitor {
public class FPSProfiler {
private static final int MOD = 30;
private final List<Double> values = new LinkedList<>();
private float fpsAccumulator = 0;
private int pointer = 0;
private double fps = 0;
@Override
public void update(float dt) {
fpsAccumulator += dt;
@@ -34,9 +28,8 @@ public class LogFPSMonitor implements FPSMonitor {
}
}
@Override
public void cleanUp() {
log.info("Min FPS: {}, max FPS: {}, avg FPS: {}",
public void printResult() {
System.out.format("Min FPS: %f, max FPS: %f, avg FPS: %f",
values.stream().min(Double::compareTo).orElse(-1.0),
values.stream().max(Double::compareTo).orElse(-1.0),
totalAverage()
@@ -58,6 +51,6 @@ public class LogFPSMonitor implements FPSMonitor {
.entrySet()
.stream()
.sorted(comparingInt(Map.Entry::getKey))
.forEach(e -> log.info("{} FPS: {}% ({} occurrences)", e.getKey(), e.getValue() * 100.0f / values.size(), e.getValue()));
.forEach(e -> System.out.printf("%s FPS: %f%% (%d occurrences)", e.getKey(), e.getValue() * 100.0f / values.size(), e.getValue()));
}
}

View File

@@ -1,21 +1,14 @@
package com.bartlomiejpluta.base.engine.util.profiling.time;
import com.bartlomiejpluta.base.api.internal.gc.Cleanable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
package com.bartlomiejpluta.base.api.util.profiler;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
@Slf4j
@Component
public class DefaultTimeProfilerService implements TimeProfilerService, Cleanable {
public class TimeProfiler {
private static final DecimalFormat DF = new DecimalFormat("0.00");
private final Map<String, Double> averages = new HashMap<>();
@Override
public void measure(String key, Runnable task) {
var start = System.nanoTime();
task.run();
@@ -28,11 +21,10 @@ public class DefaultTimeProfilerService implements TimeProfilerService, Cleanabl
}
}
@Override
public void cleanUp() {
public void printResult() {
averages.entrySet().stream()
.sorted(Entry.<String, Double>comparingByValue().reversed())
.forEachOrdered(entry -> log.info("[{}]: [{}ms] [{}us] [{}ns]",
.forEachOrdered(entry -> System.out.format("[%s]: [%sms] [%sus] [%sns]",
entry.getKey(),
DF.format(entry.getValue() / 1_000_000),
DF.format(entry.getValue() / 1_000),

View File

@@ -1,7 +1,8 @@
package ${package};
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
import com.bartlomiejpluta.base.api.game.context.Context;
import com.bartlomiejpluta.base.api.game.screen.Screen;
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
public class ${className} implements GameRunner {
@@ -9,4 +10,19 @@ public class ${className} implements GameRunner {
public void init(Context context) {
throw new RuntimeException("Not implemented yet");
}
@Override
public void input(Screen screen) {
}
@Override
public void update(float dt) {
}
@Override
public void dispose() {
// Do something after game loop is end
}
}

View File

@@ -1,24 +1,13 @@
package com.bartlomiejpluta.base.engine.logic;
import com.bartlomiejpluta.base.api.game.camera.Camera;
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
import com.bartlomiejpluta.base.api.game.screen.Screen;
import com.bartlomiejpluta.base.engine.core.gl.object.texture.TextureManager;
import com.bartlomiejpluta.base.engine.core.gl.render.Renderer;
import com.bartlomiejpluta.base.engine.project.loader.ClassLoader;
import com.bartlomiejpluta.base.engine.project.loader.ProjectLoader;
import com.bartlomiejpluta.base.engine.project.model.Project;
import com.bartlomiejpluta.base.engine.project.model.RenderableContext;
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
import com.bartlomiejpluta.base.engine.util.profiling.fps.FPSMonitor;
import com.bartlomiejpluta.base.engine.util.profiling.time.TimeProfilerService;
import com.bartlomiejpluta.base.engine.world.camera.DefaultCamera;
import com.bartlomiejpluta.base.engine.world.entity.manager.EntityManager;
import com.bartlomiejpluta.base.engine.world.image.manager.ImageManager;
import com.bartlomiejpluta.base.engine.world.map.manager.MapManager;
import com.bartlomiejpluta.base.engine.world.tileset.manager.TileSetManager;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -28,36 +17,18 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DefaultGameLogic implements GameLogic {
private final Renderer renderer;
private final TileSetManager tileSetManager;
private final MeshManager meshManager;
private final TextureManager textureManager;
private final EntityManager entityManager;
private final ImageManager imageManager;
private final TimeProfilerService profiler;
private final FPSMonitor fpsMonitor;
private final MapManager mapManager;
private final ProjectLoader projectLoader;
private final ClassLoader classLoader;
private final RenderableContext context;
private final Camera camera = new DefaultCamera();
private Project project;
private GameRunner runner;
@SneakyThrows
@Override
public void init(Screen screen) {
log.info("Initializing game logic");
renderer.init();
context.init(screen, camera);
project = projectLoader.loadProject();
var runnerClass = classLoader.<GameRunner>loadClass(project.getRunner());
runner = runnerClass.getConstructor().newInstance();
Project project = projectLoader.loadProject();
runner.init(context);
context.init(screen, camera, project);
}
@Override
@@ -68,7 +39,6 @@ public class DefaultGameLogic implements GameLogic {
@Override
public void update(float dt) {
context.update(dt);
fpsMonitor.update(dt);
}
@Override

View File

@@ -9,9 +9,11 @@ import com.bartlomiejpluta.base.engine.world.image.manager.ImageManager;
import com.bartlomiejpluta.base.engine.world.map.manager.MapManager;
import com.bartlomiejpluta.base.engine.world.tileset.manager.TileSetManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DefaultProjectLoader implements ProjectLoader {
@@ -25,6 +27,7 @@ public class DefaultProjectLoader implements ProjectLoader {
@Override
public Project loadProject() {
log.info("Loading project resources");
var resource = DefaultProjectLoader.class.getResourceAsStream(configuration.projectFile(configuration.getMainFile()));
var project = projectDeserializer.deserialize(resource);
project.getTileSetAssets().forEach(tileSetManager::registerAsset);

View File

@@ -6,6 +6,7 @@ import com.bartlomiejpluta.base.api.game.entity.Entity;
import com.bartlomiejpluta.base.api.game.gui.base.GUI;
import com.bartlomiejpluta.base.api.game.image.Image;
import com.bartlomiejpluta.base.api.game.map.handler.MapHandler;
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
import com.bartlomiejpluta.base.api.game.screen.Screen;
import com.bartlomiejpluta.base.api.internal.gc.Cleanable;
import com.bartlomiejpluta.base.api.internal.logic.Updatable;
@@ -21,12 +22,14 @@ import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RenderableContext implements Context, Updatable, Renderable, Cleanable {
@@ -38,17 +41,30 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
@Getter
private Screen screen;
@Getter
private GameRunner gameRunner;
@Getter
private Camera camera;
private Project project;
private DefaultGameMap map;
private MapHandler mapHandler;
private final List<GUI> guis = new LinkedList<>();
@Getter
private Camera camera;
public void init(Screen screen, Camera camera) {
@SneakyThrows
public void init(Screen screen, Camera camera, Project project) {
log.info("Initializing game context");
this.screen = screen;
this.camera = camera;
this.project = project;
var runnerClass = classLoader.<GameRunner>loadClass(project.getRunner());
gameRunner = runnerClass.getConstructor().newInstance();
gameRunner.init(this);
}
@SneakyThrows
@@ -62,6 +78,7 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
@Override
public Entity createEntity(String entitySetUid) {
log.info("Creating new entity with UID: [{}]", entitySetUid);
return entityManager.createEntity(entitySetUid);
}
@@ -72,6 +89,7 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
@Override
public GUI newGUI() {
log.info("Creating new GUI");
var gui = new NanoVGGUI(fontManager);
guis.add(gui);
gui.init(screen);
@@ -79,6 +97,8 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
}
public void input(Screen screen) {
gameRunner.input(screen);
if (mapHandler != null) {
mapHandler.input(screen);
}
@@ -86,6 +106,8 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
@Override
public void update(float dt) {
gameRunner.update(dt);
if (mapHandler != null) {
mapHandler.update(this, map, dt);
}
@@ -112,6 +134,10 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
@Override
public void cleanUp() {
log.info("Disposing game runner");
gameRunner.dispose();
log.info("Disposing GUIs");
guis.forEach(GUI::dispose);
}
}

View File

@@ -1,7 +0,0 @@
package com.bartlomiejpluta.base.engine.util.profiling.fps;
import com.bartlomiejpluta.base.api.internal.gc.Cleanable;
import com.bartlomiejpluta.base.api.internal.logic.Updatable;
public interface FPSMonitor extends Updatable, Cleanable {
}

View File

@@ -1,5 +0,0 @@
package com.bartlomiejpluta.base.engine.util.profiling.time;
public interface TimeProfilerService {
void measure(String key, Runnable task);
}