From d80f17bdc7590882ca2186af59e59693aa4a45b6 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Sat, 18 May 2024 19:22:38 +0200 Subject: [PATCH] Move launcher loading code into new module --- addons/venus/src/manager.gd | 2 +- addons/venus/src/modules/launcher.gd | 101 ++---------------- addons/venus/src/modules/resourceloader.gd | 113 +++++++++++++++++++++ 3 files changed, 124 insertions(+), 92 deletions(-) create mode 100644 addons/venus/src/modules/resourceloader.gd diff --git a/addons/venus/src/manager.gd b/addons/venus/src/manager.gd index 39f5bfa..cf8e966 100644 --- a/addons/venus/src/manager.gd +++ b/addons/venus/src/manager.gd @@ -32,8 +32,8 @@ var logger: CoreLoggerInstance ## Where Venus was installed to var path: String = "addons/venus/src" -var modules: Dictionary = { "standard": [ "splashes", "launcher" ], "sui": [] } ## Contains a list of all modules Venus provides +var modules: Dictionary = { "standard": [ "splashes", "resourceloader", "launcher" ], "sui": [] } func _init(core_new: Core) -> void: name = "VenusManager" diff --git a/addons/venus/src/modules/launcher.gd b/addons/venus/src/modules/launcher.gd index c47111f..4a4e5f0 100644 --- a/addons/venus/src/modules/launcher.gd +++ b/addons/venus/src/modules/launcher.gd @@ -14,98 +14,17 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . + +## Communication layer between sos!launcher and games/applications. +## +## [b]Note: [i]This module is basically a stub and currently serves no purpose.[br] +## It exists so games and applications that will be featured in the upcoming sos!launcher[br] +## don't need to be refactored in one go but can be refactored over time instead.[/i][/b] extends CoreBaseModule -## Loads resources using [method @GDScript.load] ([code]== true[/code]) or using Venus' dynamic resource loading implementation ([code]== false[/code]). -var config_load_native: bool = true -## The path to load resources from. Use [code]res://[/code] if [member config_load_native] is set to [code]true[/code] or some other path if set to [code]false[/code]. -var config_load_path: String = "res://" +## Reference to Venus' [param resourceloader] module. +@onready var resourceloader: CoreBaseModule = core.get_custom_module("resourceloader") -## A list of all format loaders -var format_loaders: Dictionary = { - # Godot file types - ".tscn": PackedScene, - ".tres": Theme, - ".gd": GDScript, - - # Fonts - ".ttf": FontFile, - ".otf": FontFile, - ".woff": FontFile, - ".woff2": FontFile, - - # Images - ".png": Image, - ".jpg": Image, - ".jpeg": Image, - ".svg": Image, - ".ktv": Image, - ".tga": Image, - ".webp": Image, -} -## The resource cache -var resource_cache: Dictionary = {} - -## Loads a resource. Supports native and dynamic resource loading. +## Loads a resource. Uses the [param resourceloader] module. func load_resource(path: String) -> Resource: - logger.diag("Loading resource located at " + path) - var resource: Resource = null - - # Check if path exists - if !FileAccess.file_exists(config_load_path + path): - await logger.crash("Loading file failed: File does not exist") - - # Check if found in cache - if resource_cache.has(path): - return resource_cache[path] - - # Load resource - if config_load_native: resource = load(config_load_path + path) - else: resource = await _load_resource_handler(path) - - # Check if null - await _load_resource_nullcheck(path, resource) - - # Add to cache - resource_cache.merge({ path: resource }) - - return resource - -## Handles dynamic resource loading using format loaders ([member format_loaders]). -func _load_resource_handler(path: String) -> Resource: - var resource: Resource = null - var error: Error = Error.OK - var type: Resource = null - - for extension in format_loaders: - if resource.ends_with(extension): - type = format_loaders[extension] - break - - # Resource loading - match(type): - PackedScene, Theme, GDScript: resource = ResourceLoader.load(config_load_path + path, "", ResourceLoader.CACHE_MODE_IGNORE) - FontFile: - resource = FontFile.new() - error = resource.load_dynamic_font(path) - Image: resource = Image.load_from_file(path) - _: await logger.crash("No format loader available for resource located at " + path) - - # Check if failed - await _load_resource_nullcheck(path, resource) - - if error != Error.OK: - await logger.crash(core.misc.stringify_variables("Loading file located at %path% failed: %error_string% (%error%)", { "path": path, "error": error, "error_string": error_string(error) })) - - # Resource processing - match(type): - PackedScene: - if resource.can_instantiate(): resource = resource.instantiate() - else: await logger.crash(core.misc.stringify_variables("Loading file located at %path% failed: Can't instantiate empty scene", { "path": path })) - - return resource - -## Simply crashes the app/game if the specified resource is [code]null[/code]. -func _load_resource_nullcheck(path: String, resource: Resource) -> void: - if resource == null: - await logger.crash(core.misc.stringify_variables("Loading file located at %path% failed: 'resource' is null", { "path": path })) + return resourceloader.load_resource(path) diff --git a/addons/venus/src/modules/resourceloader.gd b/addons/venus/src/modules/resourceloader.gd new file mode 100644 index 0000000..8a7047c --- /dev/null +++ b/addons/venus/src/modules/resourceloader.gd @@ -0,0 +1,113 @@ +# STAROPENSOURCE CORE MODULES SOURCE FILE +# Copyright (c) 2024 The StarOpenSource Project & 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 . + +## Loads resources natively (using [method @GDScript.load]) or dynamically (custom implementation) from user:// or the file system. +extends CoreBaseModule + +## Loads resources using [method @GDScript.load] ([code]== true[/code]) or using Venus' dynamic resource loading implementation ([code]== false[/code]). +var config_load_native: bool = true +## The path to load resources from. Use [code]res://[/code] if [member config_load_native] is set to [code]true[/code] or some other path if set to [code]false[/code]. +var config_load_path: String = "res://" + +## A list of all format loaders +var format_loaders: Dictionary = { + # Godot file types + ".tscn": PackedScene, + ".tres": Theme, + ".gd": GDScript, + + # Fonts + ".ttf": FontFile, + ".otf": FontFile, + ".woff": FontFile, + ".woff2": FontFile, + + # Images + ".png": Image, + ".jpg": Image, + ".jpeg": Image, + ".svg": Image, + ".ktv": Image, + ".tga": Image, + ".webp": Image, +} +## The resource cache +var resource_cache: Dictionary = {} + +## Loads a resource. Supports native and dynamic resource loading. +func load_resource(path: String) -> Resource: + logger.diag("Loading resource located at " + path) + var resource: Resource = null + + # Check if path exists + if !FileAccess.file_exists(config_load_path + path): + await logger.crash("Loading file failed: File does not exist") + + # Check if found in cache + if resource_cache.has(path): + return resource_cache[path] + + # Load resource + if config_load_native: resource = load(config_load_path + path) + else: resource = await _load_resource_handler(path) + + # Check if null + await _load_resource_nullcheck(path, resource) + + # Add to cache + resource_cache.merge({ path: resource }) + + return resource + +## Handles dynamic resource loading using format loaders ([member format_loaders]). +func _load_resource_handler(path: String) -> Resource: + var resource: Resource = null + var error: Error = Error.OK + var type: Resource = null + + for extension in format_loaders: + if resource.ends_with(extension): + type = format_loaders[extension] + break + + # Resource loading + match(type): + PackedScene, Theme, GDScript: resource = ResourceLoader.load(config_load_path + path, "", ResourceLoader.CACHE_MODE_IGNORE) + FontFile: + resource = FontFile.new() + error = resource.load_dynamic_font(path) + Image: resource = Image.load_from_file(path) + _: await logger.crash("No format loader available for resource located at " + path) + + # Check if failed + await _load_resource_nullcheck(path, resource) + + if error != Error.OK: + await logger.crash(core.misc.stringify_variables("Loading file located at %path% failed: %error_string% (%error%)", { "path": path, "error": error, "error_string": error_string(error) })) + + # Resource processing + match(type): + PackedScene: + if resource.can_instantiate(): resource = resource.instantiate() + else: await logger.crash(core.misc.stringify_variables("Loading file located at %path% failed: Can't instantiate empty scene", { "path": path })) + + return resource + +## Simply crashes the app/game if the specified resource is [code]null[/code]. +func _load_resource_nullcheck(path: String, resource: Resource) -> void: + if resource == null: + await logger.crash(core.misc.stringify_variables("Loading file located at %path% failed: 'resource' is null", { "path": path }))