gdharness 1.3.60 → 1.3.62
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.
- package/README.md +20 -20
- package/build/cli.js +2198 -1757
- package/build/godot/addons/auto_reload/auto_reload.gd +3 -3
- package/build/godot/addons/gdharness_editor/bridge_client.gd +4 -4
- package/build/godot/addons/gdharness_editor/declared_values.gd +13 -13
- package/build/godot/addons/gdharness_editor/file_reads.gd +6 -6
- package/build/godot/addons/gdharness_editor/headless_check.gd +9 -6
- package/build/godot/addons/gdharness_editor/property_paths.gd +3 -3
- package/build/godot/addons/gdharness_editor/property_values.gd +10 -10
- package/build/godot/addons/gdharness_editor/reading.gd +22 -18
- package/build/godot/addons/gdharness_editor/scene_file.gd +5 -5
- package/build/godot/addons/gdharness_editor/serialisation.gd +4 -4
- package/build/godot/addons/gdharness_editor/tools/animation_states.gd +5 -5
- package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +6 -6
- package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +9 -9
- package/build/godot/addons/gdharness_editor/tools/class_tools.gd +3 -3
- package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +5 -5
- package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +5 -5
- package/build/godot/addons/gdharness_editor/tools/play_tools.gd +2 -2
- package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +1 -1
- package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +5 -5
- package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +3 -3
- package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +3 -3
- package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +4 -4
- package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +3 -3
- package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +10 -10
- package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +1 -1
- package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +5 -5
- package/build/godot/addons/gdharness_runtime/declared_values.gd +13 -13
- package/build/godot/addons/gdharness_runtime/reading.gd +22 -18
- package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +2 -2
- package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +89 -18
- package/build/godot/addons/gdharness_runtime/runtime_capture.gd +6 -6
- package/build/godot/addons/gdharness_runtime/runtime_changes.gd +10 -10
- package/build/godot/addons/gdharness_runtime/runtime_frames.gd +5 -4
- package/build/godot/addons/gdharness_runtime/runtime_hover.gd +3 -4
- package/build/godot/addons/gdharness_runtime/runtime_input.gd +8 -8
- package/build/godot/addons/gdharness_runtime/runtime_items.gd +1 -1
- package/build/godot/addons/gdharness_runtime/runtime_menus.gd +3 -3
- package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +5 -5
- package/build/godot/addons/gdharness_runtime/runtime_paths.gd +20 -20
- package/build/godot/addons/gdharness_runtime/runtime_queries.gd +19 -13
- package/build/godot/addons/gdharness_runtime/runtime_says.gd +5 -5
- package/build/godot/addons/gdharness_runtime/runtime_targets.gd +39 -39
- package/build/godot/addons/gdharness_runtime/runtime_typing.gd +3 -3
- package/build/godot/addons/gdharness_runtime/runtime_values.gd +7 -7
- package/build/godot/addons/gdharness_runtime/runtime_waits.gd +8 -8
- package/build/godot/addons/gdharness_runtime/runtime_words.gd +5 -5
- package/build/godot/addons/gdharness_runtime/serialisation.gd +4 -4
- package/build/godot/addons/gdharness_tests/bench.gd +1 -1
- package/build/godot/addons/gdharness_tests/share.gd +6 -6
- package/build/godot/addons/gdharness_tests/suites.gd +1 -1
- package/build/godot/operations/audio_buses.gd +4 -4
- package/build/godot/operations/class_cache.gd +3 -3
- package/build/godot/operations/classdb_queries.gd +1 -1
- package/build/godot/operations/declared_values.gd +13 -13
- package/build/godot/operations/dependencies.gd +6 -6
- package/build/godot/operations/export_presets.gd +7 -7
- package/build/godot/operations/file_reads.gd +6 -6
- package/build/godot/operations/gdscript_analysis.gd +6 -6
- package/build/godot/operations/gdscript_authoring.gd +11 -11
- package/build/godot/operations/godot_operations.gd +1 -1
- package/build/godot/operations/import_pipeline.gd +12 -12
- package/build/godot/operations/input_actions.gd +3 -3
- package/build/godot/operations/logger.gd +1 -1
- package/build/godot/operations/plugins.gd +2 -2
- package/build/godot/operations/project_config.gd +11 -11
- package/build/godot/operations/project_validation.gd +1 -1
- package/build/godot/operations/property_paths.gd +3 -3
- package/build/godot/operations/property_values.gd +10 -10
- package/build/godot/operations/reading.gd +22 -18
- package/build/godot/operations/resource_files.gd +1 -1
- package/build/godot/operations/script_check.gd +2 -2
- package/build/godot/operations/serialisation.gd +4 -4
- package/build/godot/tests/listed.gd +9 -9
- package/build/keeper.js +511 -162
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ func set_editor_plugin(plugin: EditorPlugin) -> void:
|
|
|
28
28
|
# Shared helpers
|
|
29
29
|
# =============================================================================
|
|
30
30
|
## [param scene_path] opened for writing, with the node at [param node_path] in it, which must be a
|
|
31
|
-
## [param kind] the scene owns. Answers [scene, node, refusal]
|
|
31
|
+
## [param kind] the scene owns. Answers [scene, node, refusal]. The refusal is {} when both were
|
|
32
32
|
## found.
|
|
33
33
|
func _open_at(scene_path: String, node_path: String, kind: String) -> Array:
|
|
34
34
|
var scene: GdhSceneFile = GdhSceneFile.new()
|
|
@@ -143,7 +143,7 @@ func _parse_method_args(raw_args: Array) -> Array:
|
|
|
143
143
|
##
|
|
144
144
|
## A resource that is part of the scene file is saved with it. One kept in a .tres of its own was
|
|
145
145
|
## edited in memory while only the scene was saved, which refers to the file, so the edit was
|
|
146
|
-
## answered as made and was gone
|
|
146
|
+
## answered as made and was gone. It is saved too. One inside some other file (an imported model,
|
|
147
147
|
## the scene this one inherits from) is refused, since nothing written here would keep the edit.
|
|
148
148
|
func _homes(scene: GdhSceneFile, held: Array) -> Array:
|
|
149
149
|
var homes: Dictionary = {}
|
|
@@ -176,7 +176,7 @@ func _homes(scene: GdhSceneFile, held: Array) -> Array:
|
|
|
176
176
|
|
|
177
177
|
## The library a new animation called [param animation_name] goes in, as [library, why not, made]:
|
|
178
178
|
## the default one, or the one named before a slash, as the player names them ("moves/walk"). One
|
|
179
|
-
## the player lacks is made, built into the scene, and made says so
|
|
179
|
+
## the player lacks is made, built into the scene, and made says so. No other op makes a library,
|
|
180
180
|
## so refusing one left "moves/walk" with no way to be written.
|
|
181
181
|
func _library_for(player: AnimationPlayer, animation_name: String) -> Array:
|
|
182
182
|
var library: String = ""
|
|
@@ -353,7 +353,7 @@ static func _name_refusal(animation_name: String) -> String:
|
|
|
353
353
|
if animation_name.count("/") > 1:
|
|
354
354
|
return (
|
|
355
355
|
(
|
|
356
|
-
"%s names a library and an animation in it with one slash, as moves/walk
|
|
356
|
+
"%s names a library and an animation in it with one slash, as moves/walk. A "
|
|
357
357
|
+ "library holds no libraries."
|
|
358
358
|
)
|
|
359
359
|
% animation_name
|
|
@@ -391,7 +391,7 @@ static func _past_sentence(
|
|
|
391
391
|
return ""
|
|
392
392
|
return (
|
|
393
393
|
(
|
|
394
|
-
"%s is %s s long, and %s past its end, where %s: %s. %s
|
|
394
|
+
"%s is %s s long, and %s past its end, where %s: %s. %s, and scene_animation set "
|
|
395
395
|
+ "with a longer length plays %s."
|
|
396
396
|
)
|
|
397
397
|
% [
|
|
@@ -576,7 +576,7 @@ func rename_animation(args: Dictionary) -> Dictionary:
|
|
|
576
576
|
if not homes[0]:
|
|
577
577
|
return scene.refuse(str(homes[1]))
|
|
578
578
|
|
|
579
|
-
# Read before the rename, since the player moves its autoplay to the new name on its own
|
|
579
|
+
# Read before the rename, since the player moves its autoplay to the new name on its own. It
|
|
580
580
|
# does not clear one when an animation is removed.
|
|
581
581
|
var autoplayed: bool = str(player.autoplay) == animation_name
|
|
582
582
|
library.rename_animation(StringName(animation_name.trim_prefix(prefix)), StringName(new_name))
|
|
@@ -209,13 +209,13 @@ func _add_track(
|
|
|
209
209
|
for blending: String in ["interpolation", "loopWrap"]:
|
|
210
210
|
if track.has(blending):
|
|
211
211
|
return _not_added(
|
|
212
|
-
"track.%s is for property tracks
|
|
212
|
+
"track.%s is for property tracks. A method key is not blended." % blending
|
|
213
213
|
)
|
|
214
214
|
else:
|
|
215
215
|
return _not_added(
|
|
216
216
|
(
|
|
217
217
|
(
|
|
218
|
-
"add_track makes property and method tracks, and track.type is %s
|
|
218
|
+
"add_track makes property and method tracks, and track.type is %s. "
|
|
219
219
|
+ "remove_track takes any."
|
|
220
220
|
)
|
|
221
221
|
% track_type
|
|
@@ -240,7 +240,7 @@ func _add_track(
|
|
|
240
240
|
(
|
|
241
241
|
(
|
|
242
242
|
"Track %d already animates %s and has a key at %s s, which "
|
|
243
|
-
+ "keyframes[%d] would replace. Nothing was written
|
|
243
|
+
+ "keyframes[%d] would replace. Nothing was written. replaceKeys true "
|
|
244
244
|
+ "replaces it."
|
|
245
245
|
)
|
|
246
246
|
% [track_idx, str(path), _seconds(time), index]
|
|
@@ -408,10 +408,10 @@ static func _key_misfit(target: Node, method: String, arguments: Array, index: i
|
|
|
408
408
|
|
|
409
409
|
|
|
410
410
|
## Takes out the track [code]track[/code] names by its type, nodePath and property as read answers
|
|
411
|
-
## them, so a track read back can be passed as it stands
|
|
411
|
+
## them, so a track read back can be passed as it stands. Its keyframes are not looked at. Every
|
|
412
412
|
## track of that shape goes, since the editor can make two for one path and both play. A method
|
|
413
413
|
## track given a method loses only the keys calling it, since add_track puts every method called on
|
|
414
|
-
## one node in one track
|
|
414
|
+
## one node in one track. The track goes once no key is left.
|
|
415
415
|
func remove_animation_track(args: Dictionary) -> Dictionary:
|
|
416
416
|
var scene_path: String = GdhSceneFile.res_path("", str(args.get("scenePath", "")))
|
|
417
417
|
var player_node_path: String = str(args.get("playerNodePath", "."))
|
|
@@ -464,13 +464,13 @@ func remove_animation_track(args: Dictionary) -> Dictionary:
|
|
|
464
464
|
]
|
|
465
465
|
)
|
|
466
466
|
if held.is_empty():
|
|
467
|
-
return scene.refuse("%s
|
|
468
|
-
return scene.refuse("%s
|
|
467
|
+
return scene.refuse("%s. It has no tracks." % said)
|
|
468
|
+
return scene.refuse("%s. Its tracks are %s." % [said, ", ".join(held)])
|
|
469
469
|
var calling: Array = _keys_calling(anim, matching, method)
|
|
470
470
|
if calling.is_empty():
|
|
471
471
|
return scene.refuse(
|
|
472
472
|
(
|
|
473
|
-
"%s's method track on %s has no key calling %s
|
|
473
|
+
"%s's method track on %s has no key calling %s. Its keys call %s."
|
|
474
474
|
% [animation_name, node_path, method, ", ".join(_methods_called(anim, matching))]
|
|
475
475
|
)
|
|
476
476
|
)
|
|
@@ -585,7 +585,7 @@ static func _keys_at(anim: Animation, calling: Array, times: Array) -> Array:
|
|
|
585
585
|
return [
|
|
586
586
|
at,
|
|
587
587
|
(
|
|
588
|
-
"has no key at %s s
|
|
588
|
+
"has no key at %s s. Its keys are at %s s. Nothing was removed."
|
|
589
589
|
% [", ".join(named), ", ".join(held)]
|
|
590
590
|
),
|
|
591
591
|
]
|
|
@@ -14,7 +14,7 @@ extends Node
|
|
|
14
14
|
##
|
|
15
15
|
## Read off the editor's own filesystem entries rather than from
|
|
16
16
|
## `ProjectSettings.get_global_class_list()`. The entries are what the scan itself recorded, so
|
|
17
|
-
## nothing but a scan can change them
|
|
17
|
+
## nothing but a scan can change them. The settings list is loaded from the cache file when it is
|
|
18
18
|
## first asked for, which makes it a poor witness against a cache that was just rewritten, and
|
|
19
19
|
## rewriting the cache is the call most in need of an honest answer here.
|
|
20
20
|
##
|
|
@@ -98,7 +98,7 @@ func reload_script(args: Dictionary) -> Dictionary:
|
|
|
98
98
|
# read "because of a parser error" until the editor restarted, for as long as anything held the
|
|
99
99
|
# parse, such as a file open in an editor's language server. Compiling once with a line more
|
|
100
100
|
# makes the texts differ, which drops that parse and those of the scripts that resolved through
|
|
101
|
-
# it
|
|
101
|
+
# it. The file's own text is compiled below.
|
|
102
102
|
script.source_code = text + "\n"
|
|
103
103
|
var _dropped: Error = script.reload(true)
|
|
104
104
|
script.source_code = text
|
|
@@ -136,7 +136,7 @@ func reload_script(args: Dictionary) -> Dictionary:
|
|
|
136
136
|
## Which of [code]scriptPaths[/code] the editor holds a compiled copy of whose text is not the
|
|
137
137
|
## file's, without loading or reloading anything. A script compiled against such a copy fails on the
|
|
138
138
|
## members the file has gained, and a reload of it fails the same way until the copy is reloaded
|
|
139
|
-
## first
|
|
139
|
+
## first. The rescan that met this blamed the new classes the script also named, which were fine.
|
|
140
140
|
##
|
|
141
141
|
## Only a copy the editor already holds can be behind: one it has not loaded is compiled from the
|
|
142
142
|
## file when something asks for it. One open in a script tab with unsaved edits is answered apart,
|
|
@@ -10,12 +10,12 @@ var _editor_plugin: EditorPlugin = null
|
|
|
10
10
|
## How many scans the editor has completed, counted off `sources_changed`, which it emits at the end
|
|
11
11
|
## of every scan once the reimport the scan found is done: the one moment a scan is over. Neither
|
|
12
12
|
## flag it offers says so. A threaded scan stops reporting itself when its thread finishes, and its
|
|
13
|
-
## import runs a frame or more later when the thread is joined
|
|
13
|
+
## import runs a frame or more later when the thread is joined. An editor in the background took
|
|
14
14
|
## long enough over that frame that a rescan answered before the import of 211 changed scenes began.
|
|
15
15
|
var _scans_completed: int = 0
|
|
16
16
|
## When the last scan completed, on the engine's clock, or -1 before the first. The editor writes
|
|
17
17
|
## the class cache a frame after it stops reporting a scan, measured on 4.7.2, so a game started
|
|
18
|
-
## in between reads a file being rewritten
|
|
18
|
+
## in between reads a file being rewritten. How long ago the scan ended is what tells a caller
|
|
19
19
|
## whether that write can still be coming.
|
|
20
20
|
var _scan_finished_at_msec: int = -1
|
|
21
21
|
## How many reimports asked for through [method reimport_files] have finished. Counted here rather
|
|
@@ -63,7 +63,7 @@ func rescan_filesystem(args: Dictionary) -> Dictionary:
|
|
|
63
63
|
uids = _reread_changed_uids(filesystem)
|
|
64
64
|
# Files the caller has just written, moved or deleted, read again one by one. The scan finds
|
|
65
65
|
# a script that appeared and leaves the global class of one that has gone in the editor's
|
|
66
|
-
# list, which it then writes back into the class cache at a path that is not there
|
|
66
|
+
# list, which it then writes back into the class cache at a path that is not there. Reading
|
|
67
67
|
# the gone path again is what drops it.
|
|
68
68
|
var named: Variant = args.get("updateFiles", [])
|
|
69
69
|
if named is Array:
|
|
@@ -167,7 +167,7 @@ func scan_status(_args: Dictionary) -> Dictionary:
|
|
|
167
167
|
# The scenes open in tabs, the one shown and the ones holding unsaved edits: a scene edit on
|
|
168
168
|
# disk meets what the editor holds of it, and nothing said which scenes those were. A tab of a
|
|
169
169
|
# scene never saved has no path, and a new project's editor opens with an empty one, so it is
|
|
170
|
-
# left out of the open
|
|
170
|
+
# left out of the open. One with edits is kept among the unsaved, as the edits a close would
|
|
171
171
|
# lose.
|
|
172
172
|
var shown: Node = EditorInterface.get_edited_scene_root()
|
|
173
173
|
var open: Array[String] = []
|
|
@@ -226,7 +226,7 @@ func reimport_files(args: Dictionary) -> Dictionary:
|
|
|
226
226
|
## a move of its own: each cached resource and each open scene named for where it now is, so what
|
|
227
227
|
## holds them saves the new path, the editor's file list told of both ends, and each open scene that
|
|
228
228
|
## moved or that the move rewrote read again from the file. A scene with unsaved edits is left as it
|
|
229
|
-
## is and named, since reading it again would discard them
|
|
229
|
+
## is and named, since reading it again would discard them. Its root names the new path either way.
|
|
230
230
|
##
|
|
231
231
|
## A moved tab is read again even when its text did not change: the editor keeps each tab's path
|
|
232
232
|
## twice, on the root and in its own list, and a script can set only the first. The second is what
|
|
@@ -32,14 +32,14 @@ static func bake(scene: GdhSceneFile, region: Node) -> Dictionary:
|
|
|
32
32
|
scene
|
|
33
33
|
. refuse(
|
|
34
34
|
(
|
|
35
|
-
"%s is a %s, not a NavigationRegion2D or a NavigationRegion3D
|
|
35
|
+
"%s is a %s, not a NavigationRegion2D or a NavigationRegion3D. %s."
|
|
36
36
|
% [
|
|
37
37
|
at,
|
|
38
38
|
region.get_class(),
|
|
39
39
|
(
|
|
40
|
-
"
|
|
40
|
+
"The scene has none, and scene_node add puts one in"
|
|
41
41
|
if regions.is_empty()
|
|
42
|
-
else "
|
|
42
|
+
else "The scene's are at %s" % ", ".join(regions)
|
|
43
43
|
),
|
|
44
44
|
]
|
|
45
45
|
)
|
|
@@ -92,7 +92,7 @@ static func bake(scene: GdhSceneFile, region: Node) -> Dictionary:
|
|
|
92
92
|
answer["meshesNote"] = (
|
|
93
93
|
"The engine's warning that it had to parse RenderingServer meshes at runtime is about "
|
|
94
94
|
+ "a game rebaking as it runs, where reading a mesh back from the GPU stalls a frame. "
|
|
95
|
-
+ "A headless engine gives it for any bake read from MeshInstance3D nodes
|
|
95
|
+
+ "A headless engine gives it for any bake read from MeshInstance3D nodes. This one "
|
|
96
96
|
+ "ran once and is saved."
|
|
97
97
|
)
|
|
98
98
|
|
|
@@ -289,7 +289,7 @@ static func _nothing_read(scene: GdhSceneFile, held: Resource) -> String:
|
|
|
289
289
|
return said
|
|
290
290
|
return (
|
|
291
291
|
(
|
|
292
|
-
"%s %s %s outside what was read
|
|
292
|
+
"%s %s %s outside what was read. The bake reads a node elsewhere once it is in the "
|
|
293
293
|
+ "group %s and source_geometry_mode is groups_with_children, or once it is moved "
|
|
294
294
|
+ "under the region."
|
|
295
295
|
)
|
|
@@ -125,7 +125,7 @@ func play_scene(args: Dictionary) -> Dictionary:
|
|
|
125
125
|
## with put in front when [param hidden] says the editor is there: the server's `hiddenWindowFlags`
|
|
126
126
|
## gives the reason. Nothing is added for a game the arguments already play headless, and no cap
|
|
127
127
|
## where [param capped] says the project sets one or the arguments do. In front because a `--` in
|
|
128
|
-
## them makes everything after it the game's own
|
|
128
|
+
## them makes everything after it the game's own. After `%command%` when they hold one, since what
|
|
129
129
|
## goes before it is the command that runs the engine.
|
|
130
130
|
static func with_hidden_window_flags(held: String, hidden: bool, capped: bool) -> String:
|
|
131
131
|
var words: PackedStringArray = held.split(" ", false)
|
|
@@ -284,7 +284,7 @@ func quit_editor(_args: Dictionary) -> Dictionary:
|
|
|
284
284
|
## started again, so the answer carries the first attempt's reason as well as the next one's.
|
|
285
285
|
##
|
|
286
286
|
## The debug adapter binds as its node enters the tree, which is early in the editor's start and
|
|
287
|
-
## seconds before the language server, and does not try again
|
|
287
|
+
## seconds before the language server, and does not try again. Taking its node out of the tree and
|
|
288
288
|
## putting it back runs that start once more. The language server starts on the editor's first
|
|
289
289
|
## frame after it is ready and only once, so re-entering the tree would stop it for good, and it is
|
|
290
290
|
## never touched here.
|
|
@@ -12,7 +12,7 @@ extends Node
|
|
|
12
12
|
const GdhRead = preload("../reading.gd")
|
|
13
13
|
## The most functions a frame may carry when the server does not say. The engine names a function
|
|
14
14
|
## once, as it first appears, and the game's debugger queue drops those messages past its size, so
|
|
15
|
-
## the server keeps this below the queue the project sets
|
|
15
|
+
## the server keeps this below the queue the project sets. This is that for the engine's default.
|
|
16
16
|
const FRAME_FUNCTIONS: int = 1536
|
|
17
17
|
const DEBUGGER_CLASS: String = "ScriptEditorDebugger"
|
|
18
18
|
## What a quitting game sends after its profile's totals, and the answer it waits for. Kept in step
|
|
@@ -283,9 +283,9 @@ func modify_resource(args: Dictionary) -> Dictionary:
|
|
|
283
283
|
if res_path == "res://":
|
|
284
284
|
return { "ok": false, "error": "resourcePath is required" }
|
|
285
285
|
if not FileAccess.file_exists(res_path):
|
|
286
|
-
return { "ok": false, "error": "No resource at %s
|
|
286
|
+
return { "ok": false, "error": "No resource at %s. op=create makes one there." % res_path }
|
|
287
287
|
# The editor's copy of an imported file is rebuilt from the source on every import, and a save
|
|
288
|
-
# to it fails
|
|
288
|
+
# to it fails. Edited through the cache, the editor kept the changed copy after the refusal.
|
|
289
289
|
if FileAccess.file_exists(res_path + ".import"):
|
|
290
290
|
return {
|
|
291
291
|
"ok": false,
|
|
@@ -570,7 +570,7 @@ func set_theme_font_size(args: Dictionary) -> Dictionary:
|
|
|
570
570
|
)
|
|
571
571
|
|
|
572
572
|
|
|
573
|
-
## Takes one item, such as "colors/font_color"
|
|
573
|
+
## Takes one item, such as `"colors/font_color"`, or with none every item of a theme type, out of a
|
|
574
574
|
## Theme: a type is any name, so a misspelt one is written as given, and this is the way back.
|
|
575
575
|
func remove_theme_item(args: Dictionary) -> Dictionary:
|
|
576
576
|
var theme_path: String = _ensure_res_path(str(args.get("resourcePath", "")))
|
|
@@ -601,8 +601,8 @@ func remove_theme_item(args: Dictionary) -> Dictionary:
|
|
|
601
601
|
theme.remove_type(control_type)
|
|
602
602
|
elif removed.is_empty() and held.is_empty():
|
|
603
603
|
var only: String = (
|
|
604
|
-
"%s holds no items, only the type it varies, %s
|
|
605
|
-
+ "
|
|
604
|
+
"%s holds no items, only the type it varies, %s. "
|
|
605
|
+
+ "Without item, remove_theme_item takes it out."
|
|
606
606
|
)
|
|
607
607
|
return { "ok": false, "error": only % [control_type, base] }
|
|
608
608
|
elif removed.is_empty():
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@tool
|
|
2
2
|
extends RefCounted
|
|
3
3
|
## The groups a node of a scene is in. A scene's own file puts a node in a group and can take it
|
|
4
|
-
## out of one it put it in
|
|
4
|
+
## out of one it put it in. A group the scene that makes the node puts it in, the one it is
|
|
5
5
|
## instanced from or one this scene inherits, can be changed only there, as the editor's group dock
|
|
6
6
|
## shows it locked.
|
|
7
7
|
|
|
@@ -63,11 +63,11 @@ static func change(scene: GdhSceneFile, node: Node, adding: Array, removing: Arr
|
|
|
63
63
|
if not node.is_in_group(name):
|
|
64
64
|
var held: Array = _sorted(node.get_groups())
|
|
65
65
|
return (
|
|
66
|
-
"%s is in no group %s
|
|
66
|
+
"%s is in no group %s. %s."
|
|
67
67
|
% [
|
|
68
68
|
node.name,
|
|
69
69
|
name,
|
|
70
|
-
"
|
|
70
|
+
"It is in " + ", ".join(held) if not held.is_empty() else "It is in none",
|
|
71
71
|
]
|
|
72
72
|
)
|
|
73
73
|
if not here.has(name):
|
|
@@ -151,7 +151,7 @@ static func inherit(
|
|
|
151
151
|
|
|
152
152
|
## Makes the children of [param node], an instance in [param scene], editable or not, answering why
|
|
153
153
|
## it cannot or "". With them editable the scene keeps its own values for them, as the editor's
|
|
154
|
-
## Editable Children does
|
|
154
|
+
## Editable Children does. Made not editable again, the values it kept for them are dropped. The
|
|
155
155
|
## caller has had [method GdhSceneFile.foreign] refuse a node inside an instance that is not
|
|
156
156
|
## editable.
|
|
157
157
|
static func set_editable(scene: GdhSceneFile, node: Node, editable: bool) -> String:
|
|
@@ -171,7 +171,7 @@ static func set_editable(scene: GdhSceneFile, node: Node, editable: bool) -> Str
|
|
|
171
171
|
## the new path. The engine finds
|
|
172
172
|
## a moved node's entries by its unique_id, but an editable instance only by its path, so a scene
|
|
173
173
|
## saved after the move lost the values it kept below one. The node paths each holds are carried
|
|
174
|
-
## into [param carried], which holds those of [param changed] already
|
|
174
|
+
## into [param carried], which holds those of [param changed] already. With [param new_path] "",
|
|
175
175
|
## for a node deleted, they are only named. Answers followed, the scenes rewritten, and
|
|
176
176
|
## notFollowed, each one left as it was with why, each only when it names any, with what
|
|
177
177
|
## [param carried] gives.
|
|
@@ -312,7 +312,7 @@ static func _instances_of(
|
|
|
312
312
|
## [param text] with every path [param moves] names, and every path below one, moved.
|
|
313
313
|
##
|
|
314
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
|
|
315
|
+
## when the path has vanished. A rename leaves those ids as they were. With [param reparented] they
|
|
316
316
|
## run through the old parent, which still exists, so a recovery would find the wrong node. They are
|
|
317
317
|
## left out of each path moved, as a hand-written scene leaves them, and the next save writes them
|
|
318
318
|
## anew.
|
|
@@ -265,8 +265,8 @@ static func _names_nodes(property: Dictionary) -> bool:
|
|
|
265
265
|
|
|
266
266
|
|
|
267
267
|
## Carries the property [param name] of [param node], typed as nodes, from [param held], the paths
|
|
268
|
-
## the file gives it. The nodes it holds moved with the move, so only what the file held is named
|
|
269
|
-
##
|
|
268
|
+
## the file gives it. The nodes it holds moved with the move, so only what the file held is named.
|
|
269
|
+
## Marking it asked lets the write save the new paths the pack gives. A node the move deleted is
|
|
270
270
|
## cleared, as the editor's save clears it, since no path reaches it.
|
|
271
271
|
func _carry_nodes(
|
|
272
272
|
node: Node, name: String, held: Variant, was: String, now: String, entry: Dictionary
|
|
@@ -304,7 +304,7 @@ static func _unfreed(value: Variant) -> Variant:
|
|
|
304
304
|
## [param value], held by the node that was at [param was] and is at [param now], with each path in
|
|
305
305
|
## it carried, as [whether any was, the value]. A resource built into the scene is changed in place.
|
|
306
306
|
## [param entry] says where the value is held, for the record of each path. A path in a resource may
|
|
307
|
-
## be relative to something other than its holder, as the editor allows
|
|
307
|
+
## be relative to something other than its holder, as the editor allows. It is followed only when it
|
|
308
308
|
## names a node from where its holder was, as one relative to the holder does. A value
|
|
309
309
|
## [param elsewhere], a file other than the scene's, gives is named only when it names nothing since
|
|
310
310
|
## the move, which its own file's pass could not see.
|
|
@@ -539,7 +539,7 @@ func _tracks(mixer: AnimationMixer, now: String) -> void:
|
|
|
539
539
|
|
|
540
540
|
## Where an edit to [param animation], played from [param library], is saved, as {file, home, why,
|
|
541
541
|
## theirs}: file "" with the scene, or the file of its own it or its library is kept in, with home
|
|
542
|
-
## the resource saved there
|
|
542
|
+
## the resource saved there, why when nothing written here would keep the edit, and theirs when that
|
|
543
543
|
## is because it is kept in another scene or an imported file, whose tracks are written in its
|
|
544
544
|
## terms.
|
|
545
545
|
func _home_of(animation: Animation, library: AnimationLibrary) -> Dictionary:
|
|
@@ -19,7 +19,7 @@ static func what_to_add(node_type: String, instance_path: String, scene_path: St
|
|
|
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
|
|
22
|
-
# was not there
|
|
22
|
+
# was not there and laid the engine's error and a backtrace beneath the refusal.
|
|
23
23
|
if not ResourceLoader.exists(instance_path, "PackedScene"):
|
|
24
24
|
var said: String = "No scene at %s to instance" % instance_path
|
|
25
25
|
var offered: String = GdhFileWalk.new().with_nearest_files(said, instance_path)
|
|
@@ -65,7 +65,7 @@ static func not_a_node_class(argument: String, given: String) -> String:
|
|
|
65
65
|
var close: PackedStringArray = GdhRead.nearest(given, classes)
|
|
66
66
|
if close.is_empty():
|
|
67
67
|
return said + "."
|
|
68
|
-
return "%s
|
|
68
|
+
return "%s. The nearest %s %s." % [said, "is" if close.size() == 1 else "are", ", ".join(close)]
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
## A new node of [param node_type], or an instance of [param packed] when there is one. The instance
|
|
@@ -202,7 +202,7 @@ static func place(node: Node, asked: Variant) -> void:
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
## Whether [param basis] has axes that are not at right angles, which a node kept in place under a
|
|
205
|
-
## parent scaled unevenly across its turn ends up with. A Node2D says so through skew
|
|
205
|
+
## parent scaled unevenly across its turn ends up with. A Node2D says so through skew. A Node3D has
|
|
206
206
|
## no property for it, and its position, rotation and scale read as if the axes were square.
|
|
207
207
|
static func sheared(basis: Basis) -> bool:
|
|
208
208
|
var x: Vector3 = basis.x.normalized()
|
|
@@ -46,7 +46,7 @@ func _kept(scene: GdhSceneFile, saved: Node, node: Node, names: Array) -> String
|
|
|
46
46
|
var given: Variant = _properties.read_at(node, property)
|
|
47
47
|
if not scene.kept(saved, loaded, given):
|
|
48
48
|
# The file holds it, and the copy's own script set it again as the copy loaded, as it
|
|
49
|
-
# will wherever the scene loads
|
|
49
|
+
# will wherever the scene loads. An editor saves the same.
|
|
50
50
|
if scene.stores(at, property, given):
|
|
51
51
|
var on: Dictionary = scene.loads_as.get_or_add(at, {})
|
|
52
52
|
if GdhHeadlessCheck.untooled(copy.get_script()):
|
|
@@ -417,7 +417,7 @@ func delete_node(args: Dictionary) -> Dictionary:
|
|
|
417
417
|
|
|
418
418
|
|
|
419
419
|
## The connections [param scene]'s file holds from or to [param at] or a node under it, which go
|
|
420
|
-
## with the node
|
|
420
|
+
## with the node. One an instanced scene makes inside itself is that scene's, and stays there.
|
|
421
421
|
static func _connections_with(scene: GdhSceneFile, at: String) -> Array[Dictionary]:
|
|
422
422
|
var cut: Array[Dictionary] = []
|
|
423
423
|
for held: Dictionary in scene.held_connections():
|
|
@@ -880,7 +880,7 @@ func get_node_properties(args: Dictionary) -> Dictionary:
|
|
|
880
880
|
|
|
881
881
|
# Against the default the node would have in no scene: its script's for what the script
|
|
882
882
|
# declares, the class's for the rest. Compared with a bare instance of the class, every exported
|
|
883
|
-
# variable read as changed
|
|
883
|
+
# variable read as changed, and a value this scene sets back to the default was hidden, so the
|
|
884
884
|
# names this scene's file sets are always answered.
|
|
885
885
|
var set_here: Dictionary = scene.set_here(node)
|
|
886
886
|
var props: Dictionary = _properties_of(node, include_defaults, set_here)
|
|
@@ -898,8 +898,8 @@ func get_node_properties(args: Dictionary) -> Dictionary:
|
|
|
898
898
|
var turned: Basis = Basis.from_euler(placed.rotation, placed.rotation_order)
|
|
899
899
|
rebuilt = Transform3D(turned * Basis.from_scale(placed.scale), placed.position)
|
|
900
900
|
if placed != null and props.has("transform") and rebuilt.is_equal_approx(placed.transform):
|
|
901
|
-
# Rounded, since a node never scaled came back with a scale of 0.99999994 out of the matrix
|
|
902
|
-
#
|
|
901
|
+
# Rounded, since a node never scaled came back with a scale of 0.99999994 out of the matrix.
|
|
902
|
+
# The transform beside it is exact.
|
|
903
903
|
var step: Vector3 = Vector3.ONE * 0.00001
|
|
904
904
|
answer["placement"] = {
|
|
905
905
|
"position": _readable(node, placed.position.snapped(step)),
|
|
@@ -920,7 +920,7 @@ func get_node_properties(args: Dictionary) -> Dictionary:
|
|
|
920
920
|
answer["busNote"] = (
|
|
921
921
|
(
|
|
922
922
|
"%s names the bus %s, which the project's bus layout does not have, so it plays on "
|
|
923
|
-
+ "%s
|
|
923
|
+
+ "%s. The buses are %s."
|
|
924
924
|
)
|
|
925
925
|
% [
|
|
926
926
|
str(node.name) if at == "." else at,
|
|
@@ -949,14 +949,14 @@ func get_node_properties(args: Dictionary) -> Dictionary:
|
|
|
949
949
|
answer["instanceOf"] = node.scene_file_path
|
|
950
950
|
answer["editableChildren"] = scene.root.is_editable_instance(node)
|
|
951
951
|
scene.close()
|
|
952
|
-
# Only an editor holds anything unsaved
|
|
952
|
+
# Only an editor holds anything unsaved. A headless engine answering false would say it looked.
|
|
953
953
|
if Engine.is_editor_hint():
|
|
954
954
|
answer["unsavedInEditor"] = GdhSceneFile.unsaved(scene_path)
|
|
955
955
|
answer.merge(cells)
|
|
956
956
|
# An empty answer read as a node with nothing on it, rather than one with nothing changed.
|
|
957
957
|
if props.is_empty() and not include_defaults:
|
|
958
958
|
answer["note"] = (
|
|
959
|
-
"Every property of this node is at its default, so none is listed
|
|
959
|
+
"Every property of this node is at its default, so none is listed. "
|
|
960
960
|
+ "includeDefaults: true lists them all."
|
|
961
961
|
)
|
|
962
962
|
return answer
|
|
@@ -1004,8 +1004,8 @@ func save_scene(args: Dictionary) -> Dictionary:
|
|
|
1004
1004
|
return _save_open_scene(scene_path)
|
|
1005
1005
|
|
|
1006
1006
|
# Of the editor's scene when it is open, since that is what a save means, and of the file as it
|
|
1007
|
-
# loads otherwise. The editor's scene is packed where it is, as the editor's own save packs it
|
|
1008
|
-
#
|
|
1007
|
+
# loads otherwise. The editor's scene is packed where it is, as the editor's own save packs it.
|
|
1008
|
+
# Packing leaves the nodes as they were.
|
|
1009
1009
|
var written: Dictionary = {}
|
|
1010
1010
|
if open_root != null:
|
|
1011
1011
|
var packed: PackedScene = PackedScene.new()
|
|
@@ -138,7 +138,7 @@ func connect_signal(args: Dictionary) -> Dictionary:
|
|
|
138
138
|
"flags": saved_flags,
|
|
139
139
|
"flagNames": flag_names(saved_flags),
|
|
140
140
|
# Connected either way, as the editor's own dialog allows, since the method may be written
|
|
141
|
-
# next
|
|
141
|
+
# next. A caller told nothing learnt of a misspelt one only when the signal fired.
|
|
142
142
|
"methodFound": method_found,
|
|
143
143
|
}
|
|
144
144
|
# Written all the same, for the reason a missing method is: the method may be changed next.
|
|
@@ -72,7 +72,7 @@ func create_tileset(args: Dictionary) -> Dictionary:
|
|
|
72
72
|
return { "ok": false, "error": built[1] }
|
|
73
73
|
var atlas: TileSetAtlasSource = built[1]
|
|
74
74
|
# The first source sets the tile set's own tile size, which is what a TileMapLayer draws
|
|
75
|
-
# cells at
|
|
75
|
+
# cells at. Left at its default of 16 it did not match the atlas.
|
|
76
76
|
if index == 0:
|
|
77
77
|
tileset.tile_size = atlas.texture_region_size
|
|
78
78
|
var added: int = tileset.add_source(atlas)
|
|
@@ -288,7 +288,7 @@ func set_tilemap_cells(args: Dictionary) -> Dictionary:
|
|
|
288
288
|
var _named: bool = refusals.append(str(cell[1]))
|
|
289
289
|
checked.append(cell)
|
|
290
290
|
if not refusals.is_empty():
|
|
291
|
-
return scene.refuse("%s. Nothing was placed." % "
|
|
291
|
+
return scene.refuse("%s. Nothing was placed." % ". ".join(refusals))
|
|
292
292
|
var wanted: Array = []
|
|
293
293
|
var erased: int = 0
|
|
294
294
|
for cell: Array in checked:
|
|
@@ -354,7 +354,7 @@ func _tile_node(scene: GdhSceneFile, node_path: String, layer: int) -> Array:
|
|
|
354
354
|
if single != null and layer != 0:
|
|
355
355
|
return [
|
|
356
356
|
null,
|
|
357
|
-
"%s is a TileMapLayer, which is one layer
|
|
357
|
+
"%s is a TileMapLayer, which is one layer. layer applies to a TileMap" % node_path,
|
|
358
358
|
]
|
|
359
359
|
if layered != null and (layer < 0 or layer >= layered.get_layers_count()):
|
|
360
360
|
return [
|
|
@@ -407,7 +407,7 @@ func _cell(entry: Variant, index: int, tile_set: TileSet) -> Array:
|
|
|
407
407
|
return [
|
|
408
408
|
false,
|
|
409
409
|
(
|
|
410
|
-
"%s names source %d, and the TileSet has %s
|
|
410
|
+
"%s names source %d, and the TileSet has %s. sourceId -1 erases a cell"
|
|
411
411
|
% [named, source_id, _sources_of(tile_set)]
|
|
412
412
|
),
|
|
413
413
|
]
|
|
@@ -418,7 +418,7 @@ func _cell(entry: Variant, index: int, tile_set: TileSet) -> Array:
|
|
|
418
418
|
return [
|
|
419
419
|
false,
|
|
420
420
|
(
|
|
421
|
-
"%s: source %d has no tile at %s
|
|
421
|
+
"%s: source %d has no tile at %s. It has %s"
|
|
422
422
|
% [named, source_id, atlas_coords, _tiles_of(source)]
|
|
423
423
|
),
|
|
424
424
|
]
|
|
@@ -288,7 +288,7 @@ static func outside(target: Object, declared: Dictionary, value: Variant, shown:
|
|
|
288
288
|
return ""
|
|
289
289
|
return (
|
|
290
290
|
(
|
|
291
|
-
"%s is none of the names %s lists: %s, which the inspector holds it to
|
|
291
|
+
"%s is none of the names %s lists: %s, which the inspector holds it to. The engine "
|
|
292
292
|
+ "stores it as given."
|
|
293
293
|
)
|
|
294
294
|
% [shown, property, ", ".join(names)]
|
|
@@ -311,7 +311,7 @@ static func outside(target: Object, declared: Dictionary, value: Variant, shown:
|
|
|
311
311
|
if flags.is_empty() or stray == 0:
|
|
312
312
|
return ""
|
|
313
313
|
return (
|
|
314
|
-
"%d holds bits no flag of %s has (%d): its flags are %s
|
|
314
|
+
"%d holds bits no flag of %s has (%d): its flags are %s. The engine stores it as given."
|
|
315
315
|
% [whole, property, stray, _listed(flags)]
|
|
316
316
|
)
|
|
317
317
|
if hint != PROPERTY_HINT_RANGE:
|
|
@@ -327,7 +327,7 @@ static func outside(target: Object, declared: Dictionary, value: Variant, shown:
|
|
|
327
327
|
return ""
|
|
328
328
|
return (
|
|
329
329
|
(
|
|
330
|
-
"%s is outside the range %s declares, %s to %s, which the inspector holds it to
|
|
330
|
+
"%s is outside the range %s declares, %s to %s, which the inspector holds it to. The "
|
|
331
331
|
+ "engine stores it as given."
|
|
332
332
|
)
|
|
333
333
|
% [shown, property, _bound(low), _bound(high)]
|
|
@@ -544,7 +544,7 @@ static func not_held(
|
|
|
544
544
|
return (
|
|
545
545
|
(
|
|
546
546
|
"%s.bus takes the name of one of the project's audio buses, and %s is none of "
|
|
547
|
-
+ "them, so it would play on %s
|
|
547
|
+
+ "them, so it would play on %s. %s. project_info include audio_buses lists them, "
|
|
548
548
|
+ "and project_settings add_audio_bus adds one. Nothing was written."
|
|
549
549
|
)
|
|
550
550
|
% [
|
|
@@ -552,21 +552,21 @@ static func not_held(
|
|
|
552
552
|
given[1],
|
|
553
553
|
AudioServer.get_bus_name(0),
|
|
554
554
|
(
|
|
555
|
-
"
|
|
555
|
+
"The buses are " + ", ".join(names)
|
|
556
556
|
if nearest.is_empty()
|
|
557
|
-
else "
|
|
557
|
+
else "The nearest " + nearest
|
|
558
558
|
),
|
|
559
559
|
]
|
|
560
560
|
)
|
|
561
561
|
return (
|
|
562
|
-
"%s: it takes one of the names it lists, and %s is none of them
|
|
562
|
+
"%s: it takes one of the names it lists, and %s is none of them. %s. Nothing was written."
|
|
563
563
|
% [
|
|
564
564
|
said,
|
|
565
565
|
given[1],
|
|
566
566
|
(
|
|
567
|
-
"
|
|
567
|
+
"It lists " + ", ".join(names)
|
|
568
568
|
if nearest.is_empty()
|
|
569
|
-
else "
|
|
569
|
+
else "The nearest it lists " + nearest
|
|
570
570
|
),
|
|
571
571
|
]
|
|
572
572
|
)
|
|
@@ -593,7 +593,7 @@ static func held_by_children(node: Node, property: String) -> String:
|
|
|
593
593
|
|
|
594
594
|
## A sentence for each node path in [param given], by property, that names no node from
|
|
595
595
|
## [param node]. A path is written whatever it names, as the inspector writes one, since the node
|
|
596
|
-
## may be added next
|
|
596
|
+
## may be added next. A joint whose node_a named nothing then joined nothing, and no answer said so.
|
|
597
597
|
static func naming_nothing(node: Node, given: Dictionary) -> Dictionary:
|
|
598
598
|
var said: Dictionary = {}
|
|
599
599
|
for property: String in given:
|
|
@@ -610,7 +610,7 @@ static func naming_nothing(node: Node, given: Dictionary) -> Dictionary:
|
|
|
610
610
|
said[property] = (
|
|
611
611
|
(
|
|
612
612
|
"%s names no node from %s. It is written, as the editor writes one, since that "
|
|
613
|
-
+ "node may be added next
|
|
613
|
+
+ "node may be added next. Until it is, %s finds nothing."
|
|
614
614
|
)
|
|
615
615
|
% [str(named), node.name, property]
|
|
616
616
|
)
|
|
@@ -624,7 +624,7 @@ static func no_uniform(material: ShaderMaterial, property: String) -> String:
|
|
|
624
624
|
var uniform: String = property.trim_prefix("shader_parameter/")
|
|
625
625
|
if material.shader == null:
|
|
626
626
|
return (
|
|
627
|
-
"The ShaderMaterial has no shader, so it has no parameter %s yet
|
|
627
|
+
"The ShaderMaterial has no shader, so it has no parameter %s yet. Set shader first."
|
|
628
628
|
% uniform
|
|
629
629
|
)
|
|
630
630
|
var shader: String = material.shader.resource_path
|
|
@@ -634,5 +634,5 @@ static func no_uniform(material: ShaderMaterial, property: String) -> String:
|
|
|
634
634
|
uniforms.append(str(entry["name"]))
|
|
635
635
|
var said: String = "%s declares no uniform %s, which %s would set" % [named, uniform, property]
|
|
636
636
|
if uniforms.is_empty():
|
|
637
|
-
return said + "
|
|
637
|
+
return said + ". It declares no uniforms."
|
|
638
638
|
return GdhRead.offered(said, uniform, uniforms) + "."
|