From 147455cedd2f56930af181a73aa8a6b442e8edf9 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Tue, 11 Jun 2024 23:08:03 +0200 Subject: [PATCH] Add WIP graphics subsystem --- .../base/data/info/EngineInformation.java | 14 ++ .../placeholders/EngineDependencyLwjgl.java | 53 ++++ .../base/utility/PlaceholderEngine.java | 1 + gradle.properties | 2 + graphics/build.gradle | 46 ++++ graphics/gradle | 1 + graphics/gradlew | 1 + graphics/gradlew.bat | 1 + .../sosengine/graphics/GraphicsSubsystem.java | 227 ++++++++++++++++++ .../GraphicsSubsystemConfiguration.java | 169 +++++++++++++ .../graphics/classes/ApiMainClass.java | 87 +++++++ .../graphics/classes/ApiManagementClass.java | 39 +++ .../sosengine/graphics/classes/Window.java | 58 +++++ .../events/GraphicsApiShutdownEvent.java | 43 ++++ .../graphics/events/GraphicsErrorEvent.java | 49 ++++ .../sosengine/graphics/package-info.java | 23 ++ settings.gradle | 1 + testapp/build.gradle | 1 + .../sosengine/testapp/Main.java | 19 ++ 19 files changed, 835 insertions(+) create mode 100644 base/src/main/java/de/staropensource/sosengine/base/data/placeholders/EngineDependencyLwjgl.java create mode 100644 graphics/build.gradle create mode 120000 graphics/gradle create mode 120000 graphics/gradlew create mode 120000 graphics/gradlew.bat create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystemConfiguration.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiMainClass.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/classes/ApiManagementClass.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/classes/Window.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsApiShutdownEvent.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/events/GraphicsErrorEvent.java create mode 100644 graphics/src/main/java/de/staropensource/sosengine/graphics/package-info.java 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 91a6f13b..d095fe15 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 00000000..e2325690 --- /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 62aacbde..d3d19135 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 65542e38..46a81340 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 00000000..70e23644 --- /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 00000000..3337596a --- /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 00000000..502f5a2d --- /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 00000000..28401328 --- /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 00000000..c2fb8b92 --- /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 00000000..7cbb56ef --- /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 00000000..a864e0ae --- /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 00000000..49cf7175 --- /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 00000000..fbb818c1 --- /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 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 00000000..4c75c4c1 --- /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 00000000..7a1bc269 --- /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 00000000..ddced004 --- /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 07102fb1..a43ff67b 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 7309cc37..16ae7c35 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 f4d6b3f8..43e51d00 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);