gdharness 1.3.42 → 1.3.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/build/cli.js +383 -243
  2. package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
  3. package/build/godot/addons/gdharness_editor/animation_reads.gd +55 -33
  4. package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
  5. package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
  6. package/build/godot/addons/gdharness_editor/file_reads.gd +83 -42
  7. package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
  8. package/build/godot/addons/gdharness_editor/headless_check.gd +68 -44
  9. package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
  10. package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
  11. package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
  12. package/build/godot/addons/gdharness_editor/reading.gd +51 -17
  13. package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
  14. package/build/godot/addons/gdharness_editor/scene_file.gd +127 -80
  15. package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
  16. package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
  17. package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
  18. package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
  19. package/build/godot/addons/gdharness_editor/tools/animation_states.gd +37 -27
  20. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +79 -49
  21. package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
  22. package/build/godot/addons/gdharness_editor/tools/class_tools.gd +65 -42
  23. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
  24. package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
  25. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
  26. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
  27. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +166 -107
  28. package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
  29. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +68 -41
  30. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
  31. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
  32. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +12 -5
  33. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +113 -67
  34. package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
  35. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
  36. package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
  37. package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
  38. package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
  39. package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
  40. package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
  41. package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
  42. package/build/godot/addons/gdharness_runtime/reading.gd +51 -17
  43. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
  44. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +149 -147
  45. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
  46. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
  47. package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
  48. package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
  49. package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
  50. package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
  51. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
  52. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +34 -17
  53. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
  54. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
  55. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
  56. package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
  57. package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
  58. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
  59. package/build/godot/addons/gdharness_runtime/runtime_touch.gd +15 -15
  60. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
  61. package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
  62. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
  63. package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
  64. package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
  65. package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
  66. package/build/godot/addons/gdharness_tests/bench.gd +4 -5
  67. package/build/godot/addons/gdharness_tests/event.gd +10 -5
  68. package/build/godot/addons/gdharness_tests/share.gd +38 -18
  69. package/build/godot/addons/gdharness_tests/suites.gd +3 -3
  70. package/build/godot/addons/gdharness_tests/wait.gd +3 -2
  71. package/build/godot/loader/loader.gd +9 -9
  72. package/build/godot/operations/animation_reads.gd +55 -33
  73. package/build/godot/operations/audio_buses.gd +48 -19
  74. package/build/godot/operations/class_cache.gd +16 -11
  75. package/build/godot/operations/classdb_queries.gd +89 -44
  76. package/build/godot/operations/declared_values.gd +68 -32
  77. package/build/godot/operations/dependencies.gd +190 -109
  78. package/build/godot/operations/editor_tools.gd +10 -10
  79. package/build/godot/operations/export_presets.gd +100 -54
  80. package/build/godot/operations/file_reads.gd +83 -42
  81. package/build/godot/operations/file_walk.gd +12 -5
  82. package/build/godot/operations/gdscript_analysis.gd +86 -65
  83. package/build/godot/operations/gdscript_authoring.gd +83 -36
  84. package/build/godot/operations/godot_operations.gd +17 -11
  85. package/build/godot/operations/import_pipeline.gd +110 -59
  86. package/build/godot/operations/input_actions.gd +62 -39
  87. package/build/godot/operations/patterns.gd +3 -1
  88. package/build/godot/operations/plugins.gd +36 -16
  89. package/build/godot/operations/project_config.gd +61 -32
  90. package/build/godot/operations/project_diagnostics.gd +24 -11
  91. package/build/godot/operations/project_file.gd +16 -16
  92. package/build/godot/operations/project_validation.gd +71 -44
  93. package/build/godot/operations/property_paths.gd +22 -12
  94. package/build/godot/operations/property_values.gd +143 -78
  95. package/build/godot/operations/reading.gd +51 -17
  96. package/build/godot/operations/rename_checks.gd +2 -2
  97. package/build/godot/operations/resource_files.gd +11 -9
  98. package/build/godot/operations/same_values.gd +4 -4
  99. package/build/godot/operations/scene_connections.gd +27 -13
  100. package/build/godot/operations/script_check.gd +52 -49
  101. package/build/godot/operations/serialisation.gd +75 -51
  102. package/build/godot/operations/setting_reads.gd +7 -6
  103. package/build/godot/operations/value_shapes.gd +5 -6
  104. package/build/godot/tests/listed.gd +321 -268
  105. package/build/keeper.js +43 -43
  106. package/package.json +1 -1
