scene_extension.gd 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. class_name _ModLoaderSceneExtension
  2. extends RefCounted
  3. # This Class provides methods for working with scene extensions.
  4. # Currently all of the included methods are internal and should only be used by the mod loader itself.
  5. const LOG_NAME := "ModLoader:SceneExtension"
  6. # Iterates over the list of scenes to refresh them from storage.
  7. # Used to apply script extensions to preloaded scenes.
  8. static func refresh_scenes() -> void:
  9. for scene_path in ModLoaderStore.scenes_to_refresh:
  10. # Refresh cached scenes from storage
  11. var _scene_from_file: PackedScene = ResourceLoader.load(
  12. scene_path, "", ResourceLoader.CACHE_MODE_REPLACE
  13. )
  14. ModLoaderLog.debug("Refreshed scene at path: %s" % scene_path, LOG_NAME)
  15. # Iterates over the list of scenes to modify and applies the specified edits to each scene.
  16. static func handle_scene_extensions() -> void:
  17. for scene_path in ModLoaderStore.scenes_to_modify.keys():
  18. for scene_edit_callable in ModLoaderStore.scenes_to_modify[scene_path]:
  19. var cached_scene: PackedScene = load(scene_path)
  20. var cached_scene_instance: Node = cached_scene.instantiate()
  21. var edited_scene: Node = scene_edit_callable.call(cached_scene_instance)
  22. if not edited_scene:
  23. ModLoaderLog.fatal(
  24. (
  25. 'Scene extension of "%s" failed since the edit callable "%s" does not return the modified scene_instance'
  26. % [scene_path, scene_edit_callable.get_method()]
  27. ),
  28. LOG_NAME
  29. )
  30. return
  31. _save_scene(edited_scene, scene_path)
  32. # Saves a modified scene to resource cache.
  33. # Further attempts to load this scene by path will instead return this resource.
  34. #
  35. # Parameters:
  36. # - modified_scene (Node): The modified scene instance to be saved.
  37. # - scene_path (String): The path to the scene file that will be replaced.
  38. #
  39. # Returns: void
  40. static func _save_scene(modified_scene: Node, scene_path: String) -> void:
  41. var packed_scene := PackedScene.new()
  42. var _pack_error := packed_scene.pack(modified_scene)
  43. ModLoaderLog.debug("packing scene -> %s" % packed_scene, LOG_NAME)
  44. packed_scene.take_over_path(scene_path)
  45. ModLoaderLog.debug(
  46. "save_scene - taking over path - new path -> %s" % packed_scene.resource_path, LOG_NAME
  47. )
  48. ModLoaderStore.saved_objects.append(packed_scene)