gdharness 1.3.41 → 1.3.43
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/build/cli.js +131 -47
- package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
- package/build/godot/addons/gdharness_editor/animation_reads.gd +84 -35
- package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
- package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
- package/build/godot/addons/gdharness_editor/file_reads.gd +114 -39
- package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
- package/build/godot/addons/gdharness_editor/headless_check.gd +94 -41
- package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
- package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
- package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
- package/build/godot/addons/gdharness_editor/reading.gd +37 -12
- package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
- package/build/godot/addons/gdharness_editor/scene_file.gd +136 -79
- package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
- package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
- package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
- package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
- package/build/godot/addons/gdharness_editor/tools/animation_states.gd +41 -28
- package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +84 -50
- package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
- package/build/godot/addons/gdharness_editor/tools/class_tools.gd +34 -30
- package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
- package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
- package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
- package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
- package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +181 -107
- package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
- package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +75 -43
- package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
- package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
- package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +66 -0
- package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd.uid +1 -0
- package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +171 -62
- package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
- package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
- package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
- package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
- package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
- package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
- package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
- package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
- package/build/godot/addons/gdharness_runtime/reading.gd +37 -12
- package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
- package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +153 -148
- package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
- package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
- package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
- package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
- package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
- package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
- package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
- package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +38 -20
- package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
- package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
- package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
- package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
- package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
- package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
- package/build/godot/addons/gdharness_runtime/runtime_touch.gd +211 -0
- package/build/godot/addons/gdharness_runtime/runtime_touch.gd.uid +1 -0
- package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
- package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
- package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
- package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
- package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
- package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
- package/build/godot/addons/gdharness_tests/bench.gd +4 -5
- package/build/godot/addons/gdharness_tests/event.gd +10 -5
- package/build/godot/addons/gdharness_tests/share.gd +38 -18
- package/build/godot/addons/gdharness_tests/suites.gd +3 -3
- package/build/godot/addons/gdharness_tests/wait.gd +3 -2
- package/build/godot/loader/loader.gd +9 -9
- package/build/godot/operations/animation_reads.gd +84 -35
- package/build/godot/operations/audio_buses.gd +48 -19
- package/build/godot/operations/class_cache.gd +16 -11
- package/build/godot/operations/classdb_queries.gd +89 -44
- package/build/godot/operations/declared_values.gd +68 -32
- package/build/godot/operations/dependencies.gd +139 -93
- package/build/godot/operations/editor_tools.gd +9 -10
- package/build/godot/operations/export_presets.gd +100 -54
- package/build/godot/operations/file_reads.gd +114 -39
- package/build/godot/operations/file_walk.gd +12 -5
- package/build/godot/operations/gdscript_analysis.gd +105 -66
- package/build/godot/operations/gdscript_authoring.gd +138 -39
- package/build/godot/operations/godot_operations.gd +17 -11
- package/build/godot/operations/import_pipeline.gd +110 -59
- package/build/godot/operations/input_actions.gd +63 -39
- package/build/godot/operations/patterns.gd +3 -1
- package/build/godot/operations/plugins.gd +36 -16
- package/build/godot/operations/project_config.gd +144 -27
- package/build/godot/operations/project_diagnostics.gd +24 -11
- package/build/godot/operations/project_file.gd +16 -16
- package/build/godot/operations/project_validation.gd +71 -44
- package/build/godot/operations/property_paths.gd +22 -12
- package/build/godot/operations/property_values.gd +143 -78
- package/build/godot/operations/reading.gd +37 -12
- package/build/godot/operations/rename_checks.gd +2 -2
- package/build/godot/operations/resource_files.gd +11 -9
- package/build/godot/operations/same_values.gd +4 -4
- package/build/godot/operations/scene_connections.gd +27 -13
- package/build/godot/operations/script_check.gd +52 -49
- package/build/godot/operations/serialisation.gd +75 -51
- package/build/godot/operations/setting_reads.gd +7 -6
- package/build/godot/operations/value_shapes.gd +5 -6
- package/build/godot/tests/listed.gd +321 -268
- package/package.json +1 -1
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
@tool
|
|
2
2
|
extends RefCounted
|
|
3
|
-
|
|
4
|
-
##
|
|
5
|
-
## written.
|
|
3
|
+
## What a write made by a headless engine has to put back so the file holds what an editor would
|
|
4
|
+
## have written.
|
|
6
5
|
##
|
|
7
|
-
## The editor runs only tool scripts and gives every other script a placeholder that holds values
|
|
8
|
-
## runs nothing. A headless engine runs them all, so loading a file runs each script's
|
|
6
|
+
## The editor runs only tool scripts and gives every other script a placeholder that holds values
|
|
7
|
+
## and runs nothing. A headless engine runs them all, so loading a file runs each script's
|
|
9
8
|
## [code]_init[/code] and every setter of a stored property, and a tool setting one runs its setter.
|
|
10
9
|
## Whatever those change is saved with the write unless it is put back. Godot's own setters run in
|
|
11
10
|
## both, so a property a built-in setter derives (a Control's offsets from its size) is left alone
|
|
@@ -14,10 +13,9 @@ extends RefCounted
|
|
|
14
13
|
const GdhPropertyPaths = preload("property_paths.gd")
|
|
15
14
|
const GdhRead = preload("reading.gd")
|
|
16
15
|
const GdhSame = preload("same_values.gd")
|
|
17
|
-
|
|
18
16
|
const REMEDY: String = (
|
|
19
|
-
"Open the project's editor (editor_launch with hidden: true) and ask again: the write then
|
|
20
|
-
+ "through it, and the editor runs no script that is not a tool."
|
|
17
|
+
"Open the project's editor (editor_launch with hidden: true) and ask again: the write then "
|
|
18
|
+
+ "goes through it, and the editor runs no script that is not a tool."
|
|
21
19
|
)
|
|
22
20
|
|
|
23
21
|
|
|
@@ -76,7 +74,7 @@ static func kept_by_engine(object: Object, name: String, wanted: Variant, held:
|
|
|
76
74
|
not GdhSame.same(object.get(name), wanted)
|
|
77
75
|
and GdhSame.same(object.get(name), held)
|
|
78
76
|
and name != "script"
|
|
79
|
-
and not through_script(object, {name: true})
|
|
77
|
+
and not through_script(object, { name: true })
|
|
80
78
|
)
|
|
81
79
|
|
|
82
80
|
|
|
@@ -155,7 +153,7 @@ static func reached(object: Object, property: String) -> Dictionary:
|
|
|
155
153
|
name = name.get_slice(":", 0)
|
|
156
154
|
var id: String = holder.get_scene_unique_id()
|
|
157
155
|
if not id.is_empty():
|
|
158
|
-
ids[id] = {name: true}
|
|
156
|
+
ids[id] = { name: true }
|
|
159
157
|
return ids
|
|
160
158
|
|
|
161
159
|
|
|
@@ -175,7 +173,8 @@ static func spare(into: Dictionary, more: Dictionary) -> void:
|
|
|
175
173
|
into[id] = given
|
|
176
174
|
|
|
177
175
|
|
|
178
|
-
## Whether [param object] holds, at any depth, an embedded resource with a script that is not a
|
|
176
|
+
## Whether [param object] holds, at any depth, an embedded resource with a script that is not a
|
|
177
|
+
## tool.
|
|
179
178
|
static func holds_scripted_embedded(object: Object, seen: Dictionary) -> bool:
|
|
180
179
|
for value: Variant in stored(object).values():
|
|
181
180
|
for resource: Resource in resources_in(value):
|
|
@@ -219,7 +218,9 @@ static func put_back(file_path: String, previous: Variant) -> String:
|
|
|
219
218
|
return " Putting the file back as it was failed too."
|
|
220
219
|
file.close()
|
|
221
220
|
if ResourceLoader.has_cached(file_path):
|
|
222
|
-
var _replaced: Resource = ResourceLoader.load(
|
|
221
|
+
var _replaced: Resource = ResourceLoader.load(
|
|
222
|
+
file_path, "", ResourceLoader.CACHE_MODE_REPLACE
|
|
223
|
+
)
|
|
223
224
|
elif DirAccess.remove_absolute(ProjectSettings.globalize_path(file_path)) != OK:
|
|
224
225
|
return " Removing the file it wrote failed too."
|
|
225
226
|
return ""
|
|
@@ -235,14 +236,14 @@ static func sections(text: String) -> Dictionary:
|
|
|
235
236
|
for line: String in text.split("\n"):
|
|
236
237
|
if line.begins_with("["):
|
|
237
238
|
if not key.is_empty():
|
|
238
|
-
found[key] = {"head": head, "lines": lines}
|
|
239
|
+
found[key] = { "head": head, "lines": lines }
|
|
239
240
|
lines = []
|
|
240
241
|
head = line
|
|
241
242
|
key = _section_key(line)
|
|
242
243
|
continue
|
|
243
244
|
var _kept: bool = lines.append(line)
|
|
244
245
|
if not key.is_empty():
|
|
245
|
-
found[key] = {"head": head, "lines": lines}
|
|
246
|
+
found[key] = { "head": head, "lines": lines }
|
|
246
247
|
return found
|
|
247
248
|
|
|
248
249
|
|
|
@@ -257,8 +258,8 @@ static func _section_key(head: String) -> String:
|
|
|
257
258
|
return ""
|
|
258
259
|
|
|
259
260
|
|
|
260
|
-
## Each property a section sets, by name, to the text of its value. A value running over several
|
|
261
|
-
## is kept whole.
|
|
261
|
+
## Each property a section sets, by name, to the text of its value. A value running over several
|
|
262
|
+
## lines is kept whole.
|
|
262
263
|
static func entries_of(section: Dictionary) -> Dictionary:
|
|
263
264
|
var lines: PackedStringArray = section.get("lines", PackedStringArray())
|
|
264
265
|
return entries(lines)
|
|
@@ -315,7 +316,8 @@ static func _main_entries(text: String) -> Dictionary:
|
|
|
315
316
|
return entries_of(main)
|
|
316
317
|
|
|
317
318
|
|
|
318
|
-
## The ids of the embedded resources in [param text] that carry a script that is not a tool, as a
|
|
319
|
+
## The ids of the embedded resources in [param text] that carry a script that is not a tool, as a
|
|
320
|
+
## set.
|
|
319
321
|
static func scripted_sections(text: String) -> Dictionary:
|
|
320
322
|
var all: Dictionary = sections(text)
|
|
321
323
|
var scripts: Dictionary = {}
|
|
@@ -349,7 +351,9 @@ static func scripted_sections(text: String) -> Dictionary:
|
|
|
349
351
|
## null]. Only those with a script that is not a tool are compared, since only a script runs
|
|
350
352
|
## differently here, and what [param reached_ids] says the tool wrote is left out, as
|
|
351
353
|
## [method reached] answers it.
|
|
352
|
-
static func embedded_changes(
|
|
354
|
+
static func embedded_changes(
|
|
355
|
+
before: String, after: String, reached_ids: Dictionary
|
|
356
|
+
) -> Array[Array]:
|
|
353
357
|
var changed: Array[Array] = []
|
|
354
358
|
if before.is_empty():
|
|
355
359
|
return changed
|
|
@@ -375,34 +379,37 @@ static func embedded_changes(before: String, after: String, reached_ids: Diction
|
|
|
375
379
|
return changed
|
|
376
380
|
|
|
377
381
|
|
|
378
|
-
## Compares the file
|
|
379
|
-
##
|
|
380
|
-
##
|
|
381
|
-
##
|
|
382
|
-
##
|
|
383
|
-
##
|
|
382
|
+
## Compares the file [param saved] names with what it held before, and puts back what a script that
|
|
383
|
+
## is not a tool changed in it: in its embedded resources, which [param values] reach, and in
|
|
384
|
+
## [param main], its main resource, unless that is null. [param asked] and [param reached_ids] are
|
|
385
|
+
## what the call changed, and [param carried] is [method embedded_in] of [param values] taken before
|
|
386
|
+
## the save. Saved again through [param saved], and answers "" or why the file still does not hold
|
|
387
|
+
## what it should.
|
|
384
388
|
##
|
|
385
389
|
## An id is compared only where the resource holding it after the save held it before. Each headless
|
|
386
390
|
## engine hands out the ids of one sequence, so a resource the call added can be saved under the id
|
|
387
391
|
## the file had kept for one it dropped. Read as one resource, the new third line of a dialogue was
|
|
388
392
|
## taken for the old first one changed by its script, and given the old one's text back.
|
|
389
393
|
static func settle_saved(
|
|
390
|
-
|
|
391
|
-
before: String,
|
|
394
|
+
saved: GdhSaved,
|
|
392
395
|
values: Array,
|
|
393
396
|
main: Object,
|
|
394
397
|
asked: Dictionary,
|
|
395
398
|
reached_ids: Dictionary,
|
|
396
|
-
carried: Dictionary
|
|
397
|
-
resave: Callable
|
|
399
|
+
carried: Dictionary
|
|
398
400
|
) -> String:
|
|
401
|
+
var path: String = saved.path
|
|
402
|
+
var before: String = saved.before
|
|
399
403
|
for attempt: int in 2:
|
|
400
404
|
var after: String = FileAccess.get_file_as_string(path)
|
|
401
405
|
var by_id: Dictionary = embedded_in(values, {})
|
|
402
406
|
var embedded: Array[Array] = []
|
|
403
407
|
for found: Array in embedded_changes(before, after, reached_ids):
|
|
404
408
|
var holder: Resource = by_id.get(found[0])
|
|
405
|
-
if
|
|
409
|
+
if (
|
|
410
|
+
not carried.has(found[0])
|
|
411
|
+
or (holder != null and not is_same(holder, carried[found[0]]))
|
|
412
|
+
):
|
|
406
413
|
continue
|
|
407
414
|
if holder != null and _unchanged(holder, found.slice(1)):
|
|
408
415
|
continue
|
|
@@ -439,7 +446,7 @@ static func settle_saved(
|
|
|
439
446
|
var refused: String = put_back_value(main, name, was_set, held)
|
|
440
447
|
if not refused.is_empty():
|
|
441
448
|
return unasked(path, name, refused)
|
|
442
|
-
var saving: Error = resave.call()
|
|
449
|
+
var saving: Error = saved.resave.call()
|
|
443
450
|
if saving != OK:
|
|
444
451
|
return "Failed to save %s again: %s." % [path, error_string(saving)]
|
|
445
452
|
return ""
|
|
@@ -474,19 +481,22 @@ static func put_back_value(object: Object, name: String, was_set: bool, held: St
|
|
|
474
481
|
object.set(name, default_of(object, name))
|
|
475
482
|
return ""
|
|
476
483
|
if "Resource(" in held:
|
|
477
|
-
return
|
|
484
|
+
return (
|
|
485
|
+
"its value there names another resource, which cannot be restored from the text "
|
|
486
|
+
+ "here."
|
|
487
|
+
)
|
|
478
488
|
object.set(name, str_to_var(held))
|
|
479
489
|
return ""
|
|
480
490
|
|
|
481
491
|
|
|
482
|
-
## [param refused], a refusal of [param property] on [param object] for not holding what it was
|
|
483
|
-
## with why when a headless engine set it through a script that is not a tool. That setter
|
|
484
|
-
## and in the game, and an editor runs none and saves the value given, so a setter
|
|
485
|
-
## 0 refused -5 here and the same call through an editor wrote it.
|
|
492
|
+
## [param refused], a refusal of [param property] on [param object] for not holding what it was
|
|
493
|
+
## given, with why when a headless engine set it through a script that is not a tool. That setter
|
|
494
|
+
## runs here and in the game, and an editor runs none and saves the value given, so a setter
|
|
495
|
+
## clamping stock to 0 refused -5 here and the same call through an editor wrote it.
|
|
486
496
|
static func setter_ran(object: Object, property: String, refused: String) -> String:
|
|
487
497
|
if Engine.is_editor_hint() or property.is_empty():
|
|
488
498
|
return refused
|
|
489
|
-
if not through_script(object, {property.get_slice(":", 0): true}):
|
|
499
|
+
if not through_script(object, { property.get_slice(":", 0): true }):
|
|
490
500
|
return refused
|
|
491
501
|
var attached: Variant = object.get_script()
|
|
492
502
|
var named: String = "Its script"
|
|
@@ -496,8 +506,9 @@ static func setter_ran(object: Object, property: String, refused: String) -> Str
|
|
|
496
506
|
return (
|
|
497
507
|
(
|
|
498
508
|
(
|
|
499
|
-
"%s %s is not a tool script, so its setter ran in the headless engine writing this
|
|
500
|
-
+ "in the game; an editor runs none and would have saved the value
|
|
509
|
+
"%s %s is not a tool script, so its setter ran in the headless engine writing this "
|
|
510
|
+
+ "as it runs in the game; an editor runs none and would have saved the value "
|
|
511
|
+
+ "given. "
|
|
501
512
|
)
|
|
502
513
|
% [refused, named]
|
|
503
514
|
)
|
|
@@ -505,16 +516,58 @@ static func setter_ran(object: Object, property: String, refused: String) -> Str
|
|
|
505
516
|
)
|
|
506
517
|
|
|
507
518
|
|
|
519
|
+
## Moves out of alsoChanged in [param answer] each of [param names], what a headless write put back
|
|
520
|
+
## as the doing of the script of [param owner], which is not a tool, to setByScript, with a note
|
|
521
|
+
## saying why the file does not hold it.
|
|
522
|
+
static func move_script_set(answer: Dictionary, names: Array, owner: String) -> void:
|
|
523
|
+
if not answer.has("alsoChanged"):
|
|
524
|
+
return
|
|
525
|
+
var changed: Dictionary = answer["alsoChanged"]
|
|
526
|
+
var by_script: Dictionary = {}
|
|
527
|
+
for key: Variant in names:
|
|
528
|
+
if changed.has(key):
|
|
529
|
+
by_script[key] = changed[key]
|
|
530
|
+
var _erased: bool = changed.erase(key)
|
|
531
|
+
if by_script.is_empty():
|
|
532
|
+
return
|
|
533
|
+
if changed.is_empty():
|
|
534
|
+
var _dropped: bool = answer.erase("alsoChanged")
|
|
535
|
+
answer["setByScript"] = by_script
|
|
536
|
+
var listed: Array = by_script.keys()
|
|
537
|
+
var pronoun: String = "it" if listed.size() == 1 else "them"
|
|
538
|
+
answer["setByScriptNote"] = (
|
|
539
|
+
(
|
|
540
|
+
"%s's script is not a tool, so it ran in the headless engine that wrote the file, and "
|
|
541
|
+
+ "set %s as it did. The file does not hold %s, as a save from the editor, where the "
|
|
542
|
+
+ "script does not run, would not; the script sets %s again when it runs in the game."
|
|
543
|
+
)
|
|
544
|
+
% [owner, ", ".join(listed), pronoun, pronoun]
|
|
545
|
+
)
|
|
546
|
+
|
|
547
|
+
|
|
508
548
|
## Why [param name] on [param what] cannot be saved as the file held it.
|
|
509
549
|
static func unasked(what: String, name: String, why: String = "") -> String:
|
|
510
550
|
return (
|
|
511
551
|
(
|
|
512
552
|
(
|
|
513
|
-
"%s.%s would be saved differently from what the file holds, and the call did not
|
|
514
|
-
+ "it: its script ran when a headless engine loaded or set it, as it does
|
|
515
|
-
+ "in an editor%s. "
|
|
553
|
+
"%s.%s would be saved differently from what the file holds, and the call did not "
|
|
554
|
+
+ "ask for it: its script ran when a headless engine loaded or set it, as it does "
|
|
555
|
+
+ "in the game and not in an editor%s. "
|
|
516
556
|
)
|
|
517
557
|
% [what, name, "" if why.is_empty() else "; " + why.trim_suffix(".")]
|
|
518
558
|
)
|
|
519
559
|
+ REMEDY
|
|
520
560
|
)
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
## A file just saved: where it is, the text it held before, and [member resave], a Callable that
|
|
564
|
+
## saves it again and answers an Error.
|
|
565
|
+
class GdhSaved:
|
|
566
|
+
var path: String
|
|
567
|
+
var before: String
|
|
568
|
+
var resave: Callable
|
|
569
|
+
|
|
570
|
+
func _init(at: String, held: String, again: Callable) -> void:
|
|
571
|
+
path = at
|
|
572
|
+
before = held
|
|
573
|
+
resave = again
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
@tool
|
|
2
2
|
extends EditorPlugin
|
|
3
|
-
|
|
4
3
|
## The editor half of gdharness: a client that holds a socket to the server and an executor
|
|
5
4
|
## that does what the server asks, with a label in the toolbar saying whether the two are
|
|
6
5
|
## connected.
|
|
7
6
|
|
|
8
7
|
const GdhBridgeClient = preload("bridge_client.gd")
|
|
9
8
|
const GdhToolExecutor = preload("tool_executor.gd")
|
|
10
|
-
|
|
11
9
|
## The tools answered while the editor scans or imports, because none of them saves a file: the
|
|
12
10
|
## ones a caller waits on a scan with, and the ones that only read or stop a played game.
|
|
13
11
|
const ANSWERED_WHILE_SCANNING: Array[String] = [
|
|
@@ -102,7 +100,8 @@ func _on_disconnected() -> void:
|
|
|
102
100
|
func turned_away(tool_name: String) -> bool:
|
|
103
101
|
var filesystem: EditorFileSystem = EditorInterface.get_resource_filesystem()
|
|
104
102
|
return (
|
|
105
|
-
not ANSWERED_WHILE_SCANNING.has(tool_name)
|
|
103
|
+
not ANSWERED_WHILE_SCANNING.has(tool_name)
|
|
104
|
+
and (filesystem.is_scanning() or filesystem.is_importing())
|
|
106
105
|
)
|
|
107
106
|
|
|
108
107
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
@tool
|
|
2
2
|
extends RefCounted
|
|
3
|
-
|
|
4
3
|
## Where a property a tool writes lives: on the object given, on a resource built into it, or on an
|
|
5
4
|
## element of one of its lists that the write has to make first.
|
|
6
5
|
|
|
7
6
|
const GdhRead = preload("reading.gd")
|
|
8
|
-
|
|
9
7
|
const HEADINGS: int = PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP
|
|
10
8
|
|
|
11
9
|
|
|
@@ -95,11 +93,17 @@ static func _unlisted_in(items: Array, called: String, name: String, at: int) ->
|
|
|
95
93
|
var end: int = name.find("/", at + 1)
|
|
96
94
|
var index: String = name.substr(at + 1) if end < 0 else name.substr(at + 1, end - at - 1)
|
|
97
95
|
if items.is_empty():
|
|
98
|
-
return
|
|
96
|
+
return (
|
|
97
|
+
"%s holds no elements, so %s names none: give %s a whole list first."
|
|
98
|
+
% [called, name, head]
|
|
99
|
+
)
|
|
99
100
|
var last: int = items.size() - 1
|
|
100
101
|
if not index.is_valid_int():
|
|
101
102
|
return (
|
|
102
|
-
|
|
103
|
+
(
|
|
104
|
+
"%s is a list, so the step after it is the index of one of its elements, from 0 to "
|
|
105
|
+
+ "%d, not %s."
|
|
106
|
+
)
|
|
103
107
|
% [called, last, index]
|
|
104
108
|
)
|
|
105
109
|
var place: int = index.to_int()
|
|
@@ -116,8 +120,8 @@ static func _unlisted_in(items: Array, called: String, name: String, at: int) ->
|
|
|
116
120
|
if end < 0:
|
|
117
121
|
return (
|
|
118
122
|
(
|
|
119
|
-
"%s/%d is an element of %s, which a path does not replace alone: give %s a whole
|
|
120
|
-
+ "write a property of the element, as %s/%d/<property>."
|
|
123
|
+
"%s/%d is an element of %s, which a path does not replace alone: give %s a whole "
|
|
124
|
+
+ "list, or write a property of the element, as %s/%d/<property>."
|
|
121
125
|
)
|
|
122
126
|
% [head, place, called, head, head, place]
|
|
123
127
|
)
|
|
@@ -197,12 +201,15 @@ static func grow(target: Object, name: String, called: String) -> String:
|
|
|
197
201
|
above if not above.is_empty() else called,
|
|
198
202
|
count,
|
|
199
203
|
element.replace("_", " "),
|
|
200
|
-
"" if count == 1 else "s"
|
|
204
|
+
"" if count == 1 else "s",
|
|
201
205
|
]
|
|
202
206
|
)
|
|
203
207
|
if index > count:
|
|
204
208
|
return (
|
|
205
|
-
|
|
209
|
+
(
|
|
210
|
+
"%s, and a new one goes after the last, so %s%d cannot be written yet: write "
|
|
211
|
+
+ "%s%d first."
|
|
212
|
+
)
|
|
206
213
|
% [held, prefix, index, prefix, count]
|
|
207
214
|
)
|
|
208
215
|
if not adding.is_valid():
|
|
@@ -263,7 +270,10 @@ static func held_elsewhere(target: Object, name: String, home: String) -> String
|
|
|
263
270
|
var file: String = "" if held == null else held.resource_path.get_slice("::", 0)
|
|
264
271
|
if held != null and not held.is_built_in():
|
|
265
272
|
return (
|
|
266
|
-
|
|
273
|
+
(
|
|
274
|
+
"%s.%s is %s, a file of its own, so %s is written there, with resource_edit "
|
|
275
|
+
+ "modify on %s."
|
|
276
|
+
)
|
|
267
277
|
% [class_called(target), head, file, rest, file]
|
|
268
278
|
)
|
|
269
279
|
if held != null and not file.is_empty() and not home.is_empty() and file != home:
|
|
@@ -287,9 +297,9 @@ static func _built_in_elsewhere(
|
|
|
287
297
|
node = " on %s" % from.get_path_to(placed)
|
|
288
298
|
var text: String = (
|
|
289
299
|
(
|
|
290
|
-
"%s.%s is built into %s, so %s is written there, with scene_node set%s in %s, which
|
|
291
|
-
+ "it wherever that scene is used. To change it here alone, give %s a %s of
|
|
292
|
-
+ 'value with "_type" set to its class and its properties beside it.'
|
|
300
|
+
"%s.%s is built into %s, so %s is written there, with scene_node set%s in %s, which "
|
|
301
|
+
+ "changes it wherever that scene is used. To change it here alone, give %s a %s of "
|
|
302
|
+
+ 'its own: a value with "_type" set to its class and its properties beside it.'
|
|
293
303
|
)
|
|
294
304
|
% [class_called(target), head, file, rest, node, file, head, held.get_class()]
|
|
295
305
|
)
|