@@ -1,8 +1,7 @@
1
1
  @tool
2
2
  extends RefCounted
3
-
4
- ## The two ways a scene keeps its own values for nodes another scene makes: by inheriting that scene,
5
- ## or by instancing it with its children editable.
3
+ ## The two ways a scene keeps its own values for nodes another scene makes: by inheriting that
4
+ ## scene, or by instancing it with its children editable.
6
5
 
7
6
  const GdhFileReads = preload("../file_reads.gd")
8
7
  const GdhPaths = preload("scene_paths.gd")
@@ -18,11 +17,11 @@ static func taken(scene_path: String) -> Dictionary:
18
17
  "error":
19
18
  (
20
19
  (
21
- "%s already exists, and scene_create op=create would replace everything in it. Edit it "
22
- + "with scene_node, or create the scene under another path."
20
+ "%s already exists, and scene_create op=create would replace everything in it. "
21
+ + "Edit it with scene_node, or create the scene under another path."
23
22
  )
24
23
  % scene_path
25
- )
24
+ ),
26
25
  }
27
26
 
28
27
 
@@ -32,12 +31,15 @@ static func inherited(
32
31
  args: Dictionary, scene_path: String, base_path: String, script_path: String
33
32
  ) -> Dictionary:
34
33
  if scene_path.is_empty():
35
- return {"ok": false, "error": "Missing scenePath"}
34
+ return { "ok": false, "error": "Missing scenePath" }
36
35
  if args.has("rootNodeType"):
37
36
  return {
38
37
  "ok": false,
39
38
  "error":
40
- "inherits takes the root's class from %s, so rootNodeType is not given with it." % base_path
39
+ (
40
+ "inherits takes the root's class from %s, so rootNodeType is not given with it."
41
+ % base_path
42
+ ),
41
43
  }
42
44
  if FileAccess.file_exists(scene_path):
43
45
  return taken(scene_path)
@@ -45,10 +47,10 @@ static func inherited(
45
47
  if not script_path.is_empty():
46
48
  script = load(script_path) as Script
47
49
  if script == null:
48
- return {"ok": false, "error": "No script loads from " + script_path}
50
+ return { "ok": false, "error": "No script loads from " + script_path }
49
51
  var uncompiled: String = GdhSceneFile.uncompiled(script, script_path)
50
52
  if not uncompiled.is_empty():
51
- return {"ok": false, "error": uncompiled}
53
+ return { "ok": false, "error": uncompiled }
52
54
  return inherit(scene_path, base_path, str(args.get("rootNodeName", "")), script)
53
55
 
54
56
 
@@ -57,17 +59,22 @@ static func inherited(
57
59
  ## given. Answers what scene_create answers, or a refusal.
58
60
  ##
59
61
  ## Written as the text the editor's New Inherited Scene saves rather than packed from an instance of
60
- ## the base: a headless engine making that instance runs every script in the base, and the pack would
61
- ## keep what they set as this scene's own values.
62
- static func inherit(scene_path: String, base_path: String, root_name: String, script: Script) -> Dictionary:
62
+ ## the base: a headless engine making that instance runs every script in the base, and the pack
63
+ ## would keep what they set as this scene's own values.
64
+ static func inherit(
65
+ scene_path: String, base_path: String, root_name: String, script: Script
66
+ ) -> Dictionary:
63
67
  var base: Dictionary = GdhFileReads.scene_node(base_path, ".")
64
68
  if not base.get("ok", false):
65
- return {"ok": false, "error": "inherits: " + str(base.get("error", "%s holds no nodes" % base_path))}
69
+ return {
70
+ "ok": false,
71
+ "error": "inherits: " + str(base.get("error", "%s holds no nodes" % base_path)),
72
+ }
66
73
  var root_type: String = str(base["type"])
67
74
  var name: String = str(base["name"]) if root_name.is_empty() else root_name
68
75
  var unfit: String = GdhSceneFile.unfit_name(name)
69
76
  if not unfit.is_empty():
70
- return {"ok": false, "error": unfit}
77
+ return { "ok": false, "error": unfit }
71
78
  if script != null:
72
79
  var extended: String = str(script.get_instance_base_type())
73
80
  if not ClassDB.is_parent_class(root_type, extended):
@@ -77,11 +84,11 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
77
84
  (
78
85
  "%s extends %s, so it cannot be on the %s root %s inherits."
79
86
  % [script.resource_path, extended, root_type, base_path]
80
- )
87
+ ),
81
88
  }
