Enable database support in :engine

This commit is contained in:
2021-03-26 21:44:37 +01:00
parent 0cde898b51
commit dac79b9fd1
12 changed files with 147 additions and 3 deletions

View File

@@ -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);

View File

@@ -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);
};
}
}

View File

@@ -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;
}
}

View File

@@ -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}"
}

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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("\\\\", "/");

View File

@@ -2,6 +2,7 @@ app:
project:
main-file: project.bep
resource-path: /project
database-script-file: /database/data.sql
sprite:
entity: