diff --git a/addons/venus/src/manager.gd b/addons/venus/src/manager.gd index 3a1d824..84eb572 100644 --- a/addons/venus/src/manager.gd +++ b/addons/venus/src/manager.gd @@ -21,7 +21,7 @@ var core: Core var logger: CoreLoggerInstance var path: String = "addons/venus/src" -var modules: Dictionary = { "standard": [ "splashes" ], "sui": [] } +var modules: Dictionary = { "standard": [ "splashes", "launcher" ], "sui": [] } func _init(core_new: Core) -> void: name = "Venus manager" diff --git a/addons/venus/src/modules/launcher.gd b/addons/venus/src/modules/launcher.gd new file mode 100644 index 0000000..c47111f --- /dev/null +++ b/addons/venus/src/modules/launcher.gd @@ -0,0 +1,111 @@ +# 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 . +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 })) diff --git a/addons/venus/src/modules/splashes.gd b/addons/venus/src/modules/splashes.gd index cbf2604..0b0a8d9 100644 --- a/addons/venus/src/modules/splashes.gd +++ b/addons/venus/src/modules/splashes.gd @@ -16,6 +16,7 @@ # along with this program. If not, see . extends CoreBaseModule +## Contains all categories and their splashes var splashes: Dictionary = {} # +++ module +++ diff --git a/project.godot b/project.godot index 74321d5..765d922 100644 --- a/project.godot +++ b/project.godot @@ -22,10 +22,18 @@ boot_splash/bg_color=Color(0, 0, 0, 1) window/size/viewport_width=1440 window/size/viewport_height=810 +[editor] + +export/convert_text_resources_to_binary=false + [editor_plugins] enabled=PackedStringArray("res://addons/SUI/plugin.cfg", "res://addons/venus/plugin.cfg") +[filesystem] + +import/blender/enabled=false + [rendering] renderer/rendering_method="gl_compatibility"