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>
209 lines
8.3 KiB
GDScript
209 lines
8.3 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
|
|
|
|
var loadpath: String = "res://CORE/"
|
|
|
|
# To workaround the "busy setting up children" issue coreinit.gd
|
|
# "reloads" itself. I don't know why it works, but it works.
|
|
func _ready() -> void:
|
|
if name == "COREINIT":
|
|
initialize()
|
|
else:
|
|
print("coreinit -> \"Fixing\" busy setting up children issue")
|
|
var coreinit_raw: Script = ResourceLoader.load(loadpath + "coreinit.gd")
|
|
var coreinit: Node = Node.new()
|
|
coreinit.name = "COREINIT"
|
|
coreinit.set_script(coreinit_raw)
|
|
get_tree().root.add_child.call_deferred(coreinit)
|
|
if loadpath == "":
|
|
coreinit.set_deferred("loathpath","res://CORE/")
|
|
else:
|
|
coreinit.set_deferred("loadpath",loadpath)
|
|
queue_free()
|
|
|
|
# Bootstraps CORE
|
|
func initialize() -> void:
|
|
print("coreinit -> Bootstrapping CORE")
|
|
# Check requirements and quit if not met
|
|
if !check_requirements():
|
|
await get_tree().create_timer(0.25).timeout
|
|
get_tree().quit(255)
|
|
return
|
|
# Load module scripts and scenes
|
|
print("coreinit -> Loading modules")
|
|
var mod_config_raw: Script = ResourceLoader.load(loadpath + "config.gd")
|
|
var mod_corelog_raw: PackedScene = ResourceLoader.load(loadpath + "corelog.tscn")
|
|
var mod_logger_raw: Script = ResourceLoader.load(loadpath + "logger.gd")
|
|
var mod_preprocessor_raw: Script = ResourceLoader.load(loadpath + "preprocessor.gd")
|
|
var mod_core_raw: Script = ResourceLoader.load(loadpath + "core.gd")
|
|
var mod_misc_raw: Script = ResourceLoader.load(loadpath + "misc.gd")
|
|
var mod_debugdisplay_raw: PackedScene = ResourceLoader.load(loadpath + "debugdisplay.tscn")
|
|
var mod_splash_raw: PackedScene = ResourceLoader.load(loadpath + "splash.tscn")
|
|
var mod_resmgr_raw: Script = ResourceLoader.load(loadpath + "resmgr.gd")
|
|
var mod_smgr_raw: Script = ResourceLoader.load(loadpath + "smgr.gd")
|
|
var mod_events_raw: Script = ResourceLoader.load(loadpath + "events.gd")
|
|
#var mod_cml_raw: Script = ResourceLoader.load(loadpath + "cml.gd")
|
|
var mod_mkdown_raw: Script = ResourceLoader.load(loadpath + "mkdown.gd")
|
|
# Create nodes and add the raw scripts + give them names
|
|
print("coreinit -> Constructing modules")
|
|
var mod_config: Node = Node.new()
|
|
mod_config.name = "Config"
|
|
mod_config.set_script(mod_config_raw)
|
|
var mod_preprocessor: Node = Node.new()
|
|
mod_preprocessor.name = "Preprocessor"
|
|
mod_preprocessor.set_script(mod_preprocessor_raw)
|
|
var mod_logger: Node = Node.new()
|
|
mod_logger.name = "Logger"
|
|
mod_logger.set_script(mod_logger_raw)
|
|
var mod_corelog: Node = mod_corelog_raw.instantiate()
|
|
mod_corelog.name = "CORELog"
|
|
var mod_core: Node = Node.new()
|
|
mod_core.name = "CORE"
|
|
mod_core.set_script(mod_core_raw)
|
|
mod_core.loadpath = loadpath
|
|
var mod_misc: Node = Node.new()
|
|
mod_misc.name = "Miscellaneous"
|
|
mod_misc.set_script(mod_misc_raw)
|
|
var mod_debugdisplay: Node = mod_debugdisplay_raw.instantiate()
|
|
mod_debugdisplay.name = "DebugDisplay"
|
|
var mod_splash: Node = mod_splash_raw.instantiate()
|
|
mod_splash.name = "SplashScreen"
|
|
var mod_resmgr: Node = Node.new()
|
|
mod_resmgr.name = "ResourceManager"
|
|
mod_resmgr.set_script(mod_resmgr_raw)
|
|
var mod_smgr: Node = Node.new()
|
|
mod_smgr.name = "SceneManager"
|
|
mod_smgr.set_script(mod_smgr_raw)
|
|
var mod_events: Node = Node.new()
|
|
mod_events.name = "Events"
|
|
mod_events.set_script(mod_events_raw)
|
|
#var mod_cml: Node = Node.new()
|
|
#mod_cml.name = "ModLoader"
|
|
#mod_cml.set_script(mod_cml_raw)
|
|
var mod_mkdown: Node = Node.new()
|
|
mod_mkdown.name = "Markdown"
|
|
mod_mkdown.set_script(mod_mkdown_raw)
|
|
# Add all modules to /root/
|
|
print("coreinit -> Injecting modules")
|
|
get_tree().root.add_child(mod_core)
|
|
mod_core.add_child(mod_config)
|
|
mod_core.add_child(mod_preprocessor)
|
|
mod_core.add_child(mod_logger)
|
|
mod_core.add_child(mod_misc)
|
|
mod_core.add_child(mod_corelog)
|
|
mod_core.add_child(mod_debugdisplay)
|
|
mod_core.add_child(mod_splash)
|
|
mod_core.add_child(mod_resmgr)
|
|
mod_core.add_child(mod_smgr)
|
|
#mod_core.add_child(mod_cml)
|
|
mod_core.add_child(mod_events)
|
|
mod_core.add_child(mod_mkdown)
|
|
# Updates references to other modules
|
|
print("coreinit -> Updating dependency references")
|
|
mod_corelog.core = mod_core
|
|
mod_corelog.logger = mod_logger
|
|
mod_preprocessor.core = mod_core
|
|
mod_preprocessor.logger = mod_logger
|
|
mod_logger.core = mod_core
|
|
mod_logger.preprocessor = mod_preprocessor
|
|
mod_core.logger = mod_logger
|
|
mod_core.preprocessor = mod_preprocessor
|
|
mod_core.config = mod_config
|
|
mod_misc.core = mod_core
|
|
mod_debugdisplay.core = mod_core
|
|
mod_debugdisplay.misc = mod_misc
|
|
mod_splash.core = mod_core
|
|
mod_splash.logger = mod_logger
|
|
mod_resmgr.core = mod_core
|
|
mod_resmgr.logger = mod_logger
|
|
mod_smgr.logger = mod_logger
|
|
mod_smgr.core = mod_core
|
|
mod_smgr.resourcemanager = mod_resmgr
|
|
mod_events.core = mod_core
|
|
#mod_cml.core = mod_core
|
|
#mod_cml.logger = mod_logger
|
|
mod_events.logger = mod_logger
|
|
mod_mkdown.core = mod_core
|
|
mod_mkdown.logger = mod_logger
|
|
# Apply config to base modules
|
|
print("coreinit -> Applying configuration to base modules")
|
|
mod_preprocessor.enabled = get_config(mod_config,"preprocessor_enabled",true)
|
|
mod_preprocessor.diagnostic = get_config(mod_config,"preprocessor_diagnostic",false)
|
|
mod_logger.enabled = get_config(mod_config,"logger_enabled",true)
|
|
mod_logger.diagnostic = get_config(mod_config,"logger_diagnostic",false)
|
|
if get_config(mod_config,"corelog_enable",true):
|
|
mod_corelog.display()
|
|
else:
|
|
mod_corelog.dissolve()
|
|
# Call initialize() on base modules
|
|
print("coreinit -> Initializing base modules")
|
|
mod_corelog.initialize()
|
|
mod_logger.initialize()
|
|
mod_preprocessor.initialize()
|
|
# Apply config to all modules
|
|
mod_logger.diag("CORE/coreinit.gd","Reloading configuration")
|
|
mod_core.reload_config()
|
|
# Call initialize() method on all modules
|
|
mod_logger.diag("CORE/coreinit.gd","Initializing modules")
|
|
#mod_splash.initialize() ## Has no initialize() method
|
|
#mod_resmgr.initialize() ## Has no initialize() method
|
|
mod_smgr.initialize()
|
|
#mod_cml.initialize()
|
|
mod_events.initialize()
|
|
# Inject init script
|
|
mod_logger.diag("CORE/coreinit.gd","Loading init script")
|
|
if !FileAccess.file_exists(get_config(mod_config,"startup_script","res://init.gd")):
|
|
mod_core.exception("CORE/coreinit.gd","Startup script located at \"" + get_config(mod_config,"startup_script","res://init.gd") + "\" does not exist")
|
|
return
|
|
var initscr_raw: Script = ResourceLoader.load(get_config(mod_config,"core_initscript","res://init.gd"))
|
|
mod_logger.diag("CORE/coreinit.gd","Constructing init script")
|
|
var initscr: Node = Node.new()
|
|
initscr.name = "InitializationScript"
|
|
initscr.set_script(initscr_raw)
|
|
mod_logger.diag("CORE/coreinit.gd","Injecting init script")
|
|
get_tree().root.add_child(initscr)
|
|
mod_logger.diag("CORE/coreinit.gd","Bootstrapped CORE, exiting.")
|
|
queue_free()
|
|
|
|
# Retrieves a key's value from the configuration file
|
|
func get_config(config:Node,config_key:StringName,default_value:Variant) -> Variant:
|
|
if config.get(config_key) == null:
|
|
return default_value
|
|
else:
|
|
return config.get(config_key)
|
|
|
|
# Check CORE's requirements
|
|
func check_requirements() -> bool:
|
|
var engine_version: Dictionary = Engine.get_version_info()
|
|
print("coreinit -> Checking CORE requirements")
|
|
# Check if Godot major version is exactly 4
|
|
if engine_version["major"] != 4:
|
|
print("coreinit -> Error: CORE only supports Godot 4.1.stable releases.")
|
|
return false
|
|
# Check if Godot minor version is exactly 1
|
|
if engine_version["minor"] != 1:
|
|
print("coreinit -> Error: CORE only supports Godot 4.1.stable releases.")
|
|
return false
|
|
# Check if Godot release channel is "stable"
|
|
if engine_version["status"] != "stable":
|
|
print("coreinit -> Error: CORE only supports Godot 4.1.stable releases.")
|
|
return false
|
|
# Display warning if autoloads are used
|
|
if get_tree().root.get_child_count(true) != 2:
|
|
print("coreinit -> Warning: We do not recommend using autoloads in your project as bugs may occur.")
|
|
# Check if configuration file exists
|
|
if !FileAccess.file_exists(loadpath + "config.gd"):
|
|
print("coreinit -> Error: The CORE configuration file is missing. Use CORE Manager to repair your project.")
|
|
return false
|
|
# Success!
|
|
return true
|