Move the Context creation to the App engine starting point | change GLFW Window title to project name
This commit is contained in:
@@ -6,14 +6,19 @@ 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;
|
||||
import com.bartlomiejpluta.base.api.internal.gc.Disposable;
|
||||
import com.bartlomiejpluta.base.api.internal.logic.Updatable;
|
||||
import com.bartlomiejpluta.base.api.internal.render.Renderable;
|
||||
|
||||
public interface Context {
|
||||
public interface Context extends Updatable, Renderable, Disposable {
|
||||
GameRunner getGameRunner();
|
||||
|
||||
Screen getScreen();
|
||||
|
||||
Camera getCamera();
|
||||
|
||||
String getProjectName();
|
||||
|
||||
void openMap(String mapUid);
|
||||
|
||||
Entity createEntity(String entitySetUid);
|
||||
@@ -21,4 +26,8 @@ public interface Context {
|
||||
Image getImage(String imageUid);
|
||||
|
||||
GUI newGUI();
|
||||
|
||||
void init(Screen screen, Camera camera);
|
||||
|
||||
void input(Screen screen);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package com.bartlomiejpluta.base.engine;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||
import com.bartlomiejpluta.base.engine.project.model.ContextManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -16,15 +17,19 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@SpringBootApplication(scanBasePackages = "com.bartlomiejpluta.base")
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class App implements ApplicationRunner {
|
||||
private final GameEngine gameEngine;
|
||||
private final GameEngine gameEngine;
|
||||
private final ContextManager contextManager;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
log.info("Starting game engine");
|
||||
gameEngine.start();
|
||||
}
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
log.info("Creating context");
|
||||
var context = contextManager.createContext();
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(App.class, args);
|
||||
}
|
||||
log.info("Starting game engine");
|
||||
gameEngine.start(context);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(App.class, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,38 @@
|
||||
package com.bartlomiejpluta.base.engine.core.engine;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.context.Context;
|
||||
import com.bartlomiejpluta.base.api.game.screen.Screen;
|
||||
import com.bartlomiejpluta.base.engine.gc.OffHeapGarbageCollector;
|
||||
import com.bartlomiejpluta.base.engine.logic.GameLogic;
|
||||
import com.bartlomiejpluta.base.engine.thread.ThreadManager;
|
||||
import com.bartlomiejpluta.base.engine.time.ChronoMeter;
|
||||
import com.bartlomiejpluta.base.engine.ui.ScreenManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultGameEngine implements GameEngine {
|
||||
private static final String THREAD_NAME = "Game Main Thread";
|
||||
private static final String THREAD_NAME = "engine";
|
||||
|
||||
private final ScreenManager screenManager;
|
||||
private final ThreadManager threadManager;
|
||||
private final GameLogic logic;
|
||||
private final OffHeapGarbageCollector garbageCollector;
|
||||
|
||||
private final Thread thread;
|
||||
private final Screen screen;
|
||||
private final ChronoMeter chrono;
|
||||
private final int targetUps;
|
||||
private final ChronoMeter chrono = new ChronoMeter();
|
||||
|
||||
private Thread thread;
|
||||
private Screen screen;
|
||||
private int targetUps;
|
||||
|
||||
private Context context;
|
||||
|
||||
private boolean running = false;
|
||||
|
||||
@Autowired
|
||||
public DefaultGameEngine(ScreenManager screenManager,
|
||||
ThreadManager threadManager,
|
||||
GameLogic logic,
|
||||
OffHeapGarbageCollector garbageCollector,
|
||||
@Value("${app.window.title}") String title,
|
||||
@Value("${app.window.width}") int width,
|
||||
@Value("${app.window.height}") int height,
|
||||
@Value("${app.core.targetUps}") int targetUps) {
|
||||
this.screenManager = screenManager;
|
||||
this.threadManager = threadManager;
|
||||
this.logic = logic;
|
||||
this.garbageCollector = garbageCollector;
|
||||
|
||||
this.screen = screenManager.createScreen(title, width, height);
|
||||
this.thread = threadManager.createThread(THREAD_NAME, this::run);
|
||||
this.chrono = new ChronoMeter();
|
||||
this.targetUps = targetUps;
|
||||
}
|
||||
|
||||
private void run() {
|
||||
try {
|
||||
init();
|
||||
@@ -61,7 +46,7 @@ public class DefaultGameEngine implements GameEngine {
|
||||
log.info("Initializing game engine");
|
||||
screen.init();
|
||||
chrono.init();
|
||||
logic.init(screen);
|
||||
logic.init(screen, context);
|
||||
}
|
||||
|
||||
private void loop() {
|
||||
@@ -102,10 +87,34 @@ public class DefaultGameEngine implements GameEngine {
|
||||
private void cleanUp() {
|
||||
log.info("Performing off heap garbage collection");
|
||||
garbageCollector.cleanUp();
|
||||
|
||||
log.info("Disposing context");
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
public void start(Context context) {
|
||||
this.context = context;
|
||||
|
||||
this.screen = screenManager.createScreen(context.getProjectName(), WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
this.thread = threadManager.createThread(THREAD_NAME, this::run);
|
||||
|
||||
this.targetUps = TARGET_UPS;
|
||||
|
||||
log.info("Starting [{}] thread", THREAD_NAME);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
// TODO
|
||||
// It is supposed to be moved to the Context so that
|
||||
// user will be able to choose default window size,
|
||||
// as well as further possibility to resize the window
|
||||
// or forcing fullscreen mode.
|
||||
// Until it's not implemented yet, the window width and height
|
||||
// are hardcoded right here.
|
||||
//
|
||||
// The same applies for target UPS (updates per second) parameter.
|
||||
private static final int WINDOW_WIDTH = 640;
|
||||
private static final int WINDOW_HEIGHT = 480;
|
||||
private static final int TARGET_UPS = 60;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.core.engine;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.context.Context;
|
||||
|
||||
public interface GameEngine {
|
||||
void start();
|
||||
void start(Context context);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.bartlomiejpluta.base.engine.logic;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.camera.Camera;
|
||||
import com.bartlomiejpluta.base.api.game.context.Context;
|
||||
import com.bartlomiejpluta.base.api.game.screen.Screen;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderer;
|
||||
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.world.camera.DefaultCamera;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -17,18 +15,19 @@ import org.springframework.stereotype.Component;
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultGameLogic implements GameLogic {
|
||||
private final Renderer renderer;
|
||||
private final ProjectLoader projectLoader;
|
||||
private final RenderableContext context;
|
||||
private final Camera camera = new DefaultCamera();
|
||||
|
||||
private Context context;
|
||||
|
||||
@Override
|
||||
public void init(Screen screen) {
|
||||
public void init(Screen screen, Context context) {
|
||||
this.context = context;
|
||||
|
||||
log.info("Initializing game logic");
|
||||
renderer.init();
|
||||
|
||||
Project project = projectLoader.loadProject();
|
||||
|
||||
context.init(screen, camera, project);
|
||||
log.info("Initializing game context");
|
||||
context.init(screen, camera);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package com.bartlomiejpluta.base.engine.logic;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.context.Context;
|
||||
import com.bartlomiejpluta.base.api.game.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.internal.gc.Cleanable;
|
||||
|
||||
public interface GameLogic extends Cleanable {
|
||||
void init(Screen screen);
|
||||
void init(Screen screen, Context context);
|
||||
|
||||
void input(Screen screen);
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.project.model;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.context.Context;
|
||||
|
||||
public interface ContextManager {
|
||||
Context createContext();
|
||||
}
|
||||
@@ -8,68 +8,73 @@ 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;
|
||||
import com.bartlomiejpluta.base.api.internal.render.Renderable;
|
||||
import com.bartlomiejpluta.base.api.internal.render.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||
import com.bartlomiejpluta.base.engine.gui.manager.FontManager;
|
||||
import com.bartlomiejpluta.base.engine.gui.render.NanoVGGUI;
|
||||
import com.bartlomiejpluta.base.engine.project.loader.ClassLoader;
|
||||
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.map.model.DefaultGameMap;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
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 {
|
||||
@Builder
|
||||
public class DefaultContext implements Context {
|
||||
|
||||
@NonNull
|
||||
private final GameEngine engine;
|
||||
|
||||
@NonNull
|
||||
private final EntityManager entityManager;
|
||||
|
||||
@NonNull
|
||||
private final ImageManager imageManager;
|
||||
|
||||
@NonNull
|
||||
private final MapManager mapManager;
|
||||
|
||||
@NonNull
|
||||
private final FontManager fontManager;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
@Getter
|
||||
@NonNull
|
||||
private final GameRunner gameRunner;
|
||||
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String projectName;
|
||||
|
||||
@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<>();
|
||||
|
||||
@SneakyThrows
|
||||
public void init(Screen screen, Camera camera, Project project) {
|
||||
log.info("Initializing game context");
|
||||
@Override
|
||||
public void init(@NonNull Screen screen, @NonNull Camera camera) {
|
||||
this.screen = screen;
|
||||
this.camera = camera;
|
||||
this.project = project;
|
||||
|
||||
var runnerClass = classLoader.<GameRunner>loadClass(project.getRunner());
|
||||
gameRunner = runnerClass.getConstructor().newInstance();
|
||||
|
||||
gameRunner.init(this);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void openMap(String mapUid) {
|
||||
public void openMap(@NonNull String mapUid) {
|
||||
map = mapManager.loadObject(mapUid);
|
||||
mapHandler = mapManager.loadHandler(this, mapUid);
|
||||
|
||||
@@ -77,13 +82,13 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity createEntity(String entitySetUid) {
|
||||
public Entity createEntity(@NonNull String entitySetUid) {
|
||||
log.info("Creating new entity with UID: [{}]", entitySetUid);
|
||||
return entityManager.createEntity(entitySetUid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage(String imageUid) {
|
||||
public Image getImage(@NonNull String imageUid) {
|
||||
return imageManager.loadObject(imageUid);
|
||||
}
|
||||
|
||||
@@ -96,6 +101,7 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
|
||||
return gui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Screen screen) {
|
||||
gameRunner.input(screen);
|
||||
|
||||
@@ -133,11 +139,11 @@ public class RenderableContext implements Context, Updatable, Renderable, Cleana
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("Disposing game runner");
|
||||
gameRunner.dispose();
|
||||
|
||||
public void dispose() {
|
||||
log.info("Disposing GUIs");
|
||||
guis.forEach(GUI::dispose);
|
||||
|
||||
log.info("Disposing game runner");
|
||||
gameRunner.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.bartlomiejpluta.base.engine.project.model;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.context.Context;
|
||||
import com.bartlomiejpluta.base.api.game.runner.GameRunner;
|
||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||
import com.bartlomiejpluta.base.engine.gui.manager.FontManager;
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.project.loader.ClassLoader;
|
||||
import com.bartlomiejpluta.base.engine.project.serial.ProjectDeserializer;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.manager.EntityManager;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.manager.EntitySetManager;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultContextManager implements ContextManager {
|
||||
private final GameEngine engine;
|
||||
private final ProjectConfiguration configuration;
|
||||
private final ProjectDeserializer projectDeserializer;
|
||||
private final TileSetManager tileSetManager;
|
||||
private final MapManager mapManager;
|
||||
private final ImageManager imageManager;
|
||||
private final EntitySetManager entitySetManager;
|
||||
private final FontManager fontManager;
|
||||
private final EntityManager entityManager;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Context createContext() {
|
||||
log.info("Deserializing project file");
|
||||
var resource = DefaultContextManager.class.getResourceAsStream(configuration.projectFile(configuration.getMainFile()));
|
||||
var project = projectDeserializer.deserialize(resource);
|
||||
|
||||
log.info("Registering project assets");
|
||||
project.getTileSetAssets().forEach(tileSetManager::registerAsset);
|
||||
project.getMapAssets().forEach(mapManager::registerAsset);
|
||||
project.getImageAssets().forEach(imageManager::registerAsset);
|
||||
project.getEntitySetAssets().forEach(entitySetManager::registerAsset);
|
||||
project.getFontAssets().forEach(fontManager::registerAsset);
|
||||
|
||||
log.info("Creating game runner instance");
|
||||
var runnerClass = classLoader.<GameRunner>loadClass(project.getRunner());
|
||||
var gameRunner = runnerClass.getConstructor().newInstance();
|
||||
|
||||
log.info("Building context up");
|
||||
return DefaultContext.builder()
|
||||
.engine(engine)
|
||||
.entityManager(entityManager)
|
||||
.imageManager(imageManager)
|
||||
.mapManager(mapManager)
|
||||
.fontManager(fontManager)
|
||||
.gameRunner(gameRunner)
|
||||
.projectName(project.getName())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.bartlomiejpluta.base.engine.thread;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ThreadManager {
|
||||
public Thread createThread(String name, Runnable runnable) {
|
||||
log.info("Creating [{}] thread", name);
|
||||
return new Thread(runnable, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.bartlomiejpluta.base.engine.ui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.game.screen.Screen;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ScreenManager {
|
||||
public Screen createScreen(String title, int width, int height) {
|
||||
log.info("Creating GLFW window ([{}], {}x{})", title, width, height);
|
||||
return GLFWScreen.create(title, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
app:
|
||||
window:
|
||||
title: "Simple Game"
|
||||
width: 640
|
||||
height: 480
|
||||
|
||||
core:
|
||||
targetUps: 50 # Updates per second
|
||||
|
||||
project:
|
||||
main-file: project.bep
|
||||
resource-path: /project
|
||||
@@ -23,9 +15,4 @@ app:
|
||||
down: 0
|
||||
left: 1
|
||||
right: 2
|
||||
up: 3
|
||||
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.bartlomiejpluta.base.core.profiling.time.aspect.ExecutionTimeAspect: DEBUG
|
||||
up: 3
|
||||
Reference in New Issue
Block a user