JeremyStarTM
99703cf03e
Reviewed-on: StarOpenSource/core#1 Rewrote CORE and improved the startup process and startup time significantly. The documentation has been beefed up too and is now much better. Existing projects may need major refactoring however. Co-authored-by: JeremyStarTM <jeremystartm@staropensource.de> Co-committed-by: JeremyStarTM <jeremystartm@staropensource.de>
231 lines
10 KiB
GDScript
231 lines
10 KiB
GDScript
######################################
|
|
# THE CORE FRAMEWORK #
|
|
# MADE BY THE STAROPENSOURCE PROJECT #
|
|
# AND CONTRIBUTERS (THANK YOU!) #
|
|
# #
|
|
# COPYRIGHT 2023 THE STAROPENSOURCE #
|
|
# PROJECT AND CONTRIBUTERS #
|
|
# #
|
|
# LICENSED UNDER THE GNU GENERAL #
|
|
# PUBLIC LICENSE VERSION 3 (ONLY) #
|
|
######################################
|
|
extends Node
|
|
|
|
# CORE modules
|
|
var logger: Node = null
|
|
var preprocessor: Node = null
|
|
var config: Node = null
|
|
|
|
# Version
|
|
const version: Dictionary = {"type":"source","releasebuild":0,"full":"source 0"}
|
|
# Protection mode
|
|
var protection_mode: bool = false
|
|
# Development mode
|
|
var development_mode: bool = false
|
|
# Loadpath (from coreinit.gd)
|
|
var loadpath: String = ""
|
|
|
|
# Errors
|
|
enum Errors {
|
|
OK,
|
|
CORE_PROTECTIONMODE,
|
|
CORE_EXCEPTION,
|
|
CORE_INVALID_MODULE,
|
|
RESOURCEMANAGER_ALREADY_EXISTS,
|
|
RESOURCEMANAGER_INVALID_FILEPATH,
|
|
RESOURCEMANAGER_RESOURCE_MISSING,
|
|
RESOURCEMANAGER_BATCH_EMPTY,
|
|
SCENEMANAGER_ALREADY_LOADED,
|
|
SCENEMANAGER_NOT_LOADED,
|
|
SCENEMANAGER_NOT_PACKEDSCENE
|
|
}
|
|
|
|
func welcome() -> void:
|
|
if protection_mode: return
|
|
logger.info("CORE/core.gd","CORE (" + version["full"] + ") welcomes you!<nl>It seems like everything is working :)")
|
|
|
|
func reload_config() -> void:
|
|
var corelog: Node = get_node("/root/CORE/CORELog")
|
|
var debugdisplay: Node = get_node("/root/CORE/DebugDisplay")
|
|
var resourcemanager: Node = get_node("/root/CORE/ResourceManager")
|
|
var splash: Node = get_node("/root/CORE/SplashScreen")
|
|
preprocessor.enabled = get_config("preprocessor_enabled",true)
|
|
preprocessor.diagnostic = get_config("preprocessor_diagnostic",false)
|
|
logger.enabled = get_config("logger_enabled",true)
|
|
logger.diagnostic = get_config("logger_diagnostic",false)
|
|
if get_config("corelog_enabled",true):
|
|
corelog.display()
|
|
else:
|
|
corelog.dissolve()
|
|
debugdisplay.config_enabled = get_config("debugdisplay_enabled",true)
|
|
debugdisplay.config_fps = get_config("debugdisplay_fps",true)
|
|
debugdisplay.config_delta = get_config("debugdisplay_delta",true)
|
|
debugdisplay.config_rendertime = get_config("debugdisplay_rendertime",true)
|
|
debugdisplay.config_memory = get_config("debugdisplay_memory",true)
|
|
resourcemanager.config_load_invalid_file_as_null = get_config("resourcemanager_load_invalid_file_as_null",false)
|
|
splash.config_enabled = get_config("splash_enabled",false)
|
|
splash.config_image = get_config("splash_image","[LOADPATH]soscore.png").replace("[LOADPATH]",loadpath)
|
|
splash.config_image_size = get_config("config.splash_image_size",256)
|
|
splash.config_color = get_config("config.splash_color","#d60532")
|
|
splash.apply_config()
|
|
|
|
func get_config(config_key:StringName,default_value:Variant) -> Variant:
|
|
if protection_mode: return null
|
|
if config.get(config_key) == null:
|
|
return default_value
|
|
else:
|
|
return config.get(config_key)
|
|
|
|
func get_module(module_name:String) -> Node:
|
|
if protection_mode: return null
|
|
if module_name == "CORELog":
|
|
var err = error("CORE",Errors.CORE_INVALID_MODULE,{"module":module_name})
|
|
logger.error("CORE/core.gd",err["error"])
|
|
return err["code"]
|
|
var module: Node = get_node_or_null("/root/CORE/" + module_name)
|
|
if module == null:
|
|
var err = error("CORE",Errors.CORE_INVALID_MODULE,{"module":module_name})
|
|
logger.error("CORE/core.gd",err["error"])
|
|
return err["code"]
|
|
return module
|
|
|
|
func devmode():
|
|
logger.warn("CORE/core.gd","Development mode is now active.<nl>Keep this disabled if you don't know what you're doing<nl>or you may encounter serious issues!<nl><nl>You have been warned!")
|
|
logger.warn("CORE/core.gd","The development mode does nothing as of now. It is just \"a thing\" implemented for the future")
|
|
development_mode = true
|
|
|
|
func exception(module:String,exception_error:String):
|
|
protection_mode = true
|
|
var submit_issue_default = "Please report this crash to the CORE Framework repository (with
|
|
the full log file). You can submit a crash report at:
|
|
https://git.staropensource.de/StarOpenSource/core/issues/new"
|
|
var submit_issue_devmode = """Please do NOT report this crash to the CORE Framework repository
|
|
as CORE is running in development mode, which is not supported."""
|
|
var exc_message: String = """
|
|
[color=red]################################
|
|
EXCEPTION! EXCEPTION! EXCEPTION!
|
|
|
|
The CORE Framework experienced a critical error in runtime.
|
|
%submit_issue%
|
|
|
|
CORE INFORMATION
|
|
version = "%version%"
|
|
development_mode = %development_mode%
|
|
preprocessor_enabled = %preprocessor_enabled%
|
|
preprocessor_diagnostic = %preprocessor_diagnostic%
|
|
logger_enabled = %logger_enabled%
|
|
logger_diagnostic = %logger_diagnostic%
|
|
|
|
OPERATING SYSTEM
|
|
timezone = %timezone%
|
|
time_utc = "%time_utc%"
|
|
time_unix = %time_unix%
|
|
date = "%date%"
|
|
locale = "%locale%"
|
|
lang = "%lang%"
|
|
name = "%name%"
|
|
distro = "%distro%"
|
|
version = "%version_os%"
|
|
memory = %memory%
|
|
memory_peak = %memory_peak%
|
|
memory_usage = %memory_usage%
|
|
processor_count = %processor_count%
|
|
processor_name = "%processor_name%"
|
|
video_adapter = %video_adapter%
|
|
rendering_api = "%rendering_api%"
|
|
|
|
APPLICATION
|
|
cmdline = %cmdline%
|
|
permissions = %permissions%
|
|
debug_build = %debug_build%
|
|
|
|
ERROR INFORMATION
|
|
module = "%module%"
|
|
error = "%error%"
|
|
|
|
STACKTRACE
|
|
%stacktrace%
|
|
|
|
EXCEPTION! EXCEPTION! EXCEPTION!
|
|
################################
|
|
"""
|
|
if development_mode:
|
|
exc_message = exc_message.replace("%submit_issue%",submit_issue_devmode)
|
|
else:
|
|
exc_message = exc_message.replace("%submit_issue%",submit_issue_default)
|
|
exc_message = exc_message.replace("%version%",version["full"])
|
|
exc_message = exc_message.replace("%development_mode%",str(development_mode))
|
|
exc_message = exc_message.replace("%preprocessor_enabled%",str(preprocessor.enabled))
|
|
exc_message = exc_message.replace("%preprocessor_diagnostic%",str(preprocessor.diagnostic))
|
|
exc_message = exc_message.replace("%logger_enabled%",str(logger.enabled))
|
|
exc_message = exc_message.replace("%logger_diagnostic%",str(logger.diagnostic))
|
|
|
|
exc_message = exc_message.replace("%timezone%",str(Time.get_time_zone_from_system()))
|
|
exc_message = exc_message.replace("%time_utc%",Time.get_time_string_from_system(true))
|
|
exc_message = exc_message.replace("%time_unix%",str(Time.get_unix_time_from_datetime_string(Time.get_time_string_from_system(true))))
|
|
exc_message = exc_message.replace("%date%",Time.get_date_string_from_system(true))
|
|
exc_message = exc_message.replace("%locale%",OS.get_locale())
|
|
exc_message = exc_message.replace("%lang%",OS.get_locale_language())
|
|
exc_message = exc_message.replace("%name%",OS.get_name())
|
|
exc_message = exc_message.replace("%distro%",OS.get_distribution_name())
|
|
exc_message = exc_message.replace("%version_os%",OS.get_version())
|
|
exc_message = exc_message.replace("%memory%",str(OS.get_memory_info()))
|
|
exc_message = exc_message.replace("%memory_peak%",str(OS.get_static_memory_peak_usage()))
|
|
exc_message = exc_message.replace("%memory_usage%",str(OS.get_static_memory_usage()))
|
|
exc_message = exc_message.replace("%processor_count%",str(OS.get_processor_count()))
|
|
exc_message = exc_message.replace("%processor_name%",OS.get_processor_name())
|
|
exc_message = exc_message.replace("%video_adapter%",str(OS.get_video_adapter_driver_info()))
|
|
exc_message = exc_message.replace("%rendering_api%",RenderingServer.get_video_adapter_api_version())
|
|
|
|
exc_message = exc_message.replace("%cmdline%",str(OS.get_cmdline_args()))
|
|
exc_message = exc_message.replace("%permissions%",str(OS.get_granted_permissions()))
|
|
exc_message = exc_message.replace("%debug_build%",str(OS.is_debug_build()))
|
|
|
|
exc_message = exc_message.replace("%module%",module)
|
|
exc_message = exc_message.replace("%error%",exception_error)
|
|
exc_message = exc_message.replace("%stacktrace%",str(get_stack()))
|
|
|
|
print_rich(exc_message)
|
|
await get_tree().create_timer(0.25).timeout
|
|
get_tree().quit(255)
|
|
|
|
func error(module:String,error_enum:Errors,error_info:Dictionary = {}) -> Dictionary:
|
|
match(error_enum):
|
|
Errors.OK:
|
|
exception("core","Module \"" + module + "\" tried recieving information about error OK (are you ok?)")
|
|
Errors.CORE_PROTECTIONMODE:
|
|
return {"code":9223372036854775807,"error":"CORE is in protection mode and is unavailable"}
|
|
Errors.CORE_EXCEPTION:
|
|
return {"code":9223372036854775806,"error":"Launching nuke in 3... 2... 1..."}
|
|
Errors.CORE_INVALID_MODULE:
|
|
return {"code":Errors.CORE_INVALID_MODULE,"error":"The CORE module \"" + error_info["module"] + "\" does not exist"}
|
|
Errors.RESOURCEMANAGER_ALREADY_EXISTS:
|
|
return {"code":Errors.RESOURCEMANAGER_ALREADY_EXISTS,"error":"Failed loading resource: The resource \"" + error_info["name"] + "\" is already loaded"}
|
|
Errors.RESOURCEMANAGER_INVALID_FILEPATH:
|
|
return {"code":Errors.RESOURCEMANAGER_INVALID_FILEPATH,"error":"Failed loading resource: The filepath \"" + error_info["filepath"] + "\" is invalid"}
|
|
Errors.RESOURCEMANAGER_RESOURCE_MISSING:
|
|
return {"code":Errors.RESOURCEMANAGER_RESOURCE_MISSING,"error":"Failed unloading resource: The resource \"" + error_info["name"] + "\" is not loaded"}
|
|
Errors.RESOURCEMANAGER_BATCH_EMPTY:
|
|
return {"code":Errors.RESOURCEMANAGER_BATCH_EMPTY,"error":"Failed processing batch: The batch is empty"}
|
|
Errors.SCENEMANAGER_ALREADY_LOADED:
|
|
if error_info["one_scene_overlay"]:
|
|
return {"code":Errors.SCENEMANAGER_ALREADY_LOADED,"error":"Failed adding scene \"" + error_info["scene"] + "\" to overlay \"" + error_info["overlay"] + "\": The overlay is full"}
|
|
else:
|
|
return {"code":Errors.SCENEMANAGER_ALREADY_LOADED,"error":"Failed adding scene \"" + error_info["scene"] + "\" to overlay \"" + error_info["overlay"] + "\": A resource with the same name is already present in that overlay"}
|
|
Errors.SCENEMANAGER_NOT_LOADED:
|
|
if error_info["one_scene_overlay"]:
|
|
return {"code":Errors.SCENEMANAGER_ALREADY_LOADED,"error":"Failed removing scene \"" + error_info["scene"] + "\" from overlay \"" + error_info["overlay"] + "\": The overlay is empty"}
|
|
else:
|
|
return {"code":Errors.SCENEMANAGER_ALREADY_LOADED,"error":"Failed removing scene \"" + error_info["scene"] + "\" from overlay \"" + error_info["overlay"] + "\": A resource with that name could not be found within the overlay"}
|
|
Errors.SCENEMANAGER_NOT_PACKEDSCENE:
|
|
return {"code":Errors.SCENEMANAGER_NOT_PACKEDSCENE,"error":"Failed adding scene \"" + error_info["scene"] + "\" to overlay \"" + error_info["overlay"] + "\": The specified resource is not a PackedScene"}
|
|
_:
|
|
exception("core","Failed generating error: Invalid error \"" + str(error) + "\"")
|
|
return error("CORE",Errors.CORE_EXCEPTION)
|
|
|
|
func exit_safely(exitcode:int = 0) -> void:
|
|
if protection_mode: return
|
|
logger.info("CORE/core.gd","Shutting down...")
|
|
protection_mode = true
|
|
await get_tree().create_timer(0.5).timeout
|
|
get_tree().quit(exitcode)
|