Add Engine.reload method and SHUT_DOWN_FINAL state

This commit is contained in:
JeremyStar™ 2024-12-20 01:37:03 +01:00
parent c1a14d343c
commit 04f8aa360a
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D

View file

@ -20,9 +20,9 @@
package de.staropensource.engine.base package de.staropensource.engine.base
import de.staropensource.engine.base.exception.EngineInitializationFailureException import de.staropensource.engine.base.exception.EngineInitializationFailureException
import de.staropensource.engine.base.logging.Logger
import de.staropensource.engine.base.utility.Environment import de.staropensource.engine.base.utility.Environment
import de.staropensource.engine.base.utility.FileAccess import de.staropensource.engine.base.utility.FileAccess
import de.staropensource.engine.base.logging.Logger
import de.staropensource.engine.base.utility.dnihbd.BuildInformation import de.staropensource.engine.base.utility.dnihbd.BuildInformation
/** /**
@ -45,7 +45,7 @@ class Engine private constructor() {
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
internal val logger: Logger = Logger("engine-core") internal val logger: Logger = Logger(channel = "engine-core")
/** /**
* Contains the state the engine is in. * Contains the state the engine is in.
@ -81,7 +81,7 @@ class Engine private constructor() {
var info: BuildInformation? = null var info: BuildInformation? = null
// -----> Initialization // -----> Lifecycle
/** /**
* Bootstraps the engine. * Bootstraps the engine.
* *
@ -96,6 +96,7 @@ class Engine private constructor() {
@JvmStatic @JvmStatic
@Throws(Throwable::class) @Throws(Throwable::class)
private fun bootstrap(): Boolean { private fun bootstrap(): Boolean {
// Check for state
if (state != State.UNINITIALIZED || bootstrapping != null) if (state != State.UNINITIALIZED || bootstrapping != null)
return true return true
@ -104,6 +105,7 @@ class Engine private constructor() {
logger.info("Bootstrapping") logger.info("Bootstrapping")
// Run bootstrapping code // Run bootstrapping code
// *none yet*
bootstrapping = false bootstrapping = false
return true return true
@ -126,19 +128,19 @@ class Engine private constructor() {
@JvmStatic @JvmStatic
@Throws(EngineInitializationFailureException::class) @Throws(EngineInitializationFailureException::class)
fun initialize() { fun initialize() {
// Abort if initializing, shutting down // Check state
// or the engine has crashed if (bootstrapping == true)
if ( return
bootstrapping == true when (state) {
|| state == State.INITIALIZING State.INITIALIZING, State.SHUTTING_DOWN, State.SHUT_DOWN_FINAL, State.CRASHED -> return
|| state == State.SHUTTING_DOWN else -> {}
|| state == State.CRASHED }
) return
// Bootstrap if not already done so // Bootstrap if not already done so
if (!bootstrap()) if (!bootstrap())
return return
// Initialize
try { try {
state = State.INITIALIZING state = State.INITIALIZING
logger.info("Initializing") logger.info("Initializing")
@ -155,6 +157,40 @@ class Engine private constructor() {
} }
} }
/**
* Reloads the engine.
*
* The request is ignored if
* the engine isn't running.
*
* @since v1-alpha10
*/
@JvmStatic
fun reload() {
// Check for state
if (state != State.INITIALIZED)
return
logger.info("Reloading")
// Run reload code
// *none yet*
// Reload subsystems
logger.verb("Reloading subsystems")
for (subsystem: Subsystem in subsystems)
try {
logger.diag("Reloading subsystem '${subsystem.getName()}' [${subsystem::class.qualifiedName ?: "<anonymous>"}]")
subsystem.reload()
} catch (throwable: Throwable) {
logger.crash(
"Failed to reload subsystem '${subsystem.getName()}' [${subsystem::class.qualifiedName ?: "<anonymous>"}]",
throwable = throwable,
fatal = true
)
}
}
/** /**
* Shuts the engine down. * Shuts the engine down.
* *
@ -165,14 +201,14 @@ class Engine private constructor() {
*/ */
@JvmStatic @JvmStatic
fun shutdown() { fun shutdown() {
// Abort if not initialized // Check for state
if (state != State.INITIALIZED) if (state != State.INITIALIZED)
return return
logger.info("Shutting down") logger.info("Shutting down")
// Perform shutdown // Perform shutdown
performShutdown() performShutdown(false)
state = State.SHUT_DOWN state = State.SHUT_DOWN
} }
@ -187,17 +223,17 @@ class Engine private constructor() {
*/ */
@JvmStatic @JvmStatic
fun shutdownFinal(exitcode: UByte = 0u) { fun shutdownFinal(exitcode: UByte = 0u) {
// Abort if not initialized // Check for state
if (state != State.INITIALIZED) if (state != State.INITIALIZED)
return return
logger.info("Shutting down for good") logger.info("Shutting down for good")
// Perform shutdown // Perform shutdown
performShutdown() performShutdown(true)
state = State.SHUT_DOWN state = State.SHUT_DOWN_FINAL
// Quit application // Initiate application shutdown
EngineConfiguration.shutdownHandler.exit(exitcode) EngineConfiguration.shutdownHandler.exit(exitcode)
} }
@ -209,10 +245,16 @@ class Engine private constructor() {
*/ */
@JvmStatic @JvmStatic
internal fun shutdownAfterCrash() { internal fun shutdownAfterCrash() {
// Check for state
when (state) {
State.UNINITIALIZED, State.SHUTTING_DOWN, State.SHUT_DOWN, State.CRASHED -> return
else -> {}
}
logger.info("Shutting down after having crashed fatally") logger.info("Shutting down after having crashed fatally")
// Perform shutdown // Perform shutdown
performShutdown(crashed = true) performShutdown(true, crashed = true)
state = State.CRASHED state = State.CRASHED
// Quit application // Quit application
@ -225,11 +267,12 @@ class Engine private constructor() {
* This performs the actual shutdown, * This performs the actual shutdown,
* just without the bloat. * just without the bloat.
* *
* @param final whether this is the last time the engine shuts down. Doesn't actually shut the application down, just changes some messages and does other things
* @param crashed enables super careful mode to prevent further breakage * @param crashed enables super careful mode to prevent further breakage
* @since v1-alpha10 * @since v1-alpha10
*/ */
@JvmStatic @JvmStatic
private fun performShutdown(crashed: Boolean = false) { private fun performShutdown(final: Boolean, crashed: Boolean = false) {
state = State.SHUTTING_DOWN state = State.SHUTTING_DOWN
// Run shutdown code // Run shutdown code
@ -267,40 +310,64 @@ class Engine private constructor() {
INITIALIZING, INITIALIZING,
/** /**
* Specifies that the engine has fully * Specifies that the engine
* initialized and can be safely used. * has fully initialized and
* can be safely used.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
INITIALIZED, INITIALIZED,
/** /**
* Indicates that the engine is in * Indicates that the engine
* the process of shutting down. * is in the process of
* shutting itself down.
* *
* Many methods are considered * Many methods are considered
* unsafe and should not be called. * unsafe and should not be called.
*
* @since v1-alpha10
*/ */
SHUTTING_DOWN, SHUTTING_DOWN,
/** /**
* Indicates that the engine has been shut down. * Indicates that the engine has
* been shut down.
* *
* This may not be a final state. * Many methods are considered
* unsafe and should not be called.
*
* This is not a final state. The
* engine may be initialized again.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
SHUT_DOWN, SHUT_DOWN,
/** /**
* Indicates that the engine has crashed and * Indicates that the engine
* is in a state where further usage is * has been shut down for good.
* HIGHLY discouraged. Any further calls may
* cause the process or virtual machine to
* exit with a fatal error.
* *
* This is a final state. The engine cannot * This is a final state. The
* be initialized again after having crashed. * engine cannot be initialized
* again after having shut down
* final.
*
* @since v1-alpha10
*/
SHUT_DOWN_FINAL,
/**
* Indicates that the engine has
* crashed and is in a state
* where further usage is HIGHLY
* discouraged. Any further calls
* may cause the process or
* virtual machine to exit fatally.
*
* This is a final state. The
* engine cannot be initialized
* again after having crashed.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */