From 60d9f614eea972266eff57e224af39ae18c468a2 Mon Sep 17 00:00:00 2001 From: Vaillant Jeremy Date: Sat, 16 May 2026 21:50:00 +0200 Subject: [PATCH] Replace Event + GlobalAnimation autoloads with class_name + static funcs Two of the five autoloads were stateless helper bundles, not the persistent application-wide systems that the Godot 4 best-practice guide reserves autoload slots for. Convert them to plain classes with all-static methods so they no longer need a Node living under /root. - scripts/Animation.gd -> scripts/game_animation.gd (renamed: conflict with the built-in Animation class; the autoload sidestepped it by being called GlobalAnimation). class_name GameAnimation, every helper static. The dissolve tween now captures its target material in a lambda closure, eliminating the current_material member that the autoload kept as shared mutable state. - scripts/Event.gd -> scripts/event.gd, class_name Event, every handler static. Added Event.level_pressed(name) -> Callable for the one place ChooseScene needed dynamic lookup of a per-level handler (replaces the old _build_method('_on_' + name + '_pressed') + Callable(autoload, string) reflection trick with an explicit match). Updated call sites: - scripts/Global.gd: animation.connect('animation_started', Callable(Event, '...')) -> animation.animation_started.connect( Event._loading_is_started). Same for animation_finished. - scenes/levels/Levels.gd: GlobalAnimation.* -> GameAnimation.*; Quit/TextureButton.connect('pressed', Callable(Event, '...')) -> pressed.connect(Event._on_main_scene_pressed). - scenes/UI/choose_scenes/ChooseScene.gd: per-level button connects go through Event.level_pressed(); reset button's bound callable now reads Event._on_reset_level.bind(...); cleanup no longer relies on is_connected with an unbound Callable (which would never match a bound one anyway) -- iterates reset.pressed.get_connections() instead. Drop the now-dead _build_method helper. Also: organise scripts/ by promoting the one-shot migration helpers (migrate_shaders, migrate_misc, resave_scenes, devisualize_shaders, find_visualshaders) into scripts/migration/. They are not part of the runtime and should not be browsable next to the autoloads. Autoload count goes 5 -> 3 (Loading, Global, Setting remain -- Setting will move to a Resource in a later refactor). Co-Authored-By: Claude Opus 4.7 (1M context) --- project.godot | 2 - scenes/UI/choose_scenes/ChooseScene.gd | 13 +++--- scenes/levels/Levels.gd | 8 ++-- scripts/Animation.gd | 43 ------------------- scripts/Animation.gd.uid | 1 - scripts/Event.gd | 33 -------------- scripts/Event.gd.uid | 1 - scripts/Global.gd | 4 +- scripts/event.gd | 42 ++++++++++++++++++ scripts/event.gd.uid | 1 + scripts/game_animation.gd | 37 ++++++++++++++++ scripts/game_animation.gd.uid | 1 + .../{ => migration}/devisualize_shaders.gd | 0 .../devisualize_shaders.gd.uid | 0 scripts/{ => migration}/find_visualshaders.gd | 0 .../{ => migration}/find_visualshaders.gd.uid | 0 scripts/{ => migration}/migrate_misc.gd | 0 scripts/{ => migration}/migrate_misc.gd.uid | 0 scripts/{ => migration}/migrate_shaders.gd | 0 .../{ => migration}/migrate_shaders.gd.uid | 0 scripts/{ => migration}/resave_scenes.gd | 0 scripts/{ => migration}/resave_scenes.gd.uid | 0 22 files changed, 93 insertions(+), 93 deletions(-) delete mode 100644 scripts/Animation.gd delete mode 100644 scripts/Animation.gd.uid delete mode 100644 scripts/Event.gd delete mode 100644 scripts/Event.gd.uid create mode 100644 scripts/event.gd create mode 100644 scripts/event.gd.uid create mode 100644 scripts/game_animation.gd create mode 100644 scripts/game_animation.gd.uid rename scripts/{ => migration}/devisualize_shaders.gd (100%) rename scripts/{ => migration}/devisualize_shaders.gd.uid (100%) rename scripts/{ => migration}/find_visualshaders.gd (100%) rename scripts/{ => migration}/find_visualshaders.gd.uid (100%) rename scripts/{ => migration}/migrate_misc.gd (100%) rename scripts/{ => migration}/migrate_misc.gd.uid (100%) rename scripts/{ => migration}/migrate_shaders.gd (100%) rename scripts/{ => migration}/migrate_shaders.gd.uid (100%) rename scripts/{ => migration}/resave_scenes.gd (100%) rename scripts/{ => migration}/resave_scenes.gd.uid (100%) diff --git a/project.godot b/project.godot index 5a4fb6d..2947eda 100644 --- a/project.godot +++ b/project.godot @@ -26,8 +26,6 @@ config/windows_native_icon="res://releases/windows/project.ico" Loading="*res://scenes/UI/loading/Loading.tscn" Global="*res://scripts/Global.gd" Setting="*res://scripts/Setting.gd" -Event="*res://scripts/Event.gd" -GlobalAnimation="*res://scripts/Animation.gd" [display] diff --git a/scenes/UI/choose_scenes/ChooseScene.gd b/scenes/UI/choose_scenes/ChooseScene.gd index 7b1ae44..8ce99f7 100644 --- a/scenes/UI/choose_scenes/ChooseScene.gd +++ b/scenes/UI/choose_scenes/ChooseScene.gd @@ -27,9 +27,6 @@ func _load_scene(p_name): func _build_path(p_name): return "MarginContainer/" + p_name -func _build_method(p_name): - return "_on_" + p_name.to_lower() + "_pressed" - func _load_texture(thumbnail): return load(thumbnail) @@ -38,7 +35,9 @@ func _configure_select(level, node): var thumbnail = get_node(node+"/MarginContainer/CenterAlign/MainButton/MarginStich/ThumbnailLevel") thumbnail.set_texture(_load_texture(level.thumbnail())) - selector.connect("pressed", Callable(Event, _build_method(level.name()))) + var handler = Event.level_pressed(level.name()) + if handler.is_valid(): + selector.pressed.connect(handler) func configure_reset(level, node, index, animate): var reset = get_node(node+"/MarginContainer/CenterAlign/MainButton/TabAlign/ButtonReset") @@ -55,14 +54,14 @@ func _configure_reset_disable(animation, reset, animate = false): reset.set_disabled(true) reset.set_default_cursor_shape(CURSOR_ARROW) - if reset.is_connected("pressed", Callable(Event, "_on_reset_level")): - reset.disconnect("pressed", Callable(Event, "_on_reset_level")) + for c in reset.pressed.get_connections(): + reset.pressed.disconnect(c["callable"]) func _configure_reset_enable(animation, reset, level, node, index): animation.play_backwards("SlideReset") reset.set_disabled(false) reset.set_default_cursor_shape(CURSOR_POINTING_HAND) - reset.connect("pressed", Callable(Event, "_on_reset_level").bind(level, node, index, self)) + reset.pressed.connect(Event._on_reset_level.bind(level, node, index, self)) func configure_counter(level, node): var count = get_node(node+"/MarginContainer/CenterAlign/MainButton/TabAlign/ButtonCount/MarginBottom/Label") diff --git a/scenes/levels/Levels.gd b/scenes/levels/Levels.gd index 5e8f526..e627a45 100644 --- a/scenes/levels/Levels.gd +++ b/scenes/levels/Levels.gd @@ -44,7 +44,7 @@ func _load_meshes(): create_dissolve_mesh(scene_detail.key()) func _load_back_button(): - var _back = $Quit/TextureButton.connect("pressed", Callable(Event, "_on_main_scene_pressed")) + $Quit/TextureButton.pressed.connect(Event._on_main_scene_pressed) func _load_prepare_victory_condition(): var level = mlevel.new(Global.current_scene_int) @@ -102,10 +102,10 @@ func _configure_button_object(button, scene, label): button.set_meta("counted", 0) func _create_animation_slide(node, p_name): - _add_animation_to_player(p_name, GlobalAnimation.level_hud_slide(node)) + _add_animation_to_player(p_name, GameAnimation.level_hud_slide(node)) func _create_animation_warning(node, p_name): - _add_animation_to_player(p_name, GlobalAnimation.level_hud_warning(node)) + _add_animation_to_player(p_name, GameAnimation.level_hud_warning(node)) func _add_animation_to_player(p_name: String, anim: Animation) -> void: var player = $ListObjects/AnimationPlayer @@ -139,7 +139,7 @@ func _check_dissolve_mesh(): if meshes[key].tick_reference() == 0: meshes[key].set_tick_reference(Time.get_ticks_msec()) _node_object_list(key) - GlobalAnimation.start_dissolve(mesh, mesh.get_active_material(0)) + GameAnimation.start_dissolve(mesh, mesh.get_active_material(0)) if Time.get_ticks_msec() < meshes[key].tick_reference() + TIME_MAX: meshes[key].set_value(meshes[key].value() + 0.01) diff --git a/scripts/Animation.gd b/scripts/Animation.gd deleted file mode 100644 index d9149ac..0000000 --- a/scripts/Animation.gd +++ /dev/null @@ -1,43 +0,0 @@ -extends Node - -var current_material = null - -func level_hud_slide(node): - var animation = Animation.new() - var track_index = animation.add_track(Animation.TYPE_BEZIER) - var node_element = str(node.get_path()) + ":position:x" - - animation.track_set_path(track_index, node_element) - animation.bezier_track_insert_key(track_index, 0.0, 0.0, Vector2(-0.25, 0), Vector2(0.031, 190.492)) - animation.bezier_track_insert_key(track_index, 1.0, 170, Vector2(-0.349, 2.576), Vector2(0.25, 0)) - - return animation - -func level_hud_warning(node): - var animation = Animation.new() - var track_index = animation.add_track(Animation.TYPE_BEZIER) - var node_element = str(node.get_path()) + ":position:x" - - animation.track_set_path(track_index, node_element) - animation.bezier_track_insert_key(track_index, 0.0, 0.0, Vector2(-0.25, 0), Vector2(0, 78.1)) - animation.bezier_track_insert_key(track_index, 0.2, 34.9, Vector2(-0.25, 0), Vector2(0, -66)) - animation.bezier_track_insert_key(track_index, 0.4, 12.1, Vector2(0, 73.2), Vector2(0, -124.8)) - animation.bezier_track_insert_key(track_index, 0.6, -41.9, Vector2(-0.095, 109.2), Vector2(0.062, -58.8)) - animation.bezier_track_insert_key(track_index, 0.8, 13.3, Vector2(-0.188, 93.6), Vector2(0.196, 104.4)) - animation.bezier_track_insert_key(track_index, 1.0, 0.0, Vector2(-0.155, -135.5), Vector2(0.25, 0)) - - return animation - -func start_dissolve(node, material): - if material == null: - return - current_material = material - var tween = node.create_tween() - tween.tween_method(animate_dissolve, 0.0, 1.0, 1.5) \ - .set_trans(Tween.TRANS_LINEAR) \ - .set_ease(Tween.EASE_IN_OUT) - -func animate_dissolve(progress: float) -> void: - if current_material == null: - return - current_material.set_shader_parameter("dissolve_amount", ease(progress, 0.4)) diff --git a/scripts/Animation.gd.uid b/scripts/Animation.gd.uid deleted file mode 100644 index 850b499..0000000 --- a/scripts/Animation.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cgxvdwn0bwwtp diff --git a/scripts/Event.gd b/scripts/Event.gd deleted file mode 100644 index 891c708..0000000 --- a/scripts/Event.gd +++ /dev/null @@ -1,33 +0,0 @@ -extends Node - -## Events for loading scene -#### -func _loading_is_started(_anim_name): - print("[Event#_loading_is_started]") - Global.loaded = false - -func _loading_is_finished(_anim_name): - print("[Evenst#_loading_is_finished]") - Global.loaded = true - -# Events for load scene level -#### -func _on_warcraft_pressed(): - Global.current_scene_int = 0 - Global.goto_scene("res://scenes/levels/warcraft/WarCraft.tscn") - -func _on_home_pressed(): - Global.current_scene_int = 1 - Global.goto_scene("res://scenes/levels/home/Home.tscn") - -func _on_reset_level(level, node, index, parent): - Global.current_scene_int = index - level.reset() - parent.configure_reset(level, node, index, true) - parent.configure_counter(level, node) - Global.current_scene_int = null - -# Events for back to main scene -#### -func _on_main_scene_pressed(): - Global.goto_scene("res://scenes/Main.tscn") diff --git a/scripts/Event.gd.uid b/scripts/Event.gd.uid deleted file mode 100644 index 0b0c02a..0000000 --- a/scripts/Event.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://besfv1ymjgw81 diff --git a/scripts/Global.gd b/scripts/Global.gd index f1948cd..71ef79e 100644 --- a/scripts/Global.gd +++ b/scripts/Global.gd @@ -16,8 +16,8 @@ func _ready(): _initialize_loading_scene() func _initialize_loading_scene(): - animation.connect("animation_started", Callable(Event, "_loading_is_started")) - animation.connect("animation_finished", Callable(Event, "_loading_is_finished")) + animation.animation_started.connect(Event._loading_is_started) + animation.animation_finished.connect(Event._loading_is_finished) func goto_scene(path): print("[global#goto_scene] : load scene " + str(path)) diff --git a/scripts/event.gd b/scripts/event.gd new file mode 100644 index 0000000..e0e810b --- /dev/null +++ b/scripts/event.gd @@ -0,0 +1,42 @@ +class_name Event + +# UI event handlers, namespaced as static methods so they can be wired +# directly from anywhere without an autoload. +# +# button.pressed.connect(Event._on_main_scene_pressed) +# +# Per-level dispatch goes through `level_pressed(name)` which maps the level +# name to the appropriate handler. + +static func _loading_is_started(_anim_name: StringName) -> void: + Global.loaded = false + +static func _loading_is_finished(_anim_name: StringName) -> void: + Global.loaded = true + +static func _on_warcraft_pressed() -> void: + Global.current_scene_int = 0 + Global.goto_scene("res://scenes/levels/warcraft/WarCraft.tscn") + +static func _on_home_pressed() -> void: + Global.current_scene_int = 1 + Global.goto_scene("res://scenes/levels/home/Home.tscn") + +static func _on_reset_level(level, node: String, index: int, parent) -> void: + Global.current_scene_int = index + level.reset() + parent.configure_reset(level, node, index, true) + parent.configure_counter(level, node) + Global.current_scene_int = null + +static func _on_main_scene_pressed() -> void: + Global.goto_scene("res://scenes/Main.tscn") + +# Returns the press handler for a level by name (used by ChooseScene to wire +# the dynamic level-select buttons). Returns Callable() if unknown. +static func level_pressed(name: String) -> Callable: + match name.to_lower(): + "warcraft": return _on_warcraft_pressed + "home": return _on_home_pressed + push_warning("Event.level_pressed: no handler for level '%s'" % name) + return Callable() diff --git a/scripts/event.gd.uid b/scripts/event.gd.uid new file mode 100644 index 0000000..db7edee --- /dev/null +++ b/scripts/event.gd.uid @@ -0,0 +1 @@ +uid://blq7ojhkgitwj diff --git a/scripts/game_animation.gd b/scripts/game_animation.gd new file mode 100644 index 0000000..728667d --- /dev/null +++ b/scripts/game_animation.gd @@ -0,0 +1,37 @@ +class_name GameAnimation + +# Helpers for HUD slide/warning animations and the per-item dissolve effect. +# Pure functions — no state — so no autoload is needed. + +static func level_hud_slide(node: Node) -> Animation: + var animation := Animation.new() + var track_index := animation.add_track(Animation.TYPE_BEZIER) + animation.track_set_path(track_index, str(node.get_path()) + ":position:x") + animation.bezier_track_insert_key(track_index, 0.0, 0.0, Vector2(-0.25, 0), Vector2(0.031, 190.492)) + animation.bezier_track_insert_key(track_index, 1.0, 170, Vector2(-0.349, 2.576), Vector2(0.25, 0)) + return animation + +static func level_hud_warning(node: Node) -> Animation: + var animation := Animation.new() + var track_index := animation.add_track(Animation.TYPE_BEZIER) + animation.track_set_path(track_index, str(node.get_path()) + ":position:x") + animation.bezier_track_insert_key(track_index, 0.0, 0.0, Vector2(-0.25, 0), Vector2(0, 78.1)) + animation.bezier_track_insert_key(track_index, 0.2, 34.9, Vector2(-0.25, 0), Vector2(0, -66)) + animation.bezier_track_insert_key(track_index, 0.4, 12.1, Vector2(0, 73.2), Vector2(0, -124.8)) + animation.bezier_track_insert_key(track_index, 0.6, -41.9, Vector2(-0.095, 109.2), Vector2(0.062, -58.8)) + animation.bezier_track_insert_key(track_index, 0.8, 13.3, Vector2(-0.188, 93.6), Vector2(0.196, 104.4)) + animation.bezier_track_insert_key(track_index, 1.0, 0.0, Vector2(-0.155, -135.5), Vector2(0.25, 0)) + return animation + +# Captures `material` in the tween callback so no shared mutable state is +# needed (replaces the old `current_material` member from the autoload). +static func start_dissolve(node: Node, material: ShaderMaterial) -> void: + if material == null: + return + var tween := node.create_tween() + tween.tween_method( + func(progress: float) -> void: + material.set_shader_parameter("dissolve_amount", ease(progress, 0.4)), + 0.0, 1.0, 1.5) \ + .set_trans(Tween.TRANS_LINEAR) \ + .set_ease(Tween.EASE_IN_OUT) diff --git a/scripts/game_animation.gd.uid b/scripts/game_animation.gd.uid new file mode 100644 index 0000000..b742069 --- /dev/null +++ b/scripts/game_animation.gd.uid @@ -0,0 +1 @@ +uid://dtpgm3o6wdmju diff --git a/scripts/devisualize_shaders.gd b/scripts/migration/devisualize_shaders.gd similarity index 100% rename from scripts/devisualize_shaders.gd rename to scripts/migration/devisualize_shaders.gd diff --git a/scripts/devisualize_shaders.gd.uid b/scripts/migration/devisualize_shaders.gd.uid similarity index 100% rename from scripts/devisualize_shaders.gd.uid rename to scripts/migration/devisualize_shaders.gd.uid diff --git a/scripts/find_visualshaders.gd b/scripts/migration/find_visualshaders.gd similarity index 100% rename from scripts/find_visualshaders.gd rename to scripts/migration/find_visualshaders.gd diff --git a/scripts/find_visualshaders.gd.uid b/scripts/migration/find_visualshaders.gd.uid similarity index 100% rename from scripts/find_visualshaders.gd.uid rename to scripts/migration/find_visualshaders.gd.uid diff --git a/scripts/migrate_misc.gd b/scripts/migration/migrate_misc.gd similarity index 100% rename from scripts/migrate_misc.gd rename to scripts/migration/migrate_misc.gd diff --git a/scripts/migrate_misc.gd.uid b/scripts/migration/migrate_misc.gd.uid similarity index 100% rename from scripts/migrate_misc.gd.uid rename to scripts/migration/migrate_misc.gd.uid diff --git a/scripts/migrate_shaders.gd b/scripts/migration/migrate_shaders.gd similarity index 100% rename from scripts/migrate_shaders.gd rename to scripts/migration/migrate_shaders.gd diff --git a/scripts/migrate_shaders.gd.uid b/scripts/migration/migrate_shaders.gd.uid similarity index 100% rename from scripts/migrate_shaders.gd.uid rename to scripts/migration/migrate_shaders.gd.uid diff --git a/scripts/resave_scenes.gd b/scripts/migration/resave_scenes.gd similarity index 100% rename from scripts/resave_scenes.gd rename to scripts/migration/resave_scenes.gd diff --git a/scripts/resave_scenes.gd.uid b/scripts/migration/resave_scenes.gd.uid similarity index 100% rename from scripts/resave_scenes.gd.uid rename to scripts/migration/resave_scenes.gd.uid