Move shared code into seperate class

This commit is contained in:
JeremyStar™ 2024-05-18 19:03:58 +02:00
parent 37b08bd681
commit 0b54bebe92
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
3 changed files with 125 additions and 89 deletions

View file

@ -23,31 +23,30 @@ var logger: CoreLoggerInstance
var sms: CoreBaseModule var sms: CoreBaseModule
# Presencode infrastructure # Presencode infrastructure
var presenloader: Node var shared: PresencodeSharedCode
var clickoverlay: Button = Button.new() var clickoverlay: Button = Button.new()
# Presentation data # Presentation data
var entrypoint: PresencodeEntrypoint
var manifest: Dictionary
var current_slide: int = 0 var current_slide: int = 0
var slide_switch_in_progress: bool = false var slide_switch_in_progress: bool = false
# +++ initialization and processing +++ # +++ initialization and processing +++
func _init(core_new: Core, presenloader_new: Node) -> void: func _init(core_new: Core, shared_new: PresencodeSharedCode) -> void:
name = "Communication" name = "Communication"
core = core_new core = core_new
logger = core.logger.get_instance("src/classes/communication.gd", self) logger = core.logger.get_instance("src/classes/communication.gd", self)
sms = core.sms sms = core.sms
presenloader = presenloader_new shared = shared_new
clickoverlay.name = "Click Overlay" clickoverlay.name = "Click Overlay"
clickoverlay.size = Vector2(100000.0, 100000.0) clickoverlay.size = Vector2(100000.0, 100000.0)
clickoverlay.position = -Vector2(50000.5, 50000.5) clickoverlay.position = -Vector2(50000.5, 50000.5)
clickoverlay.modulate = Color(1, 1, 1, 0) clickoverlay.modulate = Color(1, 1, 1, 0)
clickoverlay.connect("pressed", func() -> void: clickoverlay.connect("pressed", func() -> void:
logger.diag("Navigating to next slide") logger.diag("Navigating to next slide")
switch_slide(current_slide + 1) await switch_slide(current_slide + 1)
) )
func _ready() -> void: func _ready() -> void:
@ -64,15 +63,10 @@ func _process(_delta: float) -> void:
_: DisplayServer.window_set_mode(DisplayServer.WindowMode.WINDOW_MODE_WINDOWED) _: DisplayServer.window_set_mode(DisplayServer.WindowMode.WINDOW_MODE_WINDOWED)
if Input.is_action_just_pressed("navigate_forwards"): if Input.is_action_just_pressed("navigate_forwards"):
logger.diag("Navigating to next slide") logger.diag("Navigating to next slide")
switch_slide(current_slide + 1) await switch_slide(current_slide + 1)
if Input.is_action_just_pressed("navigate_backwards"): if Input.is_action_just_pressed("navigate_backwards"):
logger.diag("Navigating to previous slide") logger.diag("Navigating to previous slide")
switch_slide(current_slide - 1) await switch_slide(current_slide - 1)
func _update_variables() -> void:
logger.diag("Updating variables")
entrypoint = presenloader.entrypoint_node
manifest = presenloader.manifest
# +++ slide management +++ # +++ slide management +++
func switch_slide(new_slide: int) -> PresencodeTypes.PresencodeError: func switch_slide(new_slide: int) -> PresencodeTypes.PresencodeError:
@ -84,26 +78,27 @@ func switch_slide(new_slide: int) -> PresencodeTypes.PresencodeError:
logger.error(core.misc.stringify_variables("Invalid slide %slide%", { "slide": new_slide })) logger.error(core.misc.stringify_variables("Invalid slide %slide%", { "slide": new_slide }))
slide_switch_in_progress = false slide_switch_in_progress = false
return PresencodeTypes.PresencodeError.INVALID_SLIDE return PresencodeTypes.PresencodeError.INVALID_SLIDE
if new_slide > manifest["slides"]: if new_slide > shared.manifest["slides"]:
logger.error(core.misc.stringify_variables("Invalid slide %slide%", { "slide": new_slide })) logger.error(core.misc.stringify_variables("Invalid slide %slide%", { "slide": new_slide }))
slide_switch_in_progress = false slide_switch_in_progress = false
return PresencodeTypes.PresencodeError.INVALID_SLIDE return PresencodeTypes.PresencodeError.INVALID_SLIDE
logger.info(core.misc.stringify_variables("Switching from slide %old% to %new%", { "old": old_slide, "new": new_slide })) logger.info(core.misc.stringify_variables("Switching from slide %old% to %new%", { "old": old_slide, "new": new_slide }))
await get_tree().process_frame # Prevents graphical glitches
# Play BEFORE animation # Play BEFORE animation
if manifest["animations"]: if shared.manifest["animations"]:
logger.verb("Starting BEFORE animation") logger.verb("Starting BEFORE animation")
await entrypoint.play_animation(PresencodeTypes.AnimationStage.BEFORE, old_slide, new_slide) await shared.entrypoint.play_animation(PresencodeTypes.AnimationStage.BEFORE, old_slide, new_slide)
# Call switch_slide() # Call switch_to_slide()
logger.verb("Switching slide") logger.verb("Switching slide")
await entrypoint.switch_to_slide(new_slide) await shared.entrypoint.switch_to_slide(new_slide)
# Play AFTER animation # Play AFTER animation
if manifest["animations"]: if shared.manifest["animations"]:
logger.verb("Starting AFTER animation") logger.verb("Starting AFTER animation")
await entrypoint.play_animation(PresencodeTypes.AnimationStage.AFTER, old_slide, new_slide) await shared.entrypoint.play_animation(PresencodeTypes.AnimationStage.AFTER, old_slide, new_slide)
current_slide = new_slide current_slide = new_slide
slide_switch_in_progress = false slide_switch_in_progress = false
@ -132,23 +127,23 @@ func load_resource(path: String):
var load_path: String var load_path: String
if presenloader.is_file: if shared.is_file:
# Check if file exists # Check if file exists
if !presenloader.reader.file_exists(path): if !shared.reader.file_exists(path):
await logger.crash(core.misc.stringify_variables("File path %path% could not be located inside presentation archive", { "path": path })) await logger.crash(core.misc.stringify_variables("File path %path% could not be located inside presentation archive", { "path": path }))
# Write into temporary file # Write into temporary file
presenloader.write_temporary_file(presenloader.reader.read_file(path)) shared.write_temporary_file(shared.reader.read_file(path))
# Update 'load_path' # Update 'load_path'
load_path = presenloader.temporary_file load_path = shared.temporary_file
else: else:
# Check if file exists # Check if file exists
if !FileAccess.file_exists(presenloader.path + "/" + path): if !FileAccess.file_exists(shared.path + "/" + path):
await logger.crash(core.misc.stringify_variables("File path %path% could not be located inside presentation directory (full path is %path_full%)", { "path": path, "path_full": presenloader.path + "/" + path })) await logger.crash(core.misc.stringify_variables("File path %path% could not be located inside presentation directory (full path is %path_full%)", { "path": path, "path_full": shared.path + "/" + path }))
# Update 'load_path' # Update 'load_path'
load_path = presenloader.path + "/" + path load_path = shared.path + "/" + path
# Load resource from temporary file # Load resource from temporary file
var resource = _load_resource_format_loader(load_path, path) var resource = _load_resource_format_loader(load_path, path)

