diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/info/EngineInformation.java b/base/src/main/java/de/staropensource/sosengine/base/data/info/EngineInformation.java
index 91a6f13..d095fe1 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/data/info/EngineInformation.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/info/EngineInformation.java
@@ -170,6 +170,19 @@ public final class EngineInformation {
*/
private String dependencySlf4j;
+ /**
+ * Provides the version of the dependency {@code LWJGL}.
+ *
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Provides the version of the dependency {@code LWJGL}.
+ *
+ * @return LWJGL dependency version
+ * @since 1-alpha0
+ */
+ private String dependencyLwjgl;
+
/**
* Provides the version of the Gradle plugin {@code Shadow}.
*
@@ -243,6 +256,7 @@ public final class EngineInformation {
dependencyJansi = parser.getString("dependencyJansi");
dependencyReflections = parser.getString("dependencyReflections");
dependencySlf4j = parser.getString("dependencySlf4j");
+ dependencyLwjgl = parser.getString("dependencyLwjgl");
pluginShadow = parser.getString("pluginShadow");
pluginLombok = parser.getString("pluginLombok");
diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/placeholders/EngineDependencyLwjgl.java b/base/src/main/java/de/staropensource/sosengine/base/data/placeholders/EngineDependencyLwjgl.java
new file mode 100644
index 0000000..e232569
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/placeholders/EngineDependencyLwjgl.java
@@ -0,0 +1,53 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.base.data.placeholders;
+
+import de.staropensource.sosengine.base.classes.Placeholder;
+import de.staropensource.sosengine.base.data.info.EngineInformation;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Implements the {@code engine_dependency_lwjgl} placeholder.
+ *
+ * @see Placeholder
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused" })
+public final class EngineDependencyLwjgl implements Placeholder {
+ /**
+ * Constructor.
+ *
+ * @since 1-alpha0
+ */
+ public EngineDependencyLwjgl() {}
+
+ /** {@inheritDoc} */
+ @NotNull
+ public String getName() {
+ return "engine_dependency_lwjgl";
+ }
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override
+ public String replace(@NotNull String text) {
+ return text.replace("%" + getName() + "%", EngineInformation.getInstance().getDependencyLwjgl());
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/utility/PlaceholderEngine.java b/base/src/main/java/de/staropensource/sosengine/base/utility/PlaceholderEngine.java
index 62aacbd..d3d1913 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/utility/PlaceholderEngine.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/utility/PlaceholderEngine.java
@@ -91,6 +91,7 @@ public final class PlaceholderEngine {
placeholders.add(new EngineDependencyLombok());
placeholders.add(new EngineDependencyJetbrainsAnnotations());
placeholders.add(new EngineDependencyJansi());
+ placeholders.add(new EngineDependencyLwjgl());
placeholders.add(new EngineDependencyReflections());
placeholders.add(new EngineDependencySlf4j());
// engine_plugin_*
diff --git a/gradle.properties b/gradle.properties
index 65542e3..46a8134 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -12,6 +12,8 @@ dependencyJetbrainsAnnotations=24.1.0
dependencyJansi=2.4.1
dependencyReflections=0.10.2
dependencySlf4j=2.0.13
+dependencyLwjgl=3.3.3
+dependencyLwjglNatives=
# Test dependencies
dependencyJunit=11.0-M2
diff --git a/graphics/build.gradle b/graphics/build.gradle
new file mode 100644
index 0000000..70e2364
--- /dev/null
+++ b/graphics/build.gradle
@@ -0,0 +1,46 @@
+plugins {
+ id 'java'
+ id 'io.freefair.lombok' version "${pluginLombok}"
+}
+
+dependencies {
+ // -> Runtime <-
+ // Lombok
+ compileOnly 'org.projectlombok:lombok:' + project.dependencyLombok
+ annotationProcessor 'org.projectlombok:lombok:' + project.dependencyLombok
+
+ // JetBrains Annotations
+ compileOnly 'org.jetbrains:annotations:' + project.dependencyJetbrainsAnnotations
+
+ // -> Testing <-
+ // Jetbrains Annotations
+ testCompileOnly 'org.jetbrains:annotations:' + project.dependencyJetbrainsAnnotations
+
+ // JUnit
+ testImplementation platform('org.junit:junit-bom:5.' + project.dependencyJunit)
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+
+ // jOOR
+ testImplementation 'org.jooq:joor:' + project.dependencyJoor
+
+ // -> Project <-
+ implementation project(":base")
+}
+
+javadoc.options {
+ setMemberLevel(JavadocMemberLevel.PUBLIC)
+ setOverview("src/main/javadoc/overview.html")
+ setLocale("en_US")
+ setJFlags([
+ // Force Javadoc to use English translations
+ "-Duser.language=en_US"
+ ])
+}
+
+test {
+ useJUnitPlatform()
+ testLogging {
+ events "passed", "skipped", "failed"
+ }
+}
diff --git a/graphics/gradle b/graphics/gradle
new file mode 120000
index 0000000..3337596
--- /dev/null
+++ b/graphics/gradle
@@ -0,0 +1 @@
+../gradle
\ No newline at end of file
diff --git a/graphics/gradlew b/graphics/gradlew
new file mode 120000
index 0000000..502f5a2
--- /dev/null
+++ b/graphics/gradlew
@@ -0,0 +1 @@
+../gradlew
\ No newline at end of file
diff --git a/graphics/gradlew.bat b/graphics/gradlew.bat
new file mode 120000
index 0000000..2840132
--- /dev/null
+++ b/graphics/gradlew.bat
@@ -0,0 +1 @@
+../gradlew.bat
\ No newline at end of file
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java
new file mode 100644
index 0000000..c2fb8b9
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java
@@ -0,0 +1,227 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.graphics;
+
+import de.staropensource.sosengine.base.annotations.EventListener;
+import de.staropensource.sosengine.base.classes.EventPriority;
+import de.staropensource.sosengine.base.classes.SubsystemMainClass;
+import de.staropensource.sosengine.base.classes.helpers.EventHelper;
+import de.staropensource.sosengine.base.events.internal.InternalEngineShutdownEvent;
+import de.staropensource.sosengine.base.logging.LoggerInstance;
+import de.staropensource.sosengine.base.types.LogIssuer;
+import de.staropensource.sosengine.base.utility.ListFormatter;
+import de.staropensource.sosengine.base.utility.Miscellaneous;
+import de.staropensource.sosengine.graphics.classes.ApiMainClass;
+import de.staropensource.sosengine.graphics.events.GraphicsApiShutdownEvent;
+import de.staropensource.sosengine.graphics.events.GraphicsErrorEvent;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * The main object for sos!engine's graphics subsystem.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+public final class GraphicsSubsystem implements SubsystemMainClass {
+ /**
+ * Instance.
+ *
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Returns the {@link GraphicsSubsystem} instance.
+ *
+ * @return {@link GraphicsSubsystem} instance unless uninitialized
+ * @since 1-alpha0
+ */
+ @Getter
+ private static GraphicsSubsystem instance = null;
+
+ /**
+ * Logger instance.
+ *
+ * @see LoggerInstance
+ * @since 1-alpha0
+ */
+ private final LoggerInstance logger = new LoggerInstance(new LogIssuer(getClass()));
+
+ /**
+ * A list of all registered Graphics APIs.
+ *
+ * @see ApiMainClass
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Returns a list of all registered Graphics APIs.
+ *
+ * @return list of all registered Graphics APIs
+ * @see ApiMainClass
+ * @since 1-alpha0
+ */
+ @NotNull
+ @Getter
+ private final Map<@NotNull String, @NotNull ApiMainClass> registeredApis = new HashMap<>();
+
+ /**
+ * Reference to the active Graphics API main class.
+ *
+ * @see ApiMainClass
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Returns the active Graphics API main class.
+ *
+ * @return active Graphics API main class
+ * @see ApiMainClass
+ * @since 1-alpha0
+ */
+ @Nullable
+ @Getter
+ private ApiMainClass api = null;
+
+ /**
+ * Constructor.
+ *
+ * @since 1-alpha0
+ */
+ public GraphicsSubsystem() {
+ // Check if subsystem has already initialized
+ if (instance == null)
+ instance = this;
+ else {
+ instance.logger.crash("Graphics subsystem tried to initialize twice");
+ return;
+ }
+
+ logger.verb("Initializing subsystem");
+
+ long initTime = Miscellaneous.measureExecutionTime(() -> {
+ // Initialize GraphicsSubsystemConfiguration and load it
+ new GraphicsSubsystemConfiguration();
+ GraphicsSubsystemConfiguration.getInstance().loadConfiguration();
+
+ // Precompute event listeners
+ precomputeEventListeners();
+ });
+
+ logger.info("Initialized subsystem in " + initTime + "ms");
+ }
+
+ /**
+ * Precomputes all graphics subsystem events.
+ *
+ * @since 1-alpha0
+ */
+ public static void precomputeEventListeners() {
+ EventHelper.precomputeEventListeners(GraphicsApiShutdownEvent.class);
+ EventHelper.precomputeEventListeners(GraphicsErrorEvent.class);
+ }
+
+ /**
+ * Shuts the graphics subsystem down.
+ *
+ * @since 1-alpha0
+ */
+ @EventListener(event = InternalEngineShutdownEvent.class, priority = EventPriority.EXTREMELY_UNIMPORTANT)
+ public static void shutdown() {
+ LoggerInstance logger = instance.logger;
+ logger.verb("Shutting down");
+
+ long shutdownTime = Miscellaneous.measureExecutionTime(() -> new GraphicsApiShutdownEvent().callEvent());
+
+ logger.info("Shut down in " + shutdownTime + "ms");
+ }
+
+ /**
+ * Registers a Graphics API.
+ *
+ * @param mainClass main class of the subsystem
+ * @since 1-alpha0
+ */
+ public void registerGraphicsApi(@NotNull ApiMainClass mainClass) {
+ logger.verb("Registering Graphics API " + mainClass.getApiName() + " (" + mainClass.getClass().getName() + ")");
+
+ Object[] output = Miscellaneous.getMapValue(registeredApis, mainClass).toArray();
+
+ if (output.length == 0 || output[0] == null)
+ registeredApis.put(mainClass.getApiName(), mainClass);
+ }
+
+ /**
+ * Chooses a Graphics API to use automatically based on hardware support.
+ *
+ * @return if a compatible Graphics API has been chosen
+ * @see GraphicsSubsystem#setGraphicsApi(String)
+ * @since 1-alpha0
+ */
+ public boolean setGraphicsApi() {
+ logger.verb("Choosing a compatible Graphics API");
+
+ List<@NotNull String> compatibleApis = new ArrayList<>();
+
+ // Check if registered apis are compatible
+ for (String apiName : registeredApis.keySet())
+ if (registeredApis.get(apiName).isCompatible()) {
+ logger.diag("Choosing a compatible Graphics API: " + apiName + " is compatible");
+ compatibleApis.add(apiName);
+ } else
+ logger.diag("Choosing a compatible Graphics API: " + apiName + " is not compatible");
+
+ logger.diag("Choosing a compatible Graphics API: Compatible are: " + ListFormatter.formatList(compatibleApis));
+
+ // Choose last item in list.
+ if (!compatibleApis.isEmpty()) {
+ logger.verb("Choosing a compatible Graphics API: Chose Graphics API " + compatibleApis.getLast());
+
+ api = registeredApis.get(compatibleApis.getLast());
+ api.initializeApi();
+
+ return true;
+ } else {
+ logger.error("Choosing a compatible Graphics API: No compatible Graphics API found");
+ return false;
+ }
+ }
+
+ /**
+ * Sets the Graphics API to use.
+ *
+ * @param name name of the Graphics API
+ * @see GraphicsSubsystem#setGraphicsApi()
+ * @since 1-alpha0
+ */
+ public void setGraphicsApi(@NotNull String name) {
+ logger.verb("Setting Graphics API " + name);
+
+ if (!registeredApis.containsKey(name))
+ logger.crash("Unable to set Graphics API: Graphics API " + name + " is not registered");
+
+ if (api == null)
+ api = registeredApis.get(name);
+ else
+ logger.crash("Unable to set Graphics API: Graphics API " + api.getApiName() + " already registered");
+
+ api.initializeApi();
+ }
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java
new file mode 100644
index 0000000..7cbb56e
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java
@@ -0,0 +1,169 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.graphics;
+
+import de.staropensource.sosengine.base.classes.SubsystemConfiguration;
+import de.staropensource.sosengine.base.logging.Logger;
+import de.staropensource.sosengine.base.types.CodePart;
+import de.staropensource.sosengine.base.types.LogIssuer;
+import de.staropensource.sosengine.base.utility.PropertyParser;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Properties;
+
+/**
+ * Provides the engine configuration for all classes in a centralized place.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+@Getter
+public final class GraphicsSubsystemConfiguration implements SubsystemConfiguration {
+ /**
+ * Instance.
+ *
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Returns the {@link GraphicsSubsystemConfiguration} instance.
+ *
+ * @return {@link GraphicsSubsystemConfiguration} instance
+ * @since 1-alpha0
+ */
+ @Getter
+ private static GraphicsSubsystemConfiguration instance;
+
+ /**
+ * Defines the group every property must start with to be recognized as a subsystem configuration setting.
+ *
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Returns the group that every property must start with to be recognized as a subsystem configuration setting.
+ *
+ * @return property group
+ * @since 1-alpha0
+ */
+ @NotNull
+ @Getter
+ private static final String group = "sosengine.graphics.";
+
+ /**
+ * If enabled, allows for unintentional behaviour and excess logging.
+ * Unless you want to debug or work on a sensitive part of the graphics subsystem, don't enable this!
+ *
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Gets the value for {@code debug}.
+ *
+ * @return variable value
+ * @see GraphicsSubsystemConfiguration#debug
+ * @since 1-alpha0
+ */
+ private boolean debug;
+
+ /**
+ * If enabled, graphical errors thrown by GLFW will be printed to the log by the subsystem.
+ *
+ * @see de.staropensource.sosengine.graphics.events.GraphicsErrorEvent
+ * @since 1-alpha0
+ *
+ * -- GETTER --
+ * Gets the value for {@code errorGraphicsError}.
+ *
+ * @return variable value
+ * @see GraphicsSubsystemConfiguration#errorGraphicsError
+ * @since 1-alpha0
+ */
+ private boolean errorGraphicsError;
+
+ /**
+ * Constructor.
+ *
+ * @see GraphicsSubsystem
+ * @since 1-alpha0
+ */
+ public GraphicsSubsystemConfiguration() {
+ // Only allow one instance
+ if (instance == null)
+ instance = this;
+ else
+ Logger.crash(new LogIssuer(getClass(), CodePart.ENGINE), "Tried reinitializing " + getClass().getName() + " twice");
+
+ loadDefaultConfiguration();
+ }
+
+ /** {@inheritDoc} */
+ public void loadConfiguration(@NotNull Properties properties) {
+ // Define variables
+ PropertyParser parser = new PropertyParser(properties);
+
+ for (String property : properties.stringPropertyNames()) {
+ // Check if property name starts with group
+ if (!property.startsWith(group)) continue;
+
+ // Skip to important stuff
+ property = property.substring(group.length());
+
+ // Match settings
+ try {
+ switch (property) {
+ case "debug" -> debug = parser.getBoolean(group + property);
+
+ case "errorGraphicsError" -> errorGraphicsError = parser.getBoolean(group + property);
+ }
+ } catch (NullPointerException ignored) {}
+ }
+
+ // Disable all debug options if 'debug' is disabled
+ //if (!debug) {}
+ }
+
+ /** {@inheritDoc} */
+ public void loadConfiguration() {
+ loadConfiguration(System.getProperties());
+ }
+
+ /** {@inheritDoc} */
+ public void loadDefaultConfiguration() {
+ debug = false;
+
+ errorGraphicsError = true;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable
+ public Object getSetting(@NotNull String setting) {
+ switch (setting) {
+ case "debug" -> {
+ return debug;
+ }
+ case "errorGraphicsError" -> {
+ return errorGraphicsError;
+ }
+ default -> {
+ return null;
+ }
+ }
+ }
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiMainClass.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiMainClass.java
new file mode 100644
index 0000000..a864e0a
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiMainClass.java
@@ -0,0 +1,87 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.graphics.classes;
+
+import de.staropensource.sosengine.base.Engine;
+import de.staropensource.sosengine.base.annotations.EventListener;
+import de.staropensource.sosengine.base.classes.EventPriority;
+import de.staropensource.sosengine.base.classes.SubsystemMainClass;
+import de.staropensource.sosengine.base.events.internal.InternalEngineShutdownEvent;
+import de.staropensource.sosengine.graphics.events.GraphicsErrorEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * The interface for Graphics API main classes.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused" })
+public interface ApiMainClass extends SubsystemMainClass {
+ /**
+ * Initializes the Graphics API.
+ *
+ * @since 1-alpha0
+ */
+ void initializeApi();
+
+ /**
+ * Returns the name of the Graphics API.
+ *
+ * @since 1-alpha0
+ */
+ String getApiName();
+
+ /**
+ * Returns the Graphics API's management class.
+ *
+ * @return a {@link ApiManagementClass}
+ * @see ApiManagementClass
+ * @since 1-alpha0
+ */
+ @NotNull
+ ApiManagementClass getManagement();
+
+ /**
+ * Checks if the Graphics API is compatible with the underlying hardware.
+ *
+ * @return if the Graphics API is compatible
+ * @since 1-alpha0
+ */
+ boolean isCompatible();
+
+ /**
+ * Called when a graphics error occurs.
+ *
+ * @param error graphics error
+ * @since 1-alpha0
+ */
+ @EventListener(event = GraphicsErrorEvent.class)
+ static void onGraphicsError(String error) {}
+
+ /**
+ * Called when the engine shuts down.
+ *
+ * @see Engine#shutdown()
+ * @see Engine#shutdown(int)
+ * @since 1-alpha0
+ */
+ @EventListener(event = InternalEngineShutdownEvent.class, priority = EventPriority.EXTREMELY_UNIMPORTANT)
+ static void shutdownApi() {}
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java
new file mode 100644
index 0000000..49cf717
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java
@@ -0,0 +1,39 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.graphics.classes;
+
+import de.staropensource.sosengine.base.classes.Vec2i;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * The interface for Graphics API management classes.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+public interface ApiManagementClass {
+ /**
+ * Creates a new {@link Window}.
+ *
+ * @since 1-alpha0
+ */
+ @NotNull
+ Window createWindow(String title, Vec2i size);
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java
new file mode 100644
index 0000000..fbb818c
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java
@@ -0,0 +1,58 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.graphics.classes;
+
+import de.staropensource.sosengine.base.classes.Vec2i;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A window on your screen.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
+public interface Window {
+ /**
+ * A set of all active windows.
+ *
+ * @since 1-alpha0
+ */
+ @NotNull
+ Set extends @NotNull Window> windows = new HashSet<>();
+
+ /**
+ * The window name.
+ *
+ * @since 1-alpha0
+ */
+ @NotNull
+ String windowName = "Hello Window!";
+
+ /**
+ * The window size.
+ *
+ * @since 1-alpha0
+ */
+ @NotNull
+ Vec2i windowSize = new Vec2i(0, 0);
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsApiShutdownEvent.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsApiShutdownEvent.java
new file mode 100644
index 0000000..4c75c4c
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsApiShutdownEvent.java
@@ -0,0 +1,43 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.sosengine.graphics.events;
+
+import de.staropensource.sosengine.base.classes.Event;
+import de.staropensource.sosengine.base.classes.helpers.EventHelper;
+
+/**
+ * Called when the Graphics API shuts down.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused" })
+public class GraphicsApiShutdownEvent implements Event {
+ /**
+ * Constructor.
+ */
+ public GraphicsApiShutdownEvent() {}
+
+
+ /** {@inheritDoc} */
+ @Override
+ public void callEvent() {
+ EventHelper.invokeAnnotatedMethods(getClass());
+ }
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsErrorEvent.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsErrorEvent.java
new file mode 100644
index 0000000..7a1bc26
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsErrorEvent.java
@@ -0,0 +1,49 @@
+package de.staropensource.sosengine.graphics.events;
+
+import de.staropensource.sosengine.base.classes.Event;
+import de.staropensource.sosengine.base.events.LogEvent;
+import de.staropensource.sosengine.base.types.LogIssuer;
+import de.staropensource.sosengine.base.types.LogLevel;
+import de.staropensource.sosengine.base.classes.helpers.EventHelper;
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Called when a graphics error occurs.
+ *
+ * @since 1-alpha0
+ */
+@SuppressWarnings({ "unused" })
+public class GraphicsErrorEvent implements Event {
+ /**
+ * Constructor.
+ */
+ public GraphicsErrorEvent() {}
+
+ /**
+ * {@inheritDoc}
+ * @deprecated use the {@code callEvent} method with arguments
+ * @see LogEvent#callEvent(LogLevel, LogIssuer, String)
+ */
+ @Deprecated
+ @Override
+ public void callEvent() {}
+
+ /**
+ * Calls the event and notifies all annotated methods.
+ *
+ * @param error graphics error
+ * @since 1-alpha0
+ */
+ public void callEvent(@NotNull String error) {
+ EventHelper.logCall(getClass());
+
+ for (Method method : EventHelper.getAnnotatedMethods(getClass())) {
+ try {
+ method.invoke(null, error);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException | ExceptionInInitializerError ignored) {}
+ }
+ }
+}
diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/package-info.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/package-info.java
new file mode 100644
index 0000000..ddced00
--- /dev/null
+++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/package-info.java
@@ -0,0 +1,23 @@
+/*
+ STAROPENSOURCE ENGINE SOURCE FILE
+ Copyright (c) 2024 The StarOpenSource Engine Contributors
+ Licensed under the GNU Affero General Public License v3
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+/**
+ * Contains the code required for drawing things to a screen.
+ */
+package de.staropensource.sosengine.graphics;
diff --git a/settings.gradle b/settings.gradle
index 07102fb..a43ff67 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,4 +2,5 @@ rootProject.name = 'sosengine'
include 'base'
include 'slf4j-compat'
+include 'graphics'
include 'testapp'
diff --git a/testapp/build.gradle b/testapp/build.gradle
index 7309cc3..16ae7c3 100644
--- a/testapp/build.gradle
+++ b/testapp/build.gradle
@@ -17,6 +17,7 @@ dependencies {
// -> Project <-
implementation project(":base")
implementation project(":slf4j-compat")
+ implementation project(":graphics")
}
javadoc.options {
diff --git a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java
index f4d6b3f..43e51d0 100644
--- a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java
+++ b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java
@@ -20,10 +20,15 @@
package de.staropensource.sosengine.testapp;
import de.staropensource.sosengine.base.Engine;
+import de.staropensource.sosengine.base.classes.Vec2i;
import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.LogIssuer;
+import de.staropensource.sosengine.graphics.GraphicsSubsystem;
+import de.staropensource.sosengine.graphics.classes.ApiMainClass;
+import de.staropensource.sosengine.graphics.classes.ApiManagementClass;
import de.staropensource.sosengine.slf4j_compat.Slf4jCompatibilitySubsystem;
import lombok.Getter;
+import lombok.SneakyThrows;
/**
* The initialization class for sos!engine's development application.
@@ -85,6 +90,7 @@ public class Main {
* @see Main#main(String[])
* @param args program's command line arguments
*/
+ @SneakyThrows
public void run(String[] args) {
// Initialize sos!engine
engine = new Engine();
@@ -94,6 +100,19 @@ public class Main {
// Initialize subsystems
new Slf4jCompatibilitySubsystem();
+ new GraphicsSubsystem();
+
+ // Choose Graphics API to use
+ if (!GraphicsSubsystem.getInstance().setGraphicsApi()) {
+ logger.crash("No Graphics API is compatible");
+ }
+
+ // Define 'api' & 'management' variables
+ ApiMainClass api = GraphicsSubsystem.getInstance().getApi();
+ ApiManagementClass management = api.getManagement();
+
+ // Create window
+ management.createWindow("Test", new Vec2i(960, 540));
// Sleep for five seconds
Thread.sleep(5000);