From 9add9330bb7083d892c1bafa7e316e1ef6e28b74 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Sat, 29 Jun 2024 22:18:09 +0200 Subject: [PATCH] Add completely broken automatic subsystem init --- .../staropensource/sosengine/base/Engine.java | 97 +++++++++++++++++-- .../sosengine/testapp/Main.java | 9 -- 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/base/src/main/java/de/staropensource/sosengine/base/Engine.java b/base/src/main/java/de/staropensource/sosengine/base/Engine.java index 8ebb35e..f3e35f3 100644 --- a/base/src/main/java/de/staropensource/sosengine/base/Engine.java +++ b/base/src/main/java/de/staropensource/sosengine/base/Engine.java @@ -33,15 +33,24 @@ import de.staropensource.sosengine.base.logging.CrashHandler; import de.staropensource.sosengine.base.logging.Logger; import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.types.CodePart; +import de.staropensource.sosengine.base.types.DependencyVector; +import de.staropensource.sosengine.base.types.ImmutableMap; +import de.staropensource.sosengine.base.utility.DependencyResolver; import de.staropensource.sosengine.base.utility.Miscellaneous; import de.staropensource.sosengine.base.utility.PlaceholderEngine; import de.staropensource.sosengine.base.utility.ShortcodeConverter; import lombok.Getter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Range; +import org.reflections.Reflections; +import org.reflections.scanners.Scanners; +import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; /** * sos!engine management object.
@@ -114,12 +123,8 @@ public final class Engine implements SubsystemMainClass { // Only allow one instance if (instance == null) instance = this; - else { - instance.logger.crash("sos!engine tried to initialize twice"); - //noinspection DataFlowIssue - logger = null; + else return; - } long initTime = Miscellaneous.measureExecutionTime(() -> { // Initialize variables @@ -140,6 +145,16 @@ public final class Engine implements SubsystemMainClass { // Start threads startThreads(); + + // Collect subsystems + collectSubsystems(); + + // Initialize subsystems + try { + initializeSubsystems(); + } catch (Exception exception) { + logger.crash("Subsystem dependency resolution failed"); + } }); logger.info("Initialized sos!engine v%engine_version% (commit %engine_git_commit_id_long%-%engine_git_branch%, dirty %engine_git_dirty%) in " + initTime + "ms"); @@ -221,7 +236,7 @@ public final class Engine implements SubsystemMainClass { * * @since 1-alpha0 */ - public void precomputeEventListeners() { + private void precomputeEventListeners() { // Internal events EventHelper.precomputeEventListeners(InternalEngineShutdownEvent.class); @@ -231,6 +246,65 @@ public final class Engine implements SubsystemMainClass { EventHelper.precomputeEventListeners(LogEvent.class); } + /** + * Collects all subsystems by their {@link EngineSubsystem} annotation. + * + * @since 1-alpha1 + */ + private void collectSubsystems() { + Map<@NotNull Class, @NotNull DependencyVector> subsystemsMap = new HashMap<>(); + + // Scan entire classpath through Reflections library + Reflections reflections = new Reflections( + new ConfigurationBuilder() + .setUrls(ClasspathHelper.forJavaClassPath()) + .setScanners(Scanners.TypesAnnotated) + ); + + // Get annotated methods + Set<@NotNull Class> annotatedClasses = reflections.getTypesAnnotatedWith(EngineSubsystem.class); + + // Add to 'subsystemsMap' + for (Class clazz : annotatedClasses) { + try { + //noinspection unchecked + subsystemsMap.put((Class) clazz, (DependencyVector) clazz.getMethod("getDependencyVector").invoke(null)); + } catch (Exception ignored) {} + } + + // Remove null values + for (Class subsystem : subsystemsMap.keySet()) + if (subsystemsMap.get(subsystem) == null) + subsystemsMap.remove(subsystem); + + subsystems = new ImmutableMap<>(subsystemsMap); + } + + /** + * Initializes all subsystems. + * + * @throws Exception exceptions thrown by the {@link DependencyResolver} + * @since 1-alpha1 + */ + private void initializeSubsystems() throws Exception { + DependencyResolver resolver = new DependencyResolver(); + + for (Class subsystem : subsystems.keySet()) + resolver.addVector(subsystems.get(subsystem)); + + /* + try { + resolver.resolve(); + } catch (Exception exception) { + logger.crash("An error occurred trying to initialize engine subsystems: " + exception.getClass().getName() + (exception.getMessage() == null ? "" : ": " + exception.getMessage())); + throw exception; + } + */ + + for (Class subsystem : subsystems.keySet()) + subsystem.getDeclaredConstructor().newInstance(); + } + /** * Starts engine threads. * @@ -261,6 +335,17 @@ public final class Engine implements SubsystemMainClass { Runtime.getRuntime().exit(exitCode); } + /** + * Returns the {@link DependencyVector} for this subsystem. + * + * @see DependencyVector + * @since 1-alpha1 + */ + @Override + public DependencyVector getDependencyVector() { + return new DependencyVector("engine", StarOpenSourceVersioningSystem.class, EngineInformation.getInstance().getVersioningString()); + } + /** * Shuts the engine and JVM down. * 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 8743bd2..5cd59b0 100644 --- a/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java +++ b/testapp/src/main/java/de/staropensource/sosengine/testapp/Main.java @@ -27,9 +27,6 @@ import de.staropensource.sosengine.base.types.Vec2i; import de.staropensource.sosengine.graphics.GraphicsSubsystem; import de.staropensource.sosengine.graphics.classes.ApiMainClass; import de.staropensource.sosengine.graphics.classes.ApiManagementClass; -import de.staropensource.sosengine.graphics.opengl.OpenGlSubsystem; -import de.staropensource.sosengine.graphics.vulkan.VulkanSubsystem; -import de.staropensource.sosengine.slf4j_compat.Slf4jCompatibilitySubsystem; import lombok.Getter; import lombok.SneakyThrows; @@ -101,12 +98,6 @@ public class Main { // Say hello to the world! logger.info("Hello world!"); - // Initialize subsystems - new Slf4jCompatibilitySubsystem(); - new GraphicsSubsystem(); - new OpenGlSubsystem(); - new VulkanSubsystem(); - // Choose Graphics API to use if (!GraphicsSubsystem.getInstance().setGraphicsApi()) { logger.crash("No Graphics API is compatible");