Enable database support in :engine
This commit is contained in:
@@ -12,6 +12,11 @@ import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.internal.gc.Disposable;
|
||||
import com.bartlomiejpluta.base.internal.logic.Updatable;
|
||||
import com.bartlomiejpluta.base.internal.render.Renderable;
|
||||
import com.bartlomiejpluta.base.util.lambda.UncheckedConsumer;
|
||||
import com.bartlomiejpluta.base.util.lambda.UncheckedFunction;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface Context extends Updatable, Renderable, Disposable {
|
||||
GameRunner getGameRunner();
|
||||
@@ -38,6 +43,10 @@ public interface Context extends Updatable, Renderable, Disposable {
|
||||
|
||||
Sound createSound(String soundUid);
|
||||
|
||||
void withDatabase(UncheckedConsumer<Connection, SQLException> consumer);
|
||||
|
||||
<T> T withDatabase(UncheckedFunction<Connection, T, SQLException> extractor);
|
||||
|
||||
void disposeSound(Sound sound);
|
||||
|
||||
void playSound(String soundUid);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.bartlomiejpluta.base.util.lambda;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface UncheckedConsumer<T, E extends Throwable> {
|
||||
|
||||
void accept(T t) throws E;
|
||||
|
||||
default UncheckedConsumer<T, E> andThen(UncheckedConsumer<? super T, ? extends E> after) {
|
||||
Objects.requireNonNull(after);
|
||||
return (T t) -> {
|
||||
accept(t);
|
||||
after.accept(t);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.bartlomiejpluta.base.util.lambda;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface UncheckedFunction<T, R, E extends Throwable> {
|
||||
|
||||
R apply(T t) throws E;
|
||||
|
||||
default <V> UncheckedFunction<V, R, E> compose(UncheckedFunction<? super V, ? extends T, ? extends E> before) {
|
||||
Objects.requireNonNull(before);
|
||||
return (V v) -> apply(before.apply(v));
|
||||
}
|
||||
|
||||
default <V> UncheckedFunction<T, V, E> andThen(UncheckedFunction<? super R, ? extends V, ? extends E> after) {
|
||||
Objects.requireNonNull(after);
|
||||
return (T t) -> after.apply(apply(t));
|
||||
}
|
||||
|
||||
static <T, E extends Throwable> UncheckedFunction<T, T, E> identity() {
|
||||
return t -> t;
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,8 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-freemarker'
|
||||
implementation "org.slf4j:jul-to-slf4j:${slf4jVersion}"
|
||||
|
||||
// Database
|
||||
implementation "com.h2database:h2:${h2Version}"
|
||||
implementation "com.zaxxer:HikariCP:${hikariVersion}"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ class DataSource(dbFile: File) {
|
||||
|
||||
init {
|
||||
config.jdbcUrl = "jdbc:h2:file:${dbFile.absolutePath.replace("\\", "/")}"
|
||||
config.username = "root"
|
||||
config.password = ""
|
||||
source = HikariDataSource(config)
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,10 @@ dependencies {
|
||||
|
||||
// This dependency is used by the application.
|
||||
implementation "org.joml:joml:${jomlVersion}"
|
||||
|
||||
// Database
|
||||
implementation "com.h2database:h2:${h2Version}"
|
||||
implementation "com.zaxxer:HikariCP:${hikariVersion}"
|
||||
}
|
||||
|
||||
application {
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||
import com.bartlomiejpluta.base.engine.audio.manager.SoundManager;
|
||||
import com.bartlomiejpluta.base.engine.context.model.DefaultContext;
|
||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||
import com.bartlomiejpluta.base.engine.database.service.DatabaseService;
|
||||
import com.bartlomiejpluta.base.engine.gui.manager.FontManager;
|
||||
import com.bartlomiejpluta.base.engine.gui.manager.WidgetDefinitionManager;
|
||||
import com.bartlomiejpluta.base.engine.gui.xml.inflater.Inflater;
|
||||
@@ -41,6 +42,7 @@ public class DefaultContextManager implements ContextManager {
|
||||
private final Inflater inflater;
|
||||
private final WidgetDefinitionManager widgetDefinitionManager;
|
||||
private final SoundManager soundManager;
|
||||
private final DatabaseService databaseService;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
@@ -74,6 +76,7 @@ public class DefaultContextManager implements ContextManager {
|
||||
.inflater(inflater)
|
||||
.widgetDefinitionManager(widgetDefinitionManager)
|
||||
.soundManager(soundManager)
|
||||
.databaseService(databaseService)
|
||||
.gameRunner(gameRunner)
|
||||
.projectName(project.getName())
|
||||
.build();
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.engine.audio.manager.SoundManager;
|
||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||
import com.bartlomiejpluta.base.engine.database.service.DatabaseService;
|
||||
import com.bartlomiejpluta.base.engine.gui.manager.FontManager;
|
||||
import com.bartlomiejpluta.base.engine.gui.manager.WidgetDefinitionManager;
|
||||
import com.bartlomiejpluta.base.engine.gui.render.NanoVGGUI;
|
||||
@@ -23,12 +24,16 @@ 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 com.bartlomiejpluta.base.internal.render.ShaderManager;
|
||||
import com.bartlomiejpluta.base.util.lambda.UncheckedConsumer;
|
||||
import com.bartlomiejpluta.base.util.lambda.UncheckedFunction;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -63,6 +68,9 @@ public class DefaultContext implements Context {
|
||||
@NonNull
|
||||
private final SoundManager soundManager;
|
||||
|
||||
@NonNull
|
||||
private final DatabaseService databaseService;
|
||||
|
||||
@Getter
|
||||
@NonNull
|
||||
private final GameRunner gameRunner;
|
||||
@@ -145,6 +153,25 @@ public class DefaultContext implements Context {
|
||||
return soundManager.loadObject(soundUid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void withDatabase(UncheckedConsumer<Connection, SQLException> consumer) {
|
||||
try (var connection = databaseService.getConnection()) {
|
||||
consumer.accept(connection);
|
||||
} catch (SQLException e) {
|
||||
log.error("SQL Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T withDatabase(UncheckedFunction<Connection, T, SQLException> extractor) {
|
||||
try (var connection = databaseService.getConnection()) {
|
||||
return extractor.apply(connection);
|
||||
} catch (SQLException e) {
|
||||
log.error("SQL Error", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeSound(Sound sound) {
|
||||
soundManager.disposeSound(sound);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.bartlomiejpluta.base.engine.database.service;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.init.Initializable;
|
||||
import com.bartlomiejpluta.base.internal.gc.Cleanable;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
public interface DatabaseService extends Initializable, Cleanable {
|
||||
Connection getConnection();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.bartlomiejpluta.base.engine.database.service;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.util.res.ResourcesManager;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.h2.tools.RunScript;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.sql.Connection;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class H2DatabaseService implements DatabaseService {
|
||||
private static final String CONNECTION_STRING = "jdbc:h2:mem:main";
|
||||
private final ProjectConfiguration configuration;
|
||||
private final ResourcesManager resourcesManager;
|
||||
private HikariDataSource source;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void init() {
|
||||
log.info("Starting in-memory database");
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl(CONNECTION_STRING);
|
||||
this.source = new HikariDataSource(config);
|
||||
|
||||
log.info("Loading data into in-memory database");
|
||||
var data = resourcesManager.loadResourceAsStream(configuration.getDatabaseScriptFile());
|
||||
RunScript.execute(getConnection(), new InputStreamReader(data));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return source.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("Closing in-memory database connection pool");
|
||||
source.close();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import java.nio.file.Path;
|
||||
public class ProjectConfiguration {
|
||||
private String mainFile;
|
||||
private String resourcePath;
|
||||
|
||||
private String databaseScriptFile;
|
||||
|
||||
public String projectFile(String... path) {
|
||||
return Path.of(resourcePath, path).toString().replaceAll("\\\\", "/");
|
||||
|
||||
@@ -2,6 +2,7 @@ app:
|
||||
project:
|
||||
main-file: project.bep
|
||||
resource-path: /project
|
||||
database-script-file: /database/data.sql
|
||||
|
||||
sprite:
|
||||
entity:
|
||||
|
||||
Reference in New Issue
Block a user