Framework rework
Changes in this commit include: - Add Core.cleanup() and CoreBaseModule._cleanup() functions - All builtin modules now clean and free any nodes - Reduce code duplication in src/core.gd by not writing the same code for all builtin modules but instead iterating through a array
This commit is contained in:
parent
3bcc18df82
commit
b8a43ce159
7 changed files with 77 additions and 77 deletions
|
@ -36,6 +36,9 @@ var initialized: bool = false
|
||||||
## CORE's replacement for [method Object._init] and [method Node._ready]
|
## CORE's replacement for [method Object._init] and [method Node._ready]
|
||||||
## It's [b]strongly[/b] recommended to initialize your module here.
|
## It's [b]strongly[/b] recommended to initialize your module here.
|
||||||
func _initialize() -> void: initialized = true
|
func _initialize() -> void: initialized = true
|
||||||
|
## Called when CORE is about to cleanup
|
||||||
|
## Use this function to free any children
|
||||||
|
func _cleanup() -> void: pass
|
||||||
## Called by [method Core.apply_configuration].
|
## Called by [method Core.apply_configuration].
|
||||||
## This should be used to update your module configuration.
|
## This should be used to update your module configuration.
|
||||||
func _pull_config() -> void: pass
|
func _pull_config() -> void: pass
|
||||||
|
|
89
src/core.gd
89
src/core.gd
|
@ -31,6 +31,7 @@ const version_type: CoreTypes.VersionType = CoreTypes.VersionType.BETA
|
||||||
const version_typerelease: int = 4
|
const version_typerelease: int = 4
|
||||||
|
|
||||||
# Modules
|
# Modules
|
||||||
|
const modules: Array[String] = [ "logger", "misc", "sms", "logui", "edl", "storage" ]
|
||||||
## Use this to access CORE's logging implementation.
|
## Use this to access CORE's logging implementation.
|
||||||
var logger: CoreBaseModule
|
var logger: CoreBaseModule
|
||||||
## Use this to access various useful functions.
|
## Use this to access various useful functions.
|
||||||
|
@ -72,58 +73,38 @@ func _ready() -> void:
|
||||||
custom_modules_node.name = "Custom Modules"
|
custom_modules_node.name = "Custom Modules"
|
||||||
add_child(custom_modules_node)
|
add_child(custom_modules_node)
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
# Particularily useful during testing to cleanup stuff, or if you want to do some stupid stuff with CORE during runtime
|
||||||
|
func cleanup() -> void:
|
||||||
|
logger.infof("Core", "Cleaning up")
|
||||||
|
config.queue_free()
|
||||||
|
var modules_reverse: Array[String] = modules.duplicate()
|
||||||
|
modules_reverse.reverse()
|
||||||
|
for module in modules_reverse:
|
||||||
|
await get(module)._cleanup()
|
||||||
|
get(module).queue_free()
|
||||||
|
for module in custom_modules_node.get_children(): unregister_custom_module(module.name)
|
||||||
|
remove_child(custom_modules_node)
|
||||||
|
custom_modules_node.queue_free()
|
||||||
|
queue_free()
|
||||||
|
|
||||||
# Initialize modules
|
# Initialize modules
|
||||||
## Initializes all modules during the first initialization phase.[br]
|
## Initializes all modules during the first initialization phase.[br]
|
||||||
## [br]
|
## [br]
|
||||||
## [b]NEVER call this yourself! You will break everything and risk a crash![/b]
|
## [b]NEVER call this yourself! You will break everything and risk a crash![/b]
|
||||||
func initialize_modules() -> void:
|
func initialize_modules() -> void:
|
||||||
# Create Nodes
|
for module in modules:
|
||||||
logger = CoreBaseModule.new()
|
set(module, CoreBaseModule.new())
|
||||||
misc = CoreBaseModule.new()
|
get(module).name = module
|
||||||
sms = CoreBaseModule.new()
|
get(module).set_script(load(basepath + "src/" + module + ".gd"))
|
||||||
logui = CoreBaseModule.new()
|
get(module).core = self
|
||||||
edl = CoreBaseModule.new()
|
get(module)._initialize()
|
||||||
storage = CoreBaseModule.new()
|
|
||||||
# Set names
|
|
||||||
logger.name = "Logger"
|
|
||||||
misc.name = "Misc"
|
|
||||||
sms.name = "SceneManagementSystem"
|
|
||||||
logui.name = "LogUI"
|
|
||||||
edl.name = "EasyDownLoader"
|
|
||||||
storage.name = "Storage"
|
|
||||||
# Set scripts
|
|
||||||
logger.set_script(ResourceLoader.load(basepath + "src/logger.gd"))
|
|
||||||
misc.set_script(ResourceLoader.load(basepath + "src/misc.gd"))
|
|
||||||
sms.set_script(ResourceLoader.load(basepath + "src/sms.gd"))
|
|
||||||
logui.set_script(ResourceLoader.load(basepath + "src/logui.gd"))
|
|
||||||
edl.set_script(ResourceLoader.load(basepath + "src/edl.gd"))
|
|
||||||
storage.set_script(ResourceLoader.load(basepath + "src/storage.gd"))
|
|
||||||
# Set reference to self
|
|
||||||
logger.core = self
|
|
||||||
misc.core = self
|
|
||||||
sms.core = self
|
|
||||||
logui.core = self
|
|
||||||
edl.core = self
|
|
||||||
storage.core = self
|
|
||||||
# Call _initialize() (workaround as modules cannot access "core" during _init())
|
|
||||||
logger._initialize()
|
|
||||||
misc._initialize()
|
|
||||||
sms._initialize()
|
|
||||||
logui._initialize()
|
|
||||||
edl._initialize()
|
|
||||||
storage._initialize()
|
|
||||||
|
|
||||||
# Inject modules into the SceneTree
|
# Inject modules into the SceneTree
|
||||||
## Injects CORE's builtin modules into the SceneTree.[br]
|
## Injects CORE's builtin modules into the SceneTree.[br]
|
||||||
## [br]
|
## [br]
|
||||||
## [b]NEVER call this yourself! You will break everything and risk a crash![/b]
|
## [b]NEVER call this yourself! You will break everything and risk a crash![/b]
|
||||||
func inject_modules() -> void:
|
func inject_modules() -> void: for module in modules: add_child(get(module))
|
||||||
add_child(logger)
|
|
||||||
add_child(misc)
|
|
||||||
add_child(sms)
|
|
||||||
add_child(logui)
|
|
||||||
add_child(edl)
|
|
||||||
add_child(storage)
|
|
||||||
|
|
||||||
# Wait for all modules to be fully initialized
|
# Wait for all modules to be fully initialized
|
||||||
## Wait for all builtin modules to be fully initialized.[br]
|
## Wait for all builtin modules to be fully initialized.[br]
|
||||||
|
@ -140,12 +121,7 @@ func complete_init(no_success: bool = false) -> void:
|
||||||
modsinit_custom = []
|
modsinit_custom = []
|
||||||
|
|
||||||
# Check builtin modules
|
# Check builtin modules
|
||||||
if !logger.initialized: modsinit_builtin.append("logger")
|
for module in modules: if !get(module).initialized: modsinit_builtin.append(module)
|
||||||
if !misc.initialized: modsinit_builtin.append("misc")
|
|
||||||
if !sms.initialized: modsinit_builtin.append("sms")
|
|
||||||
if !logui.initialized: modsinit_builtin.append("logui")
|
|
||||||
if !edl.initialized: modsinit_builtin.append("edl")
|
|
||||||
if !storage.initialized: modsinit_builtin.append("storage")
|
|
||||||
|
|
||||||
# Check custom modules
|
# Check custom modules
|
||||||
for module_name in custom_modules:
|
for module_name in custom_modules:
|
||||||
|
@ -154,10 +130,8 @@ func complete_init(no_success: bool = false) -> void:
|
||||||
# Print and sleep
|
# Print and sleep
|
||||||
if modsinit_builtin.size() != 0 or modsinit_custom.size() != 0:
|
if modsinit_builtin.size() != 0 or modsinit_custom.size() != 0:
|
||||||
print("Waiting for modules to finish initialization:")
|
print("Waiting for modules to finish initialization:")
|
||||||
if modsinit_builtin.size() != 0:
|
if modsinit_builtin.size() != 0: print(" Builtin: " + str(modsinit_builtin))
|
||||||
print(" Builtin: " + str(modsinit_builtin))
|
if modsinit_custom.size() != 0: print(" Custom: " + str(modsinit_custom))
|
||||||
if modsinit_custom.size() != 0:
|
|
||||||
print(" Custom: " + str(modsinit_custom))
|
|
||||||
await get_tree().create_timer(1).timeout
|
await get_tree().create_timer(1).timeout
|
||||||
|
|
||||||
# Initialization complete
|
# Initialization complete
|
||||||
|
@ -194,8 +168,11 @@ func unregister_custom_module(module_name: String) -> void:
|
||||||
if !custom_modules.has(module_name):
|
if !custom_modules.has(module_name):
|
||||||
logger.errorf("Core", "Unregistering module failed: A custom module with the name \"" + module_name + "\" does not exist.")
|
logger.errorf("Core", "Unregistering module failed: A custom module with the name \"" + module_name + "\" does not exist.")
|
||||||
return
|
return
|
||||||
custom_modules_node.remove_child(get_custom_module(module_name))
|
var module: Node = get_custom_module(module_name)
|
||||||
|
await module._cleanup()
|
||||||
|
custom_modules_node.remove_child(module)
|
||||||
custom_modules.erase(module_name)
|
custom_modules.erase(module_name)
|
||||||
|
module.queue_free()
|
||||||
|
|
||||||
# Returns a custom module
|
# Returns a custom module
|
||||||
## Returns a loaded custom module for access.
|
## Returns a loaded custom module for access.
|
||||||
|
@ -211,6 +188,7 @@ func get_custom_module(module_name: String) -> CoreBaseModule:
|
||||||
func reload_configuration(new_config: CoreConfiguration = CoreConfiguration.new()) -> void:
|
func reload_configuration(new_config: CoreConfiguration = CoreConfiguration.new()) -> void:
|
||||||
var initialized = config != null
|
var initialized = config != null
|
||||||
if initialized: logger.verbf("Core", "Reloading CORE's configuration")
|
if initialized: logger.verbf("Core", "Reloading CORE's configuration")
|
||||||
|
if config != null: config.queue_free()
|
||||||
config = new_config
|
config = new_config
|
||||||
if is_devmode(): # Override configuration in development mode
|
if is_devmode(): # Override configuration in development mode
|
||||||
config.logger_level = CoreTypes.LoggerLevel.VERB
|
config.logger_level = CoreTypes.LoggerLevel.VERB
|
||||||
|
@ -229,10 +207,7 @@ func apply_configuration() -> void:
|
||||||
if !config.custom_modules:
|
if !config.custom_modules:
|
||||||
logger.verbf("Core", "Removing all custom modules (custom modules support is disabled)")
|
logger.verbf("Core", "Removing all custom modules (custom modules support is disabled)")
|
||||||
for module in custom_modules: unregister_custom_module(module)
|
for module in custom_modules: unregister_custom_module(module)
|
||||||
logger._pull_config()
|
for module in modules: get(module)._pull_config()
|
||||||
misc._pull_config()
|
|
||||||
sms._pull_config()
|
|
||||||
logui._pull_config()
|
|
||||||
if config.custom_modules:
|
if config.custom_modules:
|
||||||
for module in custom_modules:
|
for module in custom_modules:
|
||||||
logger.diagf("Core", "Updating configuration for custom module \"" + module.name + "\"")
|
logger.diagf("Core", "Updating configuration for custom module \"" + module.name + "\"")
|
||||||
|
|
15
src/edl.gd
15
src/edl.gd
|
@ -24,6 +24,15 @@ var list_queue: Dictionary = {}
|
||||||
var list_active: Dictionary = {}
|
var list_active: Dictionary = {}
|
||||||
var list_complete: Dictionary = {}
|
var list_complete: Dictionary = {}
|
||||||
|
|
||||||
|
func _cleanup() -> void:
|
||||||
|
clean_queue()
|
||||||
|
clean_completed()
|
||||||
|
for child in get_children():
|
||||||
|
if child.is_class("HTTPRequest"):
|
||||||
|
child.cancel_request()
|
||||||
|
await get_tree().process_frame
|
||||||
|
remove_child(child)
|
||||||
|
|
||||||
func generate_id() -> int:
|
func generate_id() -> int:
|
||||||
var id = randi()
|
var id = randi()
|
||||||
if list_queue.has(id) or list_active.has(id): return generate_id()
|
if list_queue.has(id) or list_active.has(id): return generate_id()
|
||||||
|
@ -75,11 +84,13 @@ func start_download(id: int, parse_utf8: bool) -> void:
|
||||||
download.name = "Request #" + str(id)
|
download.name = "Request #" + str(id)
|
||||||
download.accept_gzip = true
|
download.accept_gzip = true
|
||||||
download.use_threads = true
|
download.use_threads = true
|
||||||
var lambda: Callable = func(result: int, http_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
|
var lambda: Callable = func(result: int, http_code: int, headers: PackedStringArray, body: PackedByteArray, httprequest: HTTPRequest) -> void:
|
||||||
logger.verbf("Edl", "Request " + str(id) + " completed\nResult: " + str(result) + "\nHTTP response code: " + str(http_code) + "\nHeaders: " + str(headers.size()) + "\nBody size: " + str(body.size()) + " Bytes // " + str(core.misc.byte2mib(body.size(), true)) + " MiB")
|
logger.verbf("Edl", "Request " + str(id) + " completed\nResult: " + str(result) + "\nHTTP response code: " + str(http_code) + "\nHeaders: " + str(headers.size()) + "\nBody size: " + str(body.size()) + " Bytes // " + str(core.misc.byte2mib(body.size(), true)) + " MiB")
|
||||||
list_complete.merge({ id: { "result": result, "http_code": http_code, "headers": headers, "body": body, "body_utf8": body.get_string_from_utf8() if !parse_utf8 else "" } })
|
list_complete.merge({ id: { "result": result, "http_code": http_code, "headers": headers, "body": body, "body_utf8": body.get_string_from_utf8() if !parse_utf8 else "" } })
|
||||||
list_active.erase(id)
|
list_active.erase(id)
|
||||||
download.connect("request_completed", lambda)
|
remove_child(httprequest)
|
||||||
|
httprequest.queue_free()
|
||||||
|
download.connect("request_completed", lambda.bind(download))
|
||||||
add_child(download)
|
add_child(download)
|
||||||
download.request(list_active[id]["url"], list_active[id]["headers"], list_active[id]["method"], list_active[id]["body"])
|
download.request(list_active[id]["url"], list_active[id]["headers"], list_active[id]["method"], list_active[id]["body"])
|
||||||
|
|
||||||
|
|
24
src/logui.gd
24
src/logui.gd
|
@ -30,8 +30,8 @@ var font_bold: Font
|
||||||
|
|
||||||
func _initialize() -> void:
|
func _initialize() -> void:
|
||||||
# Load fonts into memory
|
# Load fonts into memory
|
||||||
font_normal = ResourceLoader.load(core.basepath + "dist/FiraCode/Regular.ttf")
|
font_normal = load(core.basepath + "dist/FiraCode/Regular.ttf")
|
||||||
font_bold = ResourceLoader.load(core.basepath + "dist/FiraCode/Bold.ttf")
|
font_bold = load(core.basepath + "dist/FiraCode/Bold.ttf")
|
||||||
# Create LogUI
|
# Create LogUI
|
||||||
background = ColorRect.new()
|
background = ColorRect.new()
|
||||||
background.name = "LOGUI"
|
background.name = "LOGUI"
|
||||||
|
@ -59,17 +59,12 @@ func _initialize() -> void:
|
||||||
# Mark as initialized
|
# Mark as initialized
|
||||||
initialized = true
|
initialized = true
|
||||||
|
|
||||||
func _pull_config() -> void:
|
|
||||||
background.visible = !core.config.headless and core.config.logui_enabled
|
|
||||||
background.color = core.config.logui_background_color
|
|
||||||
logrtl.add_theme_font_size_override("normal_font_size", core.config.logui_font_size)
|
|
||||||
logrtl.add_theme_font_size_override("bold_font_size", core.config.logui_font_size)
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# Add to SceneTree
|
# Add to SceneTree
|
||||||
core.sms.add_child(background)
|
core.sms.add_child(background)
|
||||||
core.sms.move_child(background, 0)
|
core.sms.move_child(background, 0)
|
||||||
background.add_child(logrtl)
|
background.add_child(logrtl)
|
||||||
|
|
||||||
# Hide VScrollBar
|
# Hide VScrollBar
|
||||||
var vsbar: VScrollBar = logrtl.get_child(0, true)
|
var vsbar: VScrollBar = logrtl.get_child(0, true)
|
||||||
vsbar.set_deferred("size", Vector2i(1, 1))
|
vsbar.set_deferred("size", Vector2i(1, 1))
|
||||||
|
@ -79,9 +74,22 @@ func _ready() -> void:
|
||||||
vsbar.add_theme_stylebox_override("grabber", StyleBoxEmpty.new())
|
vsbar.add_theme_stylebox_override("grabber", StyleBoxEmpty.new())
|
||||||
vsbar.add_theme_stylebox_override("grabber_highlight", StyleBoxEmpty.new())
|
vsbar.add_theme_stylebox_override("grabber_highlight", StyleBoxEmpty.new())
|
||||||
vsbar.add_theme_stylebox_override("grabber_pressed", StyleBoxEmpty.new())
|
vsbar.add_theme_stylebox_override("grabber_pressed", StyleBoxEmpty.new())
|
||||||
|
|
||||||
# Connect log_event
|
# Connect log_event
|
||||||
logger.connect("log_event", func(allowed: bool, _level: CoreTypes.LoggerLevel, _origin: String, _message: String, format: String) -> void: if allowed: logrtl.text = logrtl.text + format + "\n")
|
logger.connect("log_event", func(allowed: bool, _level: CoreTypes.LoggerLevel, _origin: String, _message: String, format: String) -> void: if allowed: logrtl.text = logrtl.text + format + "\n")
|
||||||
|
|
||||||
|
func _cleanup() -> void:
|
||||||
|
background.remove_child(logrtl)
|
||||||
|
core.sms.remove_child(background)
|
||||||
|
logrtl.queue_free()
|
||||||
|
background.queue_free()
|
||||||
|
|
||||||
|
func _pull_config() -> void:
|
||||||
|
background.visible = !core.config.headless and core.config.logui_enabled
|
||||||
|
background.color = core.config.logui_background_color
|
||||||
|
logrtl.add_theme_font_size_override("normal_font_size", core.config.logui_font_size)
|
||||||
|
logrtl.add_theme_font_size_override("bold_font_size", core.config.logui_font_size)
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
if !core.config.headless:
|
if !core.config.headless:
|
||||||
var window_size: Vector2i = DisplayServer.window_get_size()
|
var window_size: Vector2i = DisplayServer.window_get_size()
|
||||||
|
|
|
@ -25,6 +25,7 @@ func quit_safely(exitcode: int = 0) -> void:
|
||||||
logger.infof("Misc", "Shutting down (code " + str(exitcode) + ")")
|
logger.infof("Misc", "Shutting down (code " + str(exitcode) + ")")
|
||||||
logger.diagf("Misc", "Waiting for log messages to be flushed")
|
logger.diagf("Misc", "Waiting for log messages to be flushed")
|
||||||
await get_tree().create_timer(0.25).timeout
|
await get_tree().create_timer(0.25).timeout
|
||||||
|
await core.cleanup()
|
||||||
get_tree().quit(exitcode)
|
get_tree().quit(exitcode)
|
||||||
|
|
||||||
@warning_ignore("integer_division")
|
@warning_ignore("integer_division")
|
||||||
|
|
19
src/sms.gd
19
src/sms.gd
|
@ -21,6 +21,7 @@
|
||||||
extends CoreBaseModule
|
extends CoreBaseModule
|
||||||
|
|
||||||
# Objects
|
# Objects
|
||||||
|
const scene_nodes: Array[String] = ["debug", "cutscene", "menu", "main", "background"]
|
||||||
var scenes_debug: Node = Node.new()
|
var scenes_debug: Node = Node.new()
|
||||||
var scenes_cutscene: Node = Node.new()
|
var scenes_cutscene: Node = Node.new()
|
||||||
var scenes_menu: Node = Node.new()
|
var scenes_menu: Node = Node.new()
|
||||||
|
@ -31,20 +32,18 @@ var scenes_background: Node = Node.new()
|
||||||
var scenes: Dictionary = {}
|
var scenes: Dictionary = {}
|
||||||
|
|
||||||
func _initialize() -> void:
|
func _initialize() -> void:
|
||||||
scenes_debug.name = "DEBUG"
|
for scene in scene_nodes:
|
||||||
scenes_cutscene.name = "CUTSCENE"
|
get("scenes_" + scene).name = scene.to_upper()
|
||||||
scenes_menu.name = "MENU"
|
add_child(get("scenes_" + scene))
|
||||||
scenes_main.name = "MAIN"
|
|
||||||
scenes_background.name = "BACKGROUND"
|
|
||||||
add_child(scenes_background)
|
|
||||||
add_child(scenes_main)
|
|
||||||
add_child(scenes_menu)
|
|
||||||
add_child(scenes_cutscene)
|
|
||||||
add_child(scenes_debug)
|
|
||||||
|
|
||||||
# Mark as initialized
|
# Mark as initialized
|
||||||
initialized = true
|
initialized = true
|
||||||
|
|
||||||
|
func _cleanup() -> void:
|
||||||
|
for scene in scene_nodes:
|
||||||
|
remove_child(get("scenes_" + scene))
|
||||||
|
get("scenes_" + scene).queue_free()
|
||||||
|
|
||||||
func _pull_config() -> void:
|
func _pull_config() -> void:
|
||||||
if core.config.headless:
|
if core.config.headless:
|
||||||
# Remove all scenes
|
# Remove all scenes
|
||||||
|
|
|
@ -6,6 +6,9 @@ func _initialize() -> void:
|
||||||
logger.info("tests/custom_module.gd", "Module has been initialized")
|
logger.info("tests/custom_module.gd", "Module has been initialized")
|
||||||
suite.callback = "_initialize"
|
suite.callback = "_initialize"
|
||||||
|
|
||||||
|
func _cleanup() -> void:
|
||||||
|
logger.info("tests/custom_module.gd", "Cleaning module")
|
||||||
|
|
||||||
func _pull_config() -> void:
|
func _pull_config() -> void:
|
||||||
logger.info("tests/custom_module.gd", "The configuration has been updated")
|
logger.info("tests/custom_module.gd", "The configuration has been updated")
|
||||||
suite.callback = "_pull_config"
|
suite.callback = "_pull_config"
|
||||||
|
|
Loading…
Reference in a new issue