63
src/classes/shared.gd Normal file
View file

@ -0,0 +1,63 @@
# PRESENCODE SOURCE FILE
# Copyright (c) 2024 JeremyStarTM & 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 <https://www.gnu.org/licenses/>.
extends Node
class_name PresencodeSharedCode
var core: Core
var logger: CoreLoggerInstance
const temporary_file: String = "user://temporary_file"
var reader: ZIPReader
var diraccess: DirAccess
var is_file: bool
var path: String
var entrypoint: Node
var manifest: Dictionary
# +++ initialization +++
func _init(core_new: Core, is_file_new: bool, path_new: String, diraccess_new: DirAccess) -> void:
core = core_new
logger = core.logger.get_instance("src/classes/shared.gd", self)
reader = ZIPReader.new()
diraccess = diraccess_new
is_file = is_file_new
path = path_new
func add_presentation_data(entrypoint_new: Node, manifest_new: Dictionary) -> void:
entrypoint = entrypoint_new
manifest = manifest_new
# +++ etc +++
func write_temporary_file(bytes: PackedByteArray) -> void:
# Check if exists, if so delete the file
if FileAccess.file_exists(temporary_file):
logger.diag("Removing temporary file")
# Open
var file: FileAccess = FileAccess.open(temporary_file, FileAccess.WRITE)
if file == null:
await logger.crash(core.misc.stringify_variables("Can't write temporary file: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) }))
# Write
file.store_buffer(bytes)
# Close
file.close()

View file

@ -18,33 +18,24 @@ extends Node
const version: int = 1 const version: int = 1
const version_float: float = float(version) const version_float: float = float(version)
const temporary_file: String = "user://temporary_file"
@onready var core: Core = get_node("/root/CORE") @onready var core: Core = get_node("/root/CORE")
@onready var logger: CoreLoggerInstance = core.logger.get_instance("src/presenloader.gd", self) @onready var logger: CoreLoggerInstance = core.logger.get_instance("src/presenloader.gd", self)
var path: String = "" var shared: PresencodeSharedCode
var is_file: bool = true var communication: PresencodeCommunication
var manifest: Dictionary = {}
var entrypoint: Script = null var entrypoint: Script = null
var entrypoint_node: PresencodeEntrypoint = null
@onready var communication: PresencodeCommunication = PresencodeCommunication.new(core, self)
var reader: ZIPReader = ZIPReader.new()
var diraccess: DirAccess = null
func _ready() -> void: func _ready() -> void:
# Register cleanup hook # Register cleanup hook
core.register_cleanup_hook(func() -> void: queue_free()) core.register_cleanup_hook(func() -> void: queue_free())
# Add 'communication' as a child
add_child(communication)
func load_presentation(load_path: String) -> String: func load_presentation(load_path: String) -> String:
logger.info(core.misc.stringify_variables("Loading presentation located at %path%", { "path": load_path })) logger.info(core.misc.stringify_variables("Loading presentation located at %path%", { "path": load_path }))
path = load_path var path = load_path
is_file = FileAccess.file_exists(path) var is_file = FileAccess.file_exists(path)
var diraccess: DirAccess = null
# Check if exists # Check if exists
logger.verb("Checking if presentation exists") logger.verb("Checking if presentation exists")
@ -60,7 +51,7 @@ func load_presentation(load_path: String) -> String:
# Open archive # Open archive
logger.verb("Opening archive") logger.verb("Opening archive")
var error: Error = reader.open(path) var error: Error = shared.reader.open(path)
if error != Error.OK: if error != Error.OK:
return core.misc.stringify_variables("Can't open ZIP archive: %error_string% (%error%)", { "error": error, "error_string": error_string(error) }, true) return core.misc.stringify_variables("Can't open ZIP archive: %error_string% (%error%)", { "error": error, "error_string": error_string(error) }, true)
else: else:
@ -70,6 +61,9 @@ func load_presentation(load_path: String) -> String:
if diraccess == null: 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) 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)
# Update 'shared'
shared = PresencodeSharedCode.new(core, is_file, path, diraccess)
# Check if required files are present # Check if required files are present
var output: String = check_required_files() var output: String = check_required_files()
if output != "": return output if output != "": return output
@ -90,12 +84,13 @@ func load_presentation(load_path: String) -> String:
output = load_entrypoint() output = load_entrypoint()
if output != "": return output if output != "": return output
# Create 'communication'
communication = PresencodeCommunication.new(core, shared)
add_child(communication)
# Inject entrypoint # Inject entrypoint
inject_entrypoint() inject_entrypoint()
# Update 'communication''s variables
communication._update_variables()
return "" return ""
func check_required_files() -> String: func check_required_files() -> String:
@ -105,11 +100,11 @@ func check_required_files() -> String:
var files: PackedStringArray = PackedStringArray([]) var files: PackedStringArray = PackedStringArray([])
# Update 'files' appropriately # Update 'files' appropriately
if is_file: if shared.is_file:
files = reader.get_files() files = shared.reader.get_files()
else: else:
files = diraccess.get_files() files = shared.diraccess.get_files()
for directory in diraccess.get_directories(): for directory in shared.diraccess.get_directories():
files.append(directory + "/") files.append(directory + "/")
# Iterate through files and directories # Iterate through files and directories
@ -132,9 +127,9 @@ func parse_manifest() -> String:
logger.verb("Parsing manifest") logger.verb("Parsing manifest")
var manifest_raw: String = "" var manifest_raw: String = ""
if is_file: manifest_raw = reader.read_file("manifest.json").get_string_from_utf8() if shared.is_file: manifest_raw = shared.reader.read_file("manifest.json").get_string_from_utf8()
else: else:
var file: FileAccess = FileAccess.open(path + "/manifest.json", FileAccess.READ) var file: FileAccess = FileAccess.open(shared.path + "/manifest.json", FileAccess.READ)
if file == null: if file == null:
return core.misc.stringify_variables("Can't read manifest: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) }) return core.misc.stringify_variables("Can't read manifest: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) })
manifest_raw = file.get_as_text() manifest_raw = file.get_as_text()
@ -147,7 +142,7 @@ func parse_manifest() -> String:
if typeof(json.data) != Variant.Type.TYPE_DICTIONARY: if typeof(json.data) != Variant.Type.TYPE_DICTIONARY:
return core.misc.stringify_variables("Can't parse manifest: Parsed manifest is not of type Dictionary but instead %type%", { "type": type_string(typeof(json.data)) }) return core.misc.stringify_variables("Can't parse manifest: Parsed manifest is not of type Dictionary but instead %type%", { "type": type_string(typeof(json.data)) })
manifest = json.data shared.manifest = json.data
return "" return ""
@ -179,7 +174,7 @@ func check_manifest() -> Array[String]:
"slides": core.validation.get_single_schema(self).matches_type([ Variant.Type.TYPE_FLOAT ]).has_minimum_float(1.0), "slides": core.validation.get_single_schema(self).matches_type([ Variant.Type.TYPE_FLOAT ]).has_minimum_float(1.0),
"animations": core.validation.get_single_schema(self).matches_type([ Variant.Type.TYPE_BOOL ]), "animations": core.validation.get_single_schema(self).matches_type([ Variant.Type.TYPE_BOOL ]),
"display_end_text_after_last_slide": core.validation.get_single_schema(self).matches_type([ Variant.Type.TYPE_BOOL ]) "display_end_text_after_last_slide": core.validation.get_single_schema(self).matches_type([ Variant.Type.TYPE_BOOL ])
}, manifest, self) }, shared.manifest, self)
return schema.evaluate() return schema.evaluate()
@ -189,16 +184,16 @@ func validate_entrypoint() -> String:
var content: String = "" var content: String = ""
# Get entrypoint content # Get entrypoint content
if is_file: if shared.is_file:
if !reader.file_exists("src/" + manifest["entrypoint"]): if !shared.reader.file_exists("src/" + shared.manifest["entrypoint"]):
return "Specified entrypoint file could not be located at src/" + manifest["entrypoint"] return "Specified entrypoint file could not be located at src/" + shared.manifest["entrypoint"]
content = reader.read_file("src/" + manifest["entrypoint"]).get_string_from_utf8() content = shared.reader.read_file("src/" + shared.manifest["entrypoint"]).get_string_from_utf8()
else: else:
if !FileAccess.file_exists(path + "/src/" + manifest["entrypoint"]): if !FileAccess.file_exists(shared.path + "/src/" + shared.manifest["entrypoint"]):
return "Specified entrypoint file could not be located at src/" + manifest["entrypoint"] return "Specified entrypoint file could not be located at src/" + shared.manifest["entrypoint"]
var file: FileAccess = FileAccess.open(path + "/src/" + manifest["entrypoint"], FileAccess.READ) var file: FileAccess = FileAccess.open(shared.path + "/src/" + shared.manifest["entrypoint"], FileAccess.READ)
if file == null: if file == null:
return core.misc.stringify_variables("Can't read entrypoint: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) }) return core.misc.stringify_variables("Can't read entrypoint: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) })
content = file.get_as_text() content = file.get_as_text()
@ -213,15 +208,15 @@ func validate_entrypoint() -> String:
func load_entrypoint() -> String: func load_entrypoint() -> String:
logger.verb("Loading entrypoint") logger.verb("Loading entrypoint")
if is_file: if shared.is_file:
# Workaround (we can't load resources from buffer. why? idk) # Workaround (we can't load resources from buffer. why? idk)
# -> Remove temporary file (if exists) # -> Remove temporary file (if exists)
write_temporary_file(reader.read_file("src/" + manifest["entrypoint"])) shared.write_temporary_file(shared.reader.read_file("src/" + shared.manifest["entrypoint"]))
# -> Load temporary file # -> Load temporary file
entrypoint = ResourceLoader.load(temporary_file) entrypoint = ResourceLoader.load(shared.temporary_file)
else: else:
# Load entrypoint # Load entrypoint
entrypoint = ResourceLoader.load(path + "/src/" + manifest["entrypoint"]) entrypoint = ResourceLoader.load(shared.path + "/src/" + shared.manifest["entrypoint"])
return "" return ""
@ -229,34 +224,17 @@ func inject_entrypoint() -> void:
logger.verb("Injecting entrypoint") logger.verb("Injecting entrypoint")
# Instantiate new PresencodeEntrypoint # Instantiate new PresencodeEntrypoint
entrypoint_node = PresencodeEntrypoint.new() shared.entrypoint = PresencodeEntrypoint.new()
entrypoint_node.name = "Entrypoint" shared.entrypoint.name = "Entrypoint"
entrypoint_node.set_script(entrypoint) shared.entrypoint.set_script(entrypoint)
# Update variables # Update variables
entrypoint_node.core = core shared.entrypoint.core = core
entrypoint_node.logger = core.logger.get_instance(communication.get_source_path("src/" + manifest["entrypoint"]), entrypoint_node) shared.entrypoint.logger = core.logger.get_instance(communication.get_source_path("src/" + shared.manifest["entrypoint"]), shared.entrypoint)
entrypoint_node.api = communication shared.entrypoint.api = communication
# Add to SceneTree # Add to SceneTree
get_tree().root.add_child.call_deferred(entrypoint_node) get_tree().root.add_child.call_deferred(shared.entrypoint)
# Execute initialize() # Execute initialize()
entrypoint_node.initialize.call_deferred() shared.entrypoint.initialize.call_deferred()
# +++ etc +++
func write_temporary_file(bytes: PackedByteArray) -> void:
# Check if exists, if so delete the file
if FileAccess.file_exists(temporary_file):
logger.diag("Removing temporary file")
# Open
var file: FileAccess = FileAccess.open(temporary_file, FileAccess.WRITE)
if file == null:
await logger.crash(core.misc.stringify_variables("Can't write temporary file: %error_string% (%error%)", { "error": FileAccess.get_open_error(), "error_string": error_string(FileAccess.get_open_error()) }))
# Write
file.store_buffer(bytes)
# Close
file.close()