forked from StarOpenSource/Engine
Fix & complete automatic subsystem initialization
This commit is contained in:
parent
3e167ac260
commit
ecf0f94784
6 changed files with 65 additions and 28 deletions
|
@ -47,10 +47,7 @@ import org.reflections.scanners.Scanners;
|
||||||
import org.reflections.util.ClasspathHelper;
|
import org.reflections.util.ClasspathHelper;
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
import org.reflections.util.ConfigurationBuilder;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sos!engine management object.<br/>
|
* sos!engine management object.<br/>
|
||||||
|
@ -98,7 +95,7 @@ public final class Engine implements SubsystemMainClass {
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
@Getter
|
@Getter
|
||||||
private ImmutableMap<@NotNull Class<? extends SubsystemMainClass>, @NotNull DependencyVector> subsystems = new ImmutableMap<>();
|
private ImmutableMap<@NotNull SubsystemMainClass, @NotNull DependencyVector> subsystems = new ImmutableMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the engine is shutting down.
|
* Indicates if the engine is shutting down.
|
||||||
|
@ -115,7 +112,7 @@ public final class Engine implements SubsystemMainClass {
|
||||||
private boolean shuttingDown = false;
|
private boolean shuttingDown = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor, initializes the StarOpenSource Engine.
|
* Initializes the StarOpenSource Engine.
|
||||||
*
|
*
|
||||||
* @since 1-alpha0
|
* @since 1-alpha0
|
||||||
*/
|
*/
|
||||||
|
@ -153,7 +150,7 @@ public final class Engine implements SubsystemMainClass {
|
||||||
try {
|
try {
|
||||||
initializeSubsystems();
|
initializeSubsystems();
|
||||||
} catch (Exception exception) {
|
} 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
|
* @since 1-alpha1
|
||||||
*/
|
*/
|
||||||
private void collectSubsystems() {
|
private void collectSubsystems() {
|
||||||
Map<@NotNull Class<? extends SubsystemMainClass>, @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(
|
Reflections reflections = new Reflections(
|
||||||
new ConfigurationBuilder()
|
new ConfigurationBuilder()
|
||||||
.setUrls(ClasspathHelper.forJavaClassPath())
|
.setUrls(ClasspathHelper.forJavaClassPath())
|
||||||
|
@ -264,16 +261,27 @@ 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);
|
||||||
|
|
||||||
// Add to 'subsystemsMap'
|
// Initialize class, get dependency vector and add to 'subsystemsMap'
|
||||||
for (Class<?> clazz : annotatedClasses) {
|
for (Class<?> clazz : annotatedClasses) {
|
||||||
try {
|
try {
|
||||||
//noinspection unchecked
|
// Create new instance
|
||||||
subsystemsMap.put((Class<? extends SubsystemMainClass>) clazz, (DependencyVector) clazz.getMethod("getDependencyVector").invoke(null));
|
Object initializedClassRaw = clazz.getDeclaredConstructor().newInstance();
|
||||||
} catch (Exception ignored) {}
|
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
|
// Remove entries with null values
|
||||||
for (Class<? extends SubsystemMainClass> subsystem : subsystemsMap.keySet())
|
for (SubsystemMainClass subsystem : subsystemsMap.keySet())
|
||||||
if (subsystemsMap.get(subsystem) == null)
|
if (subsystemsMap.get(subsystem) == null)
|
||||||
subsystemsMap.remove(subsystem);
|
subsystemsMap.remove(subsystem);
|
||||||
|
|
||||||
|
@ -287,22 +295,25 @@ 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();
|
||||||
|
|
||||||
for (Class<? extends SubsystemMainClass> subsystem : subsystems.keySet())
|
for (SubsystemMainClass subsystem : subsystems.keySet())
|
||||||
resolver.addVector(subsystems.get(subsystem));
|
resolver.addVector(subsystems.get(subsystem));
|
||||||
|
|
||||||
/*
|
logger.diag("Resolving dependencies");
|
||||||
try {
|
try {
|
||||||
resolver.resolve();
|
resolver.resolve();
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
logger.crash("An error occurred trying to initialize engine subsystems: " + exception.getClass().getName() + (exception.getMessage() == null ? "" : ": " + exception.getMessage()));
|
logger.crash("An error occurred trying to initialize engine subsystems: " + exception.getClass().getName() + (exception.getMessage() == null ? "" : ": " + exception.getMessage()));
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
for (Class<? extends SubsystemMainClass> subsystem : subsystems.keySet())
|
logger.info("Initializing engine subsystems");
|
||||||
subsystem.getDeclaredConstructor().newInstance();
|
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);
|
Runtime.getRuntime().exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void initializeSubsystem() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link DependencyVector} for this subsystem.
|
* Returns the {@link DependencyVector} for this subsystem.
|
||||||
*
|
*
|
||||||
|
|
|
@ -40,6 +40,13 @@ public interface SubsystemMainClass {
|
||||||
*/
|
*/
|
||||||
LoggerInstance logger = null;
|
LoggerInstance logger = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this subsystem.
|
||||||
|
*
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
void initializeSubsystem();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link DependencyVector} for this subsystem.
|
* Returns the {@link DependencyVector} for this subsystem.
|
||||||
*
|
*
|
||||||
|
|
|
@ -95,7 +95,11 @@ public final class OpenGlSubsystem implements ApiMainClass {
|
||||||
else {
|
else {
|
||||||
instance.logger.crash("The subsystem tried to initialize twice");
|
instance.logger.crash("The subsystem tried to initialize twice");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void initializeSubsystem() {
|
||||||
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
||||||
// Precompute event listeners
|
// Precompute event listeners
|
||||||
EventHelper.precomputeEventListeners(GraphicsErrorEvent.class);
|
EventHelper.precomputeEventListeners(GraphicsErrorEvent.class);
|
||||||
|
@ -104,7 +108,7 @@ public final class OpenGlSubsystem implements ApiMainClass {
|
||||||
GraphicsSubsystem.getInstance().registerGraphicsApi(this);
|
GraphicsSubsystem.getInstance().registerGraphicsApi(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info("Initialized subsystem in " + initTime + "ms");
|
logger.verb("Initialized subsystem in " + initTime + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|
|
@ -120,9 +120,11 @@ public final class GraphicsSubsystem implements SubsystemMainClass {
|
||||||
instance.logger.crash("Graphics subsystem tried to initialize twice");
|
instance.logger.crash("Graphics subsystem tried to initialize twice");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.verb("Initializing subsystem");
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void initializeSubsystem() {
|
||||||
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
||||||
// Initialize GraphicsSubsystemConfiguration and load it
|
// Initialize GraphicsSubsystemConfiguration and load it
|
||||||
new GraphicsSubsystemConfiguration();
|
new GraphicsSubsystemConfiguration();
|
||||||
|
@ -132,7 +134,7 @@ public final class GraphicsSubsystem implements SubsystemMainClass {
|
||||||
precomputeEventListeners();
|
precomputeEventListeners();
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info("Initialized subsystem in " + initTime + "ms");
|
logger.verb("Initialized subsystem in " + initTime + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -93,7 +93,11 @@ public final class VulkanSubsystem implements ApiMainClass {
|
||||||
instance.logger.crash("The subsystem tried to initialize twice");
|
instance.logger.crash("The subsystem tried to initialize twice");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void initializeSubsystem() {
|
||||||
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
||||||
// Warn about instability
|
// 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.");
|
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);
|
GraphicsSubsystem.getInstance().registerGraphicsApi(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info("Initialized subsystem in " + initTime + "ms");
|
logger.verb("Initialized subsystem in " + initTime + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|
|
@ -28,6 +28,7 @@ import de.staropensource.sosengine.base.events.LogEvent;
|
||||||
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.DependencyVector;
|
import de.staropensource.sosengine.base.types.DependencyVector;
|
||||||
|
import de.staropensource.sosengine.base.utility.Miscellaneous;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -66,11 +67,15 @@ public class Slf4jCompatibilitySubsystem implements SubsystemMainClass {
|
||||||
instance = this;
|
instance = this;
|
||||||
else {
|
else {
|
||||||
instance.logger.crash("The subsystem tried to initialize twice");
|
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!");
|
/** {@inheritDoc} */
|
||||||
logger.info("Initialized subsystem");
|
@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} */
|
/** {@inheritDoc} */
|
||||||
|
|
Loading…
Reference in a new issue