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 e677ea3..b5152b9 100644 --- a/base/src/main/java/de/staropensource/sosengine/base/Engine.java +++ b/base/src/main/java/de/staropensource/sosengine/base/Engine.java @@ -47,10 +47,7 @@ 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; +import java.util.*; /** * sos!engine management object.
@@ -98,7 +95,7 @@ public final class Engine implements SubsystemMainClass { */ @NotNull @Getter - private ImmutableMap<@NotNull Class, @NotNull DependencyVector> subsystems = new ImmutableMap<>(); + private ImmutableMap<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystems = new ImmutableMap<>(); /** * Indicates if the engine is shutting down. @@ -115,7 +112,7 @@ public final class Engine implements SubsystemMainClass { private boolean shuttingDown = false; /** - * Constructor, initializes the StarOpenSource Engine. + * Initializes the StarOpenSource Engine. * * @since 1-alpha0 */ @@ -153,7 +150,7 @@ public final class Engine implements SubsystemMainClass { try { initializeSubsystems(); } catch (Exception exception) { - logger.crash("Subsystem dependency resolution failed"); + logger.crash("Subsystem dependency resolution failed", exception); } }); @@ -252,9 +249,9 @@ public final class Engine implements SubsystemMainClass { * @since 1-alpha1 */ private void collectSubsystems() { - Map<@NotNull Class, @NotNull DependencyVector> subsystemsMap = new HashMap<>(); + Map<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystemsMap = new HashMap<>(); - // Scan entire classpath through Reflections library + // Scan entire classpath using the Reflections library Reflections reflections = new Reflections( new ConfigurationBuilder() .setUrls(ClasspathHelper.forJavaClassPath()) @@ -264,16 +261,27 @@ public final class Engine implements SubsystemMainClass { // Get annotated methods Set<@NotNull Class> annotatedClasses = reflections.getTypesAnnotatedWith(EngineSubsystem.class); - // Add to 'subsystemsMap' + // Initialize class, get dependency vector and add to 'subsystemsMap' for (Class clazz : annotatedClasses) { try { - //noinspection unchecked - subsystemsMap.put((Class) clazz, (DependencyVector) clazz.getMethod("getDependencyVector").invoke(null)); - } catch (Exception ignored) {} + // Create new instance + Object initializedClassRaw = clazz.getDeclaredConstructor().newInstance(); + SubsystemMainClass initializedClass = null; + + // Check if class implements SubsystemMainClass + if (initializedClassRaw instanceof SubsystemMainClass subsystemInstance) + initializedClass = subsystemInstance; + else + logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Does not implement " + SubsystemMainClass.class.getName()); + + subsystemsMap.put(Objects.requireNonNull(initializedClass), initializedClass.getDependencyVector()); + } catch (Exception exception) { + logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Method invocation error", exception); + } } - // Remove null values - for (Class subsystem : subsystemsMap.keySet()) + // Remove entries with null values + for (SubsystemMainClass subsystem : subsystemsMap.keySet()) if (subsystemsMap.get(subsystem) == null) subsystemsMap.remove(subsystem); @@ -287,22 +295,25 @@ public final class Engine implements SubsystemMainClass { * @since 1-alpha1 */ private void initializeSubsystems() throws Exception { + logger.verb("Preparing subsystem initialization"); DependencyResolver resolver = new DependencyResolver(); - for (Class subsystem : subsystems.keySet()) + for (SubsystemMainClass subsystem : subsystems.keySet()) resolver.addVector(subsystems.get(subsystem)); - /* + logger.diag("Resolving dependencies"); 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(); + logger.info("Initializing engine subsystems"); + for (SubsystemMainClass subsystem : subsystems.keySet()) { + logger.verb("Initializing subsystem " + subsystem.getClass().getName()); + subsystem.initializeSubsystem(); + } } /** @@ -335,6 +346,10 @@ public final class Engine implements SubsystemMainClass { Runtime.getRuntime().exit(exitCode); } + /** {@inheritDoc} */ + @Override + public void initializeSubsystem() {} + /** * Returns the {@link DependencyVector} for this subsystem. * diff --git a/base/src/main/java/de/staropensource/sosengine/base/classes/SubsystemMainClass.java b/base/src/main/java/de/staropensource/sosengine/base/classes/SubsystemMainClass.java index ba0272e..7db8013 100644 --- a/base/src/main/java/de/staropensource/sosengine/base/classes/SubsystemMainClass.java +++ b/base/src/main/java/de/staropensource/sosengine/base/classes/SubsystemMainClass.java @@ -40,6 +40,13 @@ public interface SubsystemMainClass { */ LoggerInstance logger = null; + /** + * Initializes this subsystem. + * + * @since 1-alpha1 + */ + void initializeSubsystem(); + /** * Returns the {@link DependencyVector} for this subsystem. * diff --git a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java index 0084d3b..8217f3d 100644 --- a/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java +++ b/graphics/opengl/src/main/java/de/staropensource/sosengine/graphics/opengl/OpenGlSubsystem.java @@ -95,7 +95,11 @@ public final class OpenGlSubsystem implements ApiMainClass { else { instance.logger.crash("The subsystem tried to initialize twice"); } + } + /** {@inheritDoc} */ + @Override + public void initializeSubsystem() { long initTime = Miscellaneous.measureExecutionTime(() -> { // Precompute event listeners EventHelper.precomputeEventListeners(GraphicsErrorEvent.class); @@ -104,7 +108,7 @@ public final class OpenGlSubsystem implements ApiMainClass { GraphicsSubsystem.getInstance().registerGraphicsApi(this); }); - logger.info("Initialized subsystem in " + initTime + "ms"); + logger.verb("Initialized subsystem in " + initTime + "ms"); } /** {@inheritDoc} */ diff --git a/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java index fc39684..374fd8b 100644 --- a/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java +++ b/graphics/src/main/java/de/staropensource/sosengine/graphics/GraphicsSubsystem.java @@ -120,9 +120,11 @@ public final class GraphicsSubsystem implements SubsystemMainClass { instance.logger.crash("Graphics subsystem tried to initialize twice"); return; } + } - logger.verb("Initializing subsystem"); - + /** {@inheritDoc} */ + @Override + public void initializeSubsystem() { long initTime = Miscellaneous.measureExecutionTime(() -> { // Initialize GraphicsSubsystemConfiguration and load it new GraphicsSubsystemConfiguration(); @@ -132,7 +134,7 @@ public final class GraphicsSubsystem implements SubsystemMainClass { precomputeEventListeners(); }); - logger.info("Initialized subsystem in " + initTime + "ms"); + logger.verb("Initialized subsystem in " + initTime + "ms"); } /** diff --git a/graphics/vulkan/src/main/java/de/staropensource/sosengine/graphics/vulkan/VulkanSubsystem.java b/graphics/vulkan/src/main/java/de/staropensource/sosengine/graphics/vulkan/VulkanSubsystem.java index acaba87..888707d 100644 --- a/graphics/vulkan/src/main/java/de/staropensource/sosengine/graphics/vulkan/VulkanSubsystem.java +++ b/graphics/vulkan/src/main/java/de/staropensource/sosengine/graphics/vulkan/VulkanSubsystem.java @@ -93,7 +93,11 @@ public final class VulkanSubsystem implements ApiMainClass { instance.logger.crash("The subsystem tried to initialize twice"); return; } + } + /** {@inheritDoc} */ + @Override + public void initializeSubsystem() { long initTime = Miscellaneous.measureExecutionTime(() -> { // Warn about instability logger.warn("The Vulkan Graphics API is in an unfinished state. Trying to initialize the Graphics API will cause an engine crash."); @@ -102,7 +106,7 @@ public final class VulkanSubsystem implements ApiMainClass { GraphicsSubsystem.getInstance().registerGraphicsApi(this); }); - logger.info("Initialized subsystem in " + initTime + "ms"); + logger.verb("Initialized subsystem in " + initTime + "ms"); } /** {@inheritDoc} */ diff --git a/slf4j-compat/src/main/java/de/staropensource/sosengine/slf4j_compat/Slf4jCompatibilitySubsystem.java b/slf4j-compat/src/main/java/de/staropensource/sosengine/slf4j_compat/Slf4jCompatibilitySubsystem.java index 1e78b71..54429bf 100644 --- a/slf4j-compat/src/main/java/de/staropensource/sosengine/slf4j_compat/Slf4jCompatibilitySubsystem.java +++ b/slf4j-compat/src/main/java/de/staropensource/sosengine/slf4j_compat/Slf4jCompatibilitySubsystem.java @@ -28,6 +28,7 @@ import de.staropensource.sosengine.base.events.LogEvent; 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.utility.Miscellaneous; import lombok.Getter; import org.slf4j.LoggerFactory; @@ -66,11 +67,15 @@ public class Slf4jCompatibilitySubsystem implements SubsystemMainClass { instance = this; else { instance.logger.crash("The subsystem tried to initialize twice"); - return; } + } - LoggerFactory.getLogger(CompatibilityLogger.class).debug("If you see this then the SLF4J Compatibility Subsystem is working!"); - logger.info("Initialized subsystem"); + /** {@inheritDoc} */ + @Override + public void initializeSubsystem() { + logger.verb("Initialized subsystem in " + + Miscellaneous.measureExecutionTime(() -> LoggerFactory.getLogger(CompatibilityLogger.class).debug("If you see this then the SLF4J Compatibility Subsystem is working!")) + + "ms"); } /** {@inheritDoc} */