Update subsystem initialization logic

This commit is contained in:
JeremyStar™ 2024-07-08 14:29:02 +02:00
parent ba2e6ebecd
commit 867304b568
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D

View file

@ -33,8 +33,9 @@ import de.staropensource.sosengine.base.logging.CrashHandler;
import de.staropensource.sosengine.base.logging.Logger; import de.staropensource.sosengine.base.logging.Logger;
import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.CodePart; 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.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.DependencyResolver;
import de.staropensource.sosengine.base.utility.Miscellaneous; import de.staropensource.sosengine.base.utility.Miscellaneous;
import de.staropensource.sosengine.base.utility.PlaceholderEngine; import de.staropensource.sosengine.base.utility.PlaceholderEngine;
@ -84,17 +85,19 @@ public final class Engine implements SubsystemMainClass {
/** /**
* Contains a list of all registered subsystems. * Contains a list of all registered subsystems.
* The list is sorted after initialization order.
* *
* @since 1-alpha1 * @since 1-alpha1
* *
* -- GETTER -- * -- GETTER --
* Returns a list of all registered subsystems. * Returns a list of all registered subsystems.
* The list is sorted after initialization order.
* *
* @since 1-alpha1 * @since 1-alpha1
*/ */
@NotNull @NotNull
@Getter @Getter
private ImmutableHashMap<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystems = new ImmutableHashMap<>(); private ImmutableLinkedList<@NotNull DependencySubsystemVector> subsystems = new ImmutableLinkedList<>();
/** /**
* Indicates if the engine is shutting down. * Indicates if the engine is shutting down.
@ -246,7 +249,7 @@ public final class Engine implements SubsystemMainClass {
* @since 1-alpha1 * @since 1-alpha1
*/ */
private void collectSubsystems() { private void collectSubsystems() {
Map<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystemsMap = new HashMap<>(); ArrayList<@NotNull DependencySubsystemVector> subsystemsMutable = new ArrayList<>();
// Scan entire classpath using the Reflections library // Scan entire classpath using the Reflections library
Reflections reflections = new Reflections( Reflections reflections = new Reflections(
@ -258,7 +261,7 @@ public final class Engine implements SubsystemMainClass {
// Get annotated methods // Get annotated methods
Set<@NotNull Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(EngineSubsystem.class); 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) { for (Class<?> clazz : annotatedClasses) {
try { try {
// Create new instance // Create new instance
@ -271,18 +274,15 @@ public final class Engine implements SubsystemMainClass {
else else
logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Does not implement " + SubsystemMainClass.class.getName()); 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) { } catch (Exception exception) {
logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Method invocation error", exception); logger.crash("Failed to initialize subsystem " + clazz.getName() + ": Method invocation error", exception);
} }
} }
// Remove entries with null values // Update 'subsystems'
for (SubsystemMainClass subsystem : subsystemsMap.keySet()) subsystems = new ImmutableLinkedList<>(subsystemsMutable);
if (subsystemsMap.get(subsystem) == null)
subsystemsMap.remove(subsystem);
subsystems = new ImmutableHashMap<>(subsystemsMap);
} }
/** /**
@ -292,27 +292,38 @@ public final class Engine implements SubsystemMainClass {
* @since 1-alpha1 * @since 1-alpha1
*/ */
private void initializeSubsystems() throws Exception { private void initializeSubsystems() throws Exception {
logger.verb("Preparing subsystem initialization");
DependencyResolver resolver = new DependencyResolver(); DependencyResolver resolver = new DependencyResolver();
LinkedList<DependencySubsystemVector> order = new LinkedList<>();
for (SubsystemMainClass subsystem : subsystems.keySet()) // Add vectors
resolver.addVector(subsystems.get(subsystem)); resolver.addVectors(subsystems);
logger.diag("Resolving dependencies"); // Resolve dependencies and get order
logger.verb("Resolving subsystem dependencies");
try { try {
resolver.resolve(); for (DependencyVector vector : resolver.resolve().getOrder()) // smol workaround
} catch (Exception exception) { order.add((DependencySubsystemVector) vector);
logger.crash("An error occurred trying to initialize engine subsystems: " + exception.getClass().getName() + (exception.getMessage() == null ? "" : ": " + exception.getMessage())); } catch (Throwable throwable) {
throw exception; 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"); logger.info("Initializing engine subsystems");
for (SubsystemMainClass subsystem : subsystems.keySet()) { for (DependencySubsystemVector vector : subsystems) {
logger.verb("Initializing subsystem " + subsystem.getClass().getName()); logger.verb("Initializing subsystem " + vector.getMainClass().getClass().getName());
subsystem.initializeSubsystem(); 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);
}
/** /**
* Starts engine threads. * Starts engine threads.
* *