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 2a9af667..b841253c 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/Engine.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/Engine.java
@@ -26,6 +26,7 @@ import de.staropensource.sosengine.base.classes.helpers.EventHelper;
import de.staropensource.sosengine.base.data.information.EngineInformation;
import de.staropensource.sosengine.base.data.versioning.StarOpenSourceVersioningSystem;
import de.staropensource.sosengine.base.events.*;
+import de.staropensource.sosengine.base.exceptions.NoAccessException;
import de.staropensource.sosengine.base.exceptions.dependency.UnmetDependenciesException;
import de.staropensource.sosengine.base.internal.events.InternalEngineShutdownEvent;
import de.staropensource.sosengine.base.internal.types.DependencySubsystemVector;
@@ -33,6 +34,7 @@ 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.DependencyVector;
+import de.staropensource.sosengine.base.types.EngineState;
import de.staropensource.sosengine.base.types.immutable.ImmutableLinkedList;
import de.staropensource.sosengine.base.utility.DependencyResolver;
import de.staropensource.sosengine.base.utility.Miscellaneous;
@@ -92,17 +94,17 @@ public final class Engine extends SubsystemClass {
private static LoggerInstance logger;
/**
- * Contains if the engine is shutting down.
+ * Contains the engine state.
*
- * @since v1-alpha1
+ * @since v1-alpha2
* -- GETTER --
- * Returns if the engine is shutting down.
+ * Returns the engine state.
*
- * @return shutdown status
- * @since v1-alpha1
+ * @return shutdown state
+ * @since v1-alpha2
*/
@Getter
- private boolean shuttingDown = false;
+ private @NotNull EngineState state = EngineState.UNKNOWN;
/**
* Contains the engine's shutdown handler.
@@ -160,6 +162,8 @@ public final class Engine extends SubsystemClass {
return;
long initTime = Miscellaneous.measureExecutionTime(() -> {
+ state = EngineState.STARTUP;
+
// Initialize engine configuration
new EngineConfiguration();
EngineConfiguration.getInstance().loadConfiguration();
@@ -185,6 +189,7 @@ public final class Engine extends SubsystemClass {
}
});
+ state = EngineState.RUNNING;
logger.info("Initialized sos!engine %engine_version% (commit %engine_git_commit_id_long%-%engine_git_branch%, dirty %engine_git_dirty%) in " + initTime + "ms");
}
@@ -389,10 +394,9 @@ public final class Engine extends SubsystemClass {
* @since v1-alpha0
*/
public synchronized void shutdown(@Range(from = 0, to = 255) int exitCode) {
- if (shuttingDown) {
- logger.error("Already shutting down");
- return;
- }
+ logger.info("Shutting engine down");
+ if (state != EngineState.CRASHED)
+ state = EngineState.SHUTDOWN;
// Make engine single-threaded
Properties properties = new Properties();
@@ -403,16 +407,13 @@ public final class Engine extends SubsystemClass {
// Flush log messages
Logger.flushLogMessages();
- logger.info("Shutting engine down");
- shuttingDown = true;
-
logger.verb("Notifiying classes about shutdown");
new EngineShutdownEvent().callEvent();
logger.verb("Notifying subsystems about shutdown");
new InternalEngineShutdownEvent().callEvent();
- logger.verb("Shutting down JVM with code " + exitCode);
+ logger.verb("Invoking shutdown handler (code " + exitCode + ")");
shutdownHandler.shutdown((short) exitCode);
}
@@ -442,6 +443,20 @@ public final class Engine extends SubsystemClass {
return new DependencyVector("engine", StarOpenSourceVersioningSystem.class, EngineInformation.getVersioningString());
}
+ /**
+ * Sets the engine state.
+ *
+ * @param state new state
+ * @throws NoAccessException if the caller class is unauthorized
+ * @since v1-alpha2
+ */
+ public void setState(@NotNull EngineState state) throws NoAccessException {
+ if (!Thread.currentThread().getStackTrace()[2].getClassName().startsWith("de.staropensource.sosengine.base."))
+ throw new NoAccessException("Only classes inside the \"de.staropensource.sosengine.base\" package are allowed to call this method.");
+
+ this.state = state;
+ }
+
/**
* The default shutdown handler, which causes the JVM to exit.
*
@@ -460,6 +475,8 @@ public final class Engine extends SubsystemClass {
/** {@inheritDoc} */
@Override
public void shutdown(short exitCode) {
+ logger.warn("Terminating JVM");
+
System.exit(exitCode);
}
}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/exceptions/NoAccessException.java b/base/src/main/java/de/staropensource/sosengine/base/exceptions/NoAccessException.java
new file mode 100644
index 00000000..8af0b8be
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/exceptions/NoAccessException.java
@@ -0,0 +1,50 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * Not to be confused with {@link de.staropensource.sosengine.base.exceptions.reflection.NoAccessException},
+ * which handles access violations of reflection objects.
+ *
+ * @since v1-alpha2
+ */
+@SuppressWarnings({ "unused" })
+public class NoAccessException extends RuntimeException {
+ /**
+ * Constructs this exception.
+ *
+ * @since v1-alpha2
+ */
+ public NoAccessException() {}
+
+ /**
+ * Constructs this exception.
+ *
+ * @param message message
+ * @since v1-alpha2
+ */
+ public NoAccessException(@NotNull String message) {
+ super(message);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/logging/CrashHandler.java b/base/src/main/java/de/staropensource/sosengine/base/logging/CrashHandler.java
index 99d3e5d3..49a12721 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/logging/CrashHandler.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/logging/CrashHandler.java
@@ -45,7 +45,6 @@ import java.util.List;
*/
@SuppressWarnings({ "unused", "JavadocDeclaration" })
public final class CrashHandler {
-
/**
* Contains the template used to print a crash report.
*
@@ -117,6 +116,8 @@ Dear developer: FIX YOUR GODDAMN SHIT! Please check if your code or 3rd party su
* @since v1-alpha0
*/
public static synchronized void handleCrash(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @Nullable Throwable throwable, boolean throwableHandled) {
+ Engine.getInstance().setState(EngineState.CRASHED);
+
if (throwable == null)
throwableHandled = false;
diff --git a/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java b/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java
new file mode 100644
index 00000000..0af32cd7
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java
@@ -0,0 +1,68 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see