diff --git a/src/presenloader.gd b/src/presenloader.gd index 5c5c0f2..f1ce5cb 100644 --- a/src/presenloader.gd +++ b/src/presenloader.gd @@ -28,6 +28,7 @@ const version_float: float = float(version) var path: String = "" var is_file: bool = true var manifest: Dictionary = {} +var entrypoint: Script = null # Access methods var reader: ZIPReader = ZIPReader.new() @@ -68,21 +69,30 @@ func load_presentation(load_path: String) -> String: if diraccess == null: return core.misc.stringify_variables("Can't open directory: %error_string% (%error%)", { "error": DirAccess.get_open_error(), "error_string": error_string(DirAccess.get_open_error()) }, true) + # Check if required files are present var output: String = check_required_files() if output != "": return output + # Parse manifest.json output = parse_manifest() if output != "": return output + # Validate manifest.json var output_array: Array[String] = check_manifest() if output_array != []: return core.misc.format_stringarray(output_array, "- ", "", "\n", "\n") + # Load and inject entrypoint + output = load_entrypoint() + if output != "": return output + + inject_entrypoint() + return "" func check_required_files() -> String: logger.verb("Checking for required files") # Define variables - var files_present: Dictionary = { "manifest": false, "slides": false } + var files_present: Dictionary = { "manifest": false, "slides": false, "src": false } var files: PackedStringArray = PackedStringArray([]) # Update 'files' appropriately @@ -97,7 +107,7 @@ func check_required_files() -> String: for file in files: if file == "manifest.json": files_present["manifest"] = true elif file.begins_with("slides/"): files_present["slides"] = true - elif file.begins_with("src/"): pass + elif file.begins_with("src/"): files_present["src"] = true elif file.begins_with("assets/"): pass else: logger.warn(core.misc.stringify_variables("Unknown file/directory %file% inside presentation directory, ignoring", { "file": file })) @@ -105,6 +115,7 @@ func check_required_files() -> String: if !files_present["manifest"]: return "The presentation manifest is missing. Make sure it is named 'manifest.json'" if !files_present["slides"]: return "The 'slides' directory is missing. You can't have a presentation without slides, dingus!" + if !files_present["src"]: return "The 'src' directory is missing. You can't have a code-based presentation without code, dingus!" return "" @@ -162,3 +173,43 @@ func check_manifest() -> Array[String]: }, manifest, self) return schema.evaluate() + +func load_entrypoint() -> String: + logger.verb("Loading entrypoint") + + if is_file: + if !reader.file_exists("src/" + manifest["entrypoint"]): + return "Specified entrypoint file could not be located at src/" + manifest["entrypoint"] + + # Workaround (we can't load resources from buffer. why? idk) + # -> Remove temporary file (if exists) + if FileAccess.file_exists("user://entrypoint.gd"): + DirAccess.remove_absolute("user://entrypoint.gd") + # -> Write entrypoint file (buffer from ZIPReader) into temporary file + var file: FileAccess = FileAccess.open("user://entrypoint.gd", FileAccess.WRITE) + if file == null: + return core.misc.stringify_variables("Can't write temporary entrypoint: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) }) + file.store_buffer(reader.read_file("src/" + manifest["entrypoint"])) + file.close() + # -> Load temporary file + entrypoint = ResourceLoader.load("user://entrypoint.gd") + else: + if !FileAccess.file_exists(path + "/src/" + manifest["entrypoint"]): + return "Specified entrypoint file could not be located at src/" + manifest["entrypoint"] + + # Load entrypoint + entrypoint = ResourceLoader.load(path + "/src/" + manifest["entrypoint"]) + + return "" + +func inject_entrypoint() -> void: + logger.verb("Injecting entrypoint") + + # Instantiate new Node + var entrypoint_node: Node = Node.new() + # Give the new node a name and the entrypoint script + entrypoint_node.name = "Entrypoint" + entrypoint_node.set_script(entrypoint) + + # Add to SceneTree + get_tree().root.add_child(entrypoint_node)