82
89
  var folder: String = GdhSceneFile.make_folder_for(scene_path)
83
90
  if not folder.is_empty():
84
- return {"ok": false, "error": folder}
91
+ return { "ok": false, "error": folder }
85
92
 
86
93
  var lines: PackedStringArray = [
87
94
  '[gd_scene format=3 uid="%s"]' % ResourceUID.id_to_text(ResourceUID.create_id()),
@@ -105,18 +112,24 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
105
112
  if file == null or not file.store_string("\n".join(lines) + "\n"):
106
113
  return {
107
114
  "ok": false,
108
- "error": "Could not write %s: %s" % [scene_path, error_string(FileAccess.get_open_error())]
115
+ "error":
116
+ "Could not write %s: %s" % [scene_path, error_string(FileAccess.get_open_error())],
109
117
  }
110
118
  file.close()
111
119
 
112
- var loaded: PackedScene = ResourceLoader.load(scene_path, "PackedScene", ResourceLoader.CACHE_MODE_IGNORE)
120
+ var loaded: PackedScene = ResourceLoader.load(
121
+ scene_path, "PackedScene", ResourceLoader.CACHE_MODE_IGNORE
122
+ )
113
123
  var instanced: PackedScene = loaded.get_state().get_node_instance(0) if loaded != null else null
114
124
  if instanced == null or instanced.resource_path != base_path:
115
125
  var _removed: Error = DirAccess.remove_absolute(scene_path)
116
126
  return {
117
127
  "ok": false,
118
128
  "error":
119
- "%s did not load back as a scene inheriting %s, so it was removed." % [scene_path, base_path]
129
+ (
130
+ "%s did not load back as a scene inheriting %s, so it was removed."
131
+ % [scene_path, base_path]
132
+ ),
120
133
  }
121
134
  GdhSceneFile.refresh(scene_path)
122
135
  var answer: Dictionary = {
@@ -124,7 +137,7 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
124
137
  "scenePath": scene_path,
125
138
  "inherits": base_path,
126
139
  "rootNodeType": root_type,
127
- "rootNodeName": name
140
+ "rootNodeName": name,
128
141
  }
129
142
  var properties: Dictionary = base["properties"]
130
143
  var carried: Variant = script if script != null else properties.get("script")
@@ -139,7 +152,8 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
139
152
  ## Makes the children of [param node], an instance in [param scene], editable or not, answering why
140
153
  ## it cannot or "". With them editable the scene keeps its own values for them, as the editor's
141
154
  ## Editable Children does; made not editable again, the values it kept for them are dropped. The
142
- ## caller has had [method GdhSceneFile.foreign] refuse a node inside an instance that is not editable.
155
+ ## caller has had [method GdhSceneFile.foreign] refuse a node inside an instance that is not
156
+ ## editable.
143
157
  static func set_editable(scene: GdhSceneFile, node: Node, editable: bool) -> String:
144
158
  if node.owner == null or node.scene_file_path.is_empty():
145
159
  return (
@@ -161,7 +175,9 @@ static func set_editable(scene: GdhSceneFile, node: Node, editable: bool) -> Str
161
175
  ## for a node deleted, they are only named. Answers followed, the scenes rewritten, and
162
176
  ## notFollowed, each one left as it was with why, each only when it names any, with what
163
177
  ## [param carried] gives.
164
- static func follow(changed: String, old_path: String, new_path: String, carried: GdhPaths) -> Dictionary:
178
+ static func follow(
179
+ changed: String, old_path: String, new_path: String, carried: GdhPaths
180
+ ) -> Dictionary:
165
181
  var texts: Dictionary = {}
166
182
  _read_scenes("res://", texts)
167
183
  var kin: Array[String] = [changed]
@@ -187,7 +203,7 @@ static func follow(changed: String, old_path: String, new_path: String, carried:
187
203
  moves[old_path] = new_path
188
204
  var read: Dictionary = GdhFileReads.scene_tree(scene_path, -1, false, false)
189
205
  if not read.get("ok", false):
190
- not_followed.append({"scenePath": scene_path, "reason": str(read.get("error", ""))})
206
+ not_followed.append({ "scenePath": scene_path, "reason": str(read.get("error", "")) })
191
207
  continue
192
208
  var tree: Dictionary = read["tree"]
193
209
  _instances_of(tree, changed, old_path, new_path, moves)
@@ -198,28 +214,29 @@ static func follow(changed: String, old_path: String, new_path: String, carried:
198
214
  rewritten = _rewritten(text, moves, old_path.get_base_dir() != new_path.get_base_dir())
199
215
  if rewritten != text:
200
216
  if not unsaved.is_empty():
201
- not_followed.append({"scenePath": scene_path, "reason": unsaved})
217
+ not_followed.append({ "scenePath": scene_path, "reason": unsaved })
202
218
  continue
203
219
  var file: FileAccess = FileAccess.open(scene_path, FileAccess.WRITE)
204
220
  if file == null or not file.store_string(rewritten):
205
221
  not_followed.append(
206
- {"scenePath": scene_path, "reason": error_string(FileAccess.get_open_error())}
222
+ { "scenePath": scene_path, "reason": error_string(FileAccess.get_open_error()) }
207
223
  )
208
224
  continue
209
225
  file.close()
210
226
  GdhSceneFile.refresh(scene_path)
211
227
  followed.append(scene_path)
212
228
  var holds_paths: bool = text.contains("NodePath(")
213
- # A script is only read, for the lines naming the node, so it does not need the file written.
229
+ # A script is only read, for the lines naming the node, so it does not need the file
230
+ # written.
214
231
  if moves.is_empty() or not (holds_paths or text.contains('Script"')):
215
232
  continue
216
233
  if holds_paths and not unsaved.is_empty() and not new_path.is_empty():
217
- not_followed.append({"scenePath": scene_path, "reason": unsaved})
234
+ not_followed.append({ "scenePath": scene_path, "reason": unsaved })
218
235
  continue
219
236
  var before: int = carried.retargeted.size()
220
237
  var unwritten: String = carried.carry_into(scene_path, moves)
221
238
  if not unwritten.is_empty() and not followed.has(scene_path):
222
- not_followed.append({"scenePath": scene_path, "reason": unwritten})
239
+ not_followed.append({ "scenePath": scene_path, "reason": unwritten })
223
240
  elif carried.retargeted.size() > before and not followed.has(scene_path):
224
241
  followed.append(scene_path)
225
242
  var answer: Dictionary = carried.answer()
@@ -238,7 +255,9 @@ static func _read_scenes(directory: String, texts: Dictionary) -> void:
238
255
  _read_scenes(directory.path_join(name), texts)
239
256
  for name: String in DirAccess.get_files_at(directory):
240
257
  if name.ends_with(".tscn"):
241
- texts[directory.path_join(name)] = FileAccess.get_file_as_string(directory.path_join(name))
258
+ texts[directory.path_join(name)] = FileAccess.get_file_as_string(
259
+ directory.path_join(name)
260
+ )
242
261
 
243
262
 
244
263
  ## Whether the scene at [param scene_path] inherits [param changed], through any number of scenes.
@@ -253,19 +272,22 @@ static func _inherits(scene_path: String, changed: String, texts: Dictionary) ->
253
272
  return false
254
273
 
255
274
 
256
- ## The scene the root of [param text] inherits, or "": a root entry naming an instance and no parent.
275
+ ## The scene the root of [param text] inherits, or "": a root entry naming an instance and no
276
+ ## parent.
257
277
  static func _base_of(text: String) -> String:
258
278
  for line: String in text.split("\n"):
259
279
  if not line.begins_with("[node "):
260
280
  continue
261
- var instanced: RegExMatch = RegEx.create_from_string('instance=ExtResource\\("([^"]+)"\\)').search(
262
- line
281
+ var instanced: RegExMatch = (
282
+ RegEx.create_from_string('instance=ExtResource\\("([^"]+)"\\)').search(line)
263
283
  )
264
284
  if instanced == null or line.contains(" parent="):
265
285
  return ""
266
286
  var named: RegExMatch = (
267
287
  RegEx
268
- . create_from_string('\\[ext_resource [^\\n]*path="([^"]+)" id="%s"\\]' % instanced.get_string(1))
288
+ . create_from_string(
289
+ '\\[ext_resource [^\\n]*path="([^"]+)" id="%s"\\]' % instanced.get_string(1)
290
+ )
269
291
  . search(text)
270
292
  )
271
293
  return named.get_string(1) if named != null else ""
@@ -289,10 +311,11 @@ static func _instances_of(
289
311
 
290
312
  ## [param text] with every path [param moves] names, and every path below one, moved.
291
313
  ##
292
- ## Beside a path the saver writes the unique_ids of the nodes along it, which the loader follows when
293
- ## the path has vanished. A rename leaves those ids as they were; with [param reparented] they run
294
- ## through the old parent, which still exists, so a recovery would find the wrong node. They are left
295
- ## out of each path moved, as a hand-written scene leaves them, and the next save writes them anew.
314
+ ## Beside a path the saver writes the unique_ids of the nodes along it, which the loader follows
315
+ ## when the path has vanished. A rename leaves those ids as they were; with [param reparented] they
316
+ ## run through the old parent, which still exists, so a recovery would find the wrong node. They are
317
+ ## left out of each path moved, as a hand-written scene leaves them, and the next save writes them
318
+ ## anew.
296
319
  static func _rewritten(text: String, moves: Dictionary, reparented: bool) -> String:
297
320
  if moves.is_empty():
298
321
  return text
@@ -314,7 +337,11 @@ static func _rewritten(text: String, moves: Dictionary, reparented: bool) -> Str
314
337
  var placed: String = _attribute_set(
315
338
  line, "parent", "." if moved_parent.is_empty() else moved_parent
316
339
  )
317
- line = _without_ids(placed, "parent_id_path") if placed != line and reparented else placed
340
+ line = (
341
+ _without_ids(placed, "parent_id_path")
342
+ if placed != line and reparented
343
+ else placed
344
+ )
318
345
  else:
319
346
  line = _attribute_moved(line, "parent", "parent_id_path", moves, reparented)
320
347
  lines[at] = line
@@ -338,8 +365,8 @@ static func _attribute_set(line: String, attribute: String, value: String) -> St
338
365
  return line.substr(0, found.get_start(1)) + value + line.substr(found.get_end(1))
339
366
 
340
367
 
341
- ## [param line] with the path under [param attribute] moved by [param moves], and, when that moved it
342
- ## and the move was a reparent, without the ids under [param ids] that went along the old path.
368
+ ## [param line] with the path under [param attribute] moved by [param moves], and, when that moved
369
+ ## it and the move was a reparent, without the ids under [param ids] that went along the old path.
343
370
  static func _attribute_moved(
344
371
  line: String, attribute: String, ids: String, moves: Dictionary, reparented: bool
345
372
  ) -> String:
@@ -1,6 +1,5 @@
1
1
  @tool
2
2
  extends RefCounted
3
-
4
3
  ## The node paths scenes hold, carried after a node moves as the editor's own rename carries them:
5
4
  ## the NodePath values on their nodes, inside arrays, dictionaries and the resources built into the
6
5
  ## scene too, and the tracks of the animations their players play. After a delete they are named
@@ -9,7 +8,11 @@ extends RefCounted
9
8
  ## A path is worked out from where its holder was and where it pointed before the move, so it is
10
9
  ## followed in a scene loaded after the move as well, where the old path no longer resolves.
11
10
 
12
- enum { UNCHANGED, REWRITTEN, DELETED }
11
+ enum {
12
+ UNCHANGED,
13
+ REWRITTEN,
14
+ DELETED,
15
+ }
13
16
 
14
17
  const GdhHeadlessCheck = preload("../headless_check.gd")
15
18
  const GdhRead = preload("../reading.gd")
@@ -87,7 +90,7 @@ func carry(scene: GdhSceneFile, moves: Dictionary) -> int:
87
90
  var name: String = str(property["name"])
88
91
  if not _may_hold_paths(property):
89
92
  continue
90
- var entry: Dictionary = {"scenePath": scene.path, "nodePath": now, "property": name}
93
+ var entry: Dictionary = { "scenePath": scene.path, "nodePath": now, "property": name }
91
94
  var elsewhere: String = "" if set_here.has(name) else from
92
95
  var carried: Array = _carried(node.get(name), was, now, entry, elsewhere)
93
96
  if carried[0]:
@@ -241,10 +244,12 @@ static func _may_hold_paths(property: Dictionary) -> bool:
241
244
  ## it carried, as [whether any was, the value]. A resource built into the scene is changed in place.
242
245
  ## [param entry] says where the value is held, for the record of each path. A path in a resource may
243
246
  ## be relative to something other than its holder, as the editor allows; it is followed only when it
244
- ## names a node from where its holder was, as one relative to the holder does. A value [param
245
- ## elsewhere], a file other than the scene's, gives is named only when it names nothing since the
246
- ## move, which its own file's pass could not see.
247
- func _carried(value: Variant, was: String, now: String, entry: Dictionary, elsewhere: String) -> Array:
247
+ ## names a node from where its holder was, as one relative to the holder does. A value
248
+ ## [param elsewhere], a file other than the scene's, gives is named only when it names nothing since
249
+ ## the move, which its own file's pass could not see.
250
+ func _carried(
251
+ value: Variant, was: String, now: String, entry: Dictionary, elsewhere: String
252
+ ) -> Array:
248
253
  match typeof(value):
249
254
  TYPE_NODE_PATH:
250
255
  var path: NodePath = value
@@ -256,7 +261,10 @@ func _carried(value: Variant, was: String, now: String, entry: Dictionary, elsew
256
261
  not_retargeted.append(
257
262
  _left(
258
263
  record,
259
- "The value is set in %s, and an edit here would not be saved there." % elsewhere
264
+ (
265
+ "The value is set in %s, and an edit here would not be saved there."
266
+ % elsewhere
267
+ )
260
268
  )
261
269
  )
262
270
  elif after[0] == DELETED:
@@ -350,7 +358,9 @@ func _after(path: NodePath, was: String, now: String) -> Array:
350
358
  ## Whether [param path], held by the node at [param now], names no node.
351
359
  func _names_nothing(path: NodePath, now: String) -> bool:
352
360
  var holder: Node = _scene.root.get_node_or_null(now)
353
- return holder != null and holder.get_node_or_null(NodePath(path.get_concatenated_names())) == null
361
+ return (
362
+ holder != null and holder.get_node_or_null(NodePath(path.get_concatenated_names())) == null
363
+ )
354
364
 
355
365
 
356
366
  ## The path to [param target] through the unique node that was at [param start], written through its
@@ -424,8 +434,9 @@ func _tracks(mixer: AnimationMixer, now: String) -> void:
424
434
  var animation: Animation = library.get_animation(animation_name)
425
435
  var home: Dictionary = _home_of(animation, library)
426
436
  var why: String = home["why"]
427
- # Carried once, from the first scene playing it. One kept in a file of its own that this call
428
- # rewrote is held in _homes, so a later scene loading that file is given this same copy.
437
+ # Carried once, from the first scene playing it. One kept in a file of its own that this
438
+ # call rewrote is held in _homes, so a later scene loading that file is given this same
439
+ # copy.
429
440
  if _seen.has(animation):
430
441
  continue
431
442
  _seen[animation] = true
@@ -466,13 +477,14 @@ func _tracks(mixer: AnimationMixer, now: String) -> void:
466
477
 
467
478
 
468
479
  ## Where an edit to [param animation], played from [param library], is saved, as {file, home, why,
469
- ## theirs}: file "" with the scene, or the file of its own it or its library is kept in, with home the
470
- ## resource saved there; why, when nothing written here would keep the edit; theirs, when that is
471
- ## because it is kept in another scene or an imported file, whose tracks are written in its terms.
480
+ ## theirs}: file "" with the scene, or the file of its own it or its library is kept in, with home
481
+ ## the resource saved there; why, when nothing written here would keep the edit; theirs, when that
482
+ ## is because it is kept in another scene or an imported file, whose tracks are written in its
483
+ ## terms.
472
484
  func _home_of(animation: Animation, library: AnimationLibrary) -> Dictionary:
473
485
  var file: String = animation.resource_path.get_slice("::", 0)
474
486
  if file.is_empty() or file == _scene.path:
475
- return {"file": "", "why": ""}
487
+ return { "file": "", "why": "" }
476
488
  var home: Resource = animation
477
489
  if animation.resource_path.contains("::"):
478
490
  home = library if library.resource_path == file else null
@@ -483,18 +495,21 @@ func _home_of(animation: Animation, library: AnimationLibrary) -> Dictionary:
483
495
  }
484
496
  if not Engine.is_editor_hint():
485
497
  var script: Script = home.get_script()
486
- if (script != null and not script.is_tool()) or GdhHeadlessCheck.holds_scripted_embedded(home, {}):
498
+ if (
499
+ (script != null and not script.is_tool())
500
+ or GdhHeadlessCheck.holds_scripted_embedded(home, {})
501
+ ):
487
502
  return {
488
503
  "why":
489
504
  (
490
505
  (
491
506
  (
492
- "%s holds a resource with a script that is not a tool, which a headless engine runs as "
493
- + "it loads the file. "
507
+ "%s holds a resource with a script that is not a tool, which a "
508
+ + "headless engine runs as it loads the file. "
494
509
  )
495
510
  % file
496
511
  )
497
512
  + GdhHeadlessCheck.REMEDY
498
- )
513
+ ),
499
514
  }
500
- return {"file": file, "home": home, "why": ""}
515
+ return { "file": file, "home": home, "why": "" }
@@ -1,6 +1,5 @@
1
1
  @tool
2
2
  extends RefCounted
3
-
4
3
  ## What a new node in a scene is made or copied from, what the scene owns of it, and where among its
5
4
  ## siblings a node may go.
6
5
 
@@ -15,7 +14,8 @@ static func what_to_add(node_type: String, instance_path: String, scene_path: St
15
14
  if node_type.is_empty() == instance_path.is_empty():
16
15
  return [
17
16
  null,
18
- "add takes nodeType for a node of a class, or instancePath for a scene, and one of them only."
17
+ "add takes nodeType for a node of a class, or instancePath for a scene, and one of "
18
+ + "them only.",
19
19
  ]
20
20
  if not instance_path.is_empty():
21
21
  # Asked before the cycle walk, which reads the file's dependencies and so loaded a file that
@@ -35,9 +35,12 @@ static func what_to_add(node_type: String, instance_path: String, scene_path: St
35
35
  return [
36
36
  null,
37
37
  (
38
- "nodeType must be a node class, and %s is a scene: pass it as instancePath to instance it."
38
+ (
39
+ "nodeType must be a node class, and %s is a scene: pass it as instancePath to "
40
+ + "instance it."
41
+ )
39
42
  % node_type
40
- )
43
+ ),
41
44
  ]
42
45
  if not ClassDB.class_exists(node_type) or not ClassDB.is_parent_class(node_type, "Node"):
43
46
  return [null, not_a_node_class("nodeType", node_type)]
@@ -73,10 +76,12 @@ static func made(packed: PackedScene, node_type: String) -> Node:
73
76
  static func copied(source: Node, root: Node, copies: Dictionary) -> Node:
74
77
  var copy: Node = null
75
78
  if not source.scene_file_path.is_empty():
76
- # An instanced scene made again from its file, so the copy is an instance too. Node.duplicate
77
- # makes a plain node of the instance's class, and the pack saved it with every property of the
78
- # instance's root frozen into this scene.
79
- var packed: PackedScene = ResourceLoader.load(source.scene_file_path, "PackedScene") as PackedScene
79
+ # An instanced scene made again from its file, so the copy is an instance too.
80
+ # Node.duplicate makes a plain node of the instance's class, and the pack saved it with
81
+ # every property of the instance's root frozen into this scene.
82
+ var packed: PackedScene = (
83
+ ResourceLoader.load(source.scene_file_path, "PackedScene") as PackedScene
84
+ )
80
85
  if packed == null:
81
86
  return null
82
87
  copy = packed.instantiate(PackedScene.GEN_EDIT_STATE_INSTANCE)
@@ -123,7 +128,11 @@ static func reconnect(copies: Dictionary, top: Node) -> void:
123
128
  if not flags & Object.CONNECT_PERSIST or target == null:
124
129
  continue
125
130
  var to: Object = copies.get(target, target)
126
- if to == target and target is Node and (target == top or top.is_ancestor_of(target as Node)):
131
+ if (
132
+ to == target
133
+ and target is Node
134
+ and (target == top or top.is_ancestor_of(target as Node))
135
+ ):
127
136
  continue
128
137
  var aimed: Callable = Callable(to, callable.get_method())
129
138
  if (
@@ -131,7 +140,10 @@ static func reconnect(copies: Dictionary, top: Node) -> void:
131
140
  and copy.connect(signal_name, aimed, flags) != OK
132
141
  ):
133
142
  push_error(
134
- "gdharness: could not copy the connection %s of %s" % [signal_name, source.name]
143
+ (
144
+ "gdharness: could not copy the connection %s of %s"
145
+ % [signal_name, source.name]
146
+ )
135
147
  )
136
148
 
137
149
 
@@ -150,7 +162,9 @@ static func own(node: Node, root: Node) -> void:
150
162
  static func unplaceable(parent: Node, node: Node, asked: Variant) -> String:
151
163
  if asked == null:
152
164
  return ""
153
- var others: int = parent.get_child_count() - (1 if node != null and node.get_parent() == parent else 0)
165
+ var others: int = (
166
+ parent.get_child_count() - (1 if node != null and node.get_parent() == parent else 0)
167
+ )
154
168
  var at: int = GdhRead.as_int(asked, -1)
155
169
  if at < 0 or at > others:
156
170
  return (
@@ -159,7 +173,7 @@ static func unplaceable(parent: Node, node: Node, asked: Variant) -> String:
159
173
  str(at) if asked is int or asked is float else JSON.stringify(asked),
160
174
  others,
161
175
  parent.name,
162
- others
176
+ others,
163
177
  ]
164
178
  )
165
179
  return ""
@@ -234,7 +248,8 @@ static func _spatial_space(parent: Node) -> Transform3D:
234
248
  return space
235
249
 
236
250
 
237
- ## Where the children of [param parent] are drawn in 2D, as [method _spatial_space] works it out in 3D.
251
+ ## Where the children of [param parent] are drawn in 2D, as [method _spatial_space] works it out in
252
+ ## 3D.
238
253
  static func _canvas_space(parent: Node) -> Transform2D:
239
254
  var space: Transform2D = Transform2D.IDENTITY
240
255
  var at: Node = parent
@@ -1,6 +1,5 @@
1
1
  @tool
2
2
  extends RefCounted
3
-
4
3
  ## Where else in a scene a resource built into it is held, since such a resource is one object
5
4
  ## wherever the scene uses it.
6
5
 
@@ -25,17 +24,22 @@ static func holders(scene: GdhSceneFile, node: Node, key: String) -> Array[Dicti
25
24
  for at: Node in nodes:
26
25
  for declared: Dictionary in at.get_property_list():
27
26
  var property: String = str(declared.get("name", ""))
28
- if property.is_empty() or not (GdhRead.as_int(declared.get("usage", 0)) & PROPERTY_USAGE_STORAGE):
27
+ if (
28
+ property.is_empty()
29
+ or not (GdhRead.as_int(declared.get("usage", 0)) & PROPERTY_USAGE_STORAGE)
30
+ ):
29
31
  continue
30
32
  for found: String in _paths_to(at.get(property), property, wanted, {}):
31
33
  if at != node or not key.begins_with(found + "/"):
32
- found_at.append({"node": scene.path_of(at), "property": found})
34
+ found_at.append({ "node": scene.path_of(at), "property": found })
33
35
  return found_at
34
36
 
35
37
 
36
38
  ## The paths below [param path] at which [param value] holds a resource of [param wanted], by
37
39
  ## instance id, stepping into lists and into resources built into a scene.
38
- static func _paths_to(value: Variant, path: String, wanted: Dictionary, seen: Dictionary) -> Array[String]:
40
+ static func _paths_to(
41
+ value: Variant, path: String, wanted: Dictionary, seen: Dictionary
42
+ ) -> Array[String]:
39
43
  var paths: Array[String] = []
40
44
  if value is Array:
41
45
  var items: Array = value
@@ -54,6 +58,9 @@ static func _paths_to(value: Variant, path: String, wanted: Dictionary, seen: Di
54
58
  seen[id] = true
55
59
  for declared: Dictionary in held.get_property_list():
56
60
  var property: String = str(declared.get("name", ""))
57
- if not property.is_empty() and GdhRead.as_int(declared.get("usage", 0)) & PROPERTY_USAGE_STORAGE:
61
+ if (
62
+ not property.is_empty()
63
+ and GdhRead.as_int(declared.get("usage", 0)) & PROPERTY_USAGE_STORAGE
64
+ ):
58
65
  paths.append_array(_paths_to(held.get(property), path + "/" + property, wanted, seen))
59
66
  return paths