From 867304b568c1f10e34f93927f6f6708cfedbefbc Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Mon, 8 Jul 2024 14:29:02 +0200 Subject: [PATCH] Update subsystem initialization logic --- .../staropensource/sosengine/base/Engine.java | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 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 d60bdbc..d2c64f2 100644 --- a/base/src/main/java/de/staropensource/sosengine/base/Engine.java +++ b/base/src/main/java/de/staropensource/sosengine/base/Engine.java @@ -33,8 +33,9 @@ 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.dependency.DependencySubsystemVector; import de.staropensource.sosengine.base.types.dependency.DependencyVector; -import de.staropensource.sosengine.base.types.immutable.ImmutableHashMap; +import de.staropensource.sosengine.base.types.immutable.ImmutableLinkedList; import de.staropensource.sosengine.base.utility.DependencyResolver; import de.staropensource.sosengine.base.utility.Miscellaneous; import de.staropensource.sosengine.base.utility.PlaceholderEngine; @@ -84,17 +85,19 @@ public final class Engine implements SubsystemMainClass { /** * Contains a list of all registered subsystems. + * The list is sorted after initialization order. * * @since 1-alpha1 * * -- GETTER -- * Returns a list of all registered subsystems. + * The list is sorted after initialization order. * * @since 1-alpha1 */ @NotNull @Getter - private ImmutableHashMap<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystems = new ImmutableHashMap<>(); + private ImmutableLinkedList<@NotNull DependencySubsystemVector> subsystems = new ImmutableLinkedList<>(); /** * Indicates if the engine is shutting down. @@ -246,7 +249,7 @@ public final class Engine implements SubsystemMainClass { * @since 1-alpha1 */ private void collectSubsystems() { - Map<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystemsMap = new HashMap<>(); + ArrayList<@NotNull DependencySubsystemVector> subsystemsMutable = new ArrayList<>(); // Scan entire classpath using the Reflections library Reflections reflections = new Reflections( @@ -258,7 +261,7 @@ public final class Engine implements SubsystemMainClass { // Get annotated methods Set<@NotNull Class> annotatedClasses = reflections.getTypesAnnotatedWith(EngineSubsystem.class); - // Initialize class, get dependency vector and add to 'subsystemsMap' + // Initialize classes, get dependency vector and add to 'subsystemsMutable' for (Class clazz : annotatedClasses) { try { // Create new instance @@ -271,18 +274,15 @@ public final class Engine implements SubsystemMainClass { else logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Does not implement " + SubsystemMainClass.class.getName()); - subsystemsMap.put(Objects.requireNonNull(initializedClass), initializedClass.getDependencyVector()); + //noinspection DataFlowIssue // the crash call will prevent a NullPointerException + subsystemsMutable.add(new DependencySubsystemVector(initializedClass.getDependencyVector(), initializedClass)); } catch (Exception exception) { logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Method invocation error", exception); } } - // Remove entries with null values - for (SubsystemMainClass subsystem : subsystemsMap.keySet()) - if (subsystemsMap.get(subsystem) == null) - subsystemsMap.remove(subsystem); - - subsystems = new ImmutableHashMap<>(subsystemsMap); + // Update 'subsystems' + subsystems = new ImmutableLinkedList<>(subsystemsMutable); } /** @@ -292,25 +292,36 @@ public final class Engine implements SubsystemMainClass { * @since 1-alpha1 */ private void initializeSubsystems() throws Exception { - logger.verb("Preparing subsystem initialization"); DependencyResolver resolver = new DependencyResolver(); + LinkedList order = new LinkedList<>(); - for (SubsystemMainClass subsystem : subsystems.keySet()) - resolver.addVector(subsystems.get(subsystem)); + // Add vectors + resolver.addVectors(subsystems); - logger.diag("Resolving dependencies"); + // Resolve dependencies and get order + logger.verb("Resolving subsystem 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 (DependencyVector vector : resolver.resolve().getOrder()) // smol workaround + order.add((DependencySubsystemVector) vector); + } catch (Throwable throwable) { + logger.crash("An error occurred trying to resolve subsystem dependencies: " + throwable.getClass().getName() + (throwable.getMessage() == null ? "" : ": " + throwable.getMessage())); + throw throwable; } + // Initialize subsystems logger.info("Initializing engine subsystems"); - for (SubsystemMainClass subsystem : subsystems.keySet()) { - logger.verb("Initializing subsystem " + subsystem.getClass().getName()); - subsystem.initializeSubsystem(); + for (DependencySubsystemVector vector : subsystems) { + logger.verb("Initializing subsystem " + vector.getMainClass().getClass().getName()); + try { + vector.getMainClass().initializeSubsystem(); + } catch (Throwable throwable) { + logger.crash("An error occurred trying to initialize subsystem " + vector.getMainClass().getClass().getName() + ": " + throwable.getClass().getName() + (throwable.getMessage() == null ? "" : ": " + throwable.getMessage())); + throw throwable; + } } + + // Update 'subsystems' + subsystems = new ImmutableLinkedList<>(order); } /**