gdharness 1.3.0 → 1.3.1

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 (68) hide show
  1. package/build/cli.js +14 -13
  2. package/build/godot/addons/gdharness_editor/animation_reads.gd +7 -19
  3. package/build/godot/addons/gdharness_editor/bridge_client.gd +8 -8
  4. package/build/godot/addons/gdharness_editor/file_reads.gd +60 -25
  5. package/build/godot/addons/gdharness_editor/headless_check.gd +7 -7
  6. package/build/godot/addons/gdharness_editor/plugin.gd +6 -6
  7. package/build/godot/addons/gdharness_editor/property_values.gd +120 -53
  8. package/build/godot/addons/gdharness_editor/reading.gd +28 -0
  9. package/build/godot/addons/gdharness_editor/scene_file.gd +28 -23
  10. package/build/godot/addons/gdharness_editor/serialisation.gd +45 -94
  11. package/build/godot/addons/gdharness_editor/tool_executor.gd +24 -24
  12. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +52 -41
  13. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +4 -4
  14. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +2 -2
  15. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +14 -14
  16. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +48 -41
  17. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +17 -17
  18. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +14 -12
  19. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +7 -7
  20. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +81 -77
  21. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +4 -4
  22. package/build/godot/addons/gdharness_editor/value_shapes.gd +111 -0
  23. package/build/godot/addons/gdharness_editor/value_shapes.gd.uid +1 -0
  24. package/build/godot/addons/gdharness_runtime/reading.gd +28 -0
  25. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +18 -18
  26. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +29 -29
  27. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +21 -18
  28. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +86 -80
  29. package/build/godot/addons/gdharness_runtime/runtime_input.gd +65 -64
  30. package/build/godot/addons/gdharness_runtime/runtime_items.gd +6 -6
  31. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +8 -8
  32. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +6 -6
  33. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +10 -10
  34. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +7 -7
  35. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +41 -41
  36. package/build/godot/addons/gdharness_runtime/runtime_says.gd +3 -3
  37. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +33 -33
  38. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +20 -20
  39. package/build/godot/addons/gdharness_runtime/runtime_values.gd +25 -24
  40. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +56 -50
  41. package/build/godot/addons/gdharness_runtime/serialisation.gd +45 -94
  42. package/build/godot/addons/gdharness_runtime/value_shapes.gd +111 -0
  43. package/build/godot/addons/gdharness_runtime/value_shapes.gd.uid +1 -0
  44. package/build/godot/operations/animation_reads.gd +7 -19
  45. package/build/godot/operations/audio_buses.gd +10 -10
  46. package/build/godot/operations/class_cache.gd +16 -16
  47. package/build/godot/operations/classdb_queries.gd +12 -12
  48. package/build/godot/operations/dependencies.gd +33 -29
  49. package/build/godot/operations/editor_tools.gd +12 -12
  50. package/build/godot/operations/export_presets.gd +10 -8
  51. package/build/godot/operations/file_reads.gd +60 -25
  52. package/build/godot/operations/gdscript_analysis.gd +20 -20
  53. package/build/godot/operations/gdscript_authoring.gd +17 -15
  54. package/build/godot/operations/godot_operations.gd +64 -63
  55. package/build/godot/operations/import_pipeline.gd +20 -20
  56. package/build/godot/operations/input_actions.gd +17 -17
  57. package/build/godot/operations/logger.gd +1 -1
  58. package/build/godot/operations/plugins.gd +8 -8
  59. package/build/godot/operations/project_config.gd +24 -17
  60. package/build/godot/operations/project_diagnostics.gd +9 -9
  61. package/build/godot/operations/property_values.gd +120 -53
  62. package/build/godot/operations/reading.gd +28 -0
  63. package/build/godot/operations/rename_checks.gd +3 -3
  64. package/build/godot/operations/resource_files.gd +5 -5
  65. package/build/godot/operations/script_check.gd +7 -7
  66. package/build/godot/operations/serialisation.gd +45 -94
  67. package/build/godot/operations/value_shapes.gd +111 -0
  68. package/package.json +1 -1
@@ -10,7 +10,7 @@ extends Node
10
10
  ## `debug_data` signal every ScriptEditorDebugger emits for every message, on a node Godot does not
11
11
  ## expose to scripts: found by its class in the editor's tree and connected to by name.
12
12
 
13
- const Read = preload("../reading.gd")
13
+ const GdhRead = preload("../reading.gd")
14
14
 
15
15
  ## The most functions a frame may carry when the server does not say. The engine names a function
16
16
  ## once, as it first appears, and the game's debugger queue drops those messages past its size, so
@@ -28,7 +28,7 @@ const PROFILE_FROM_START: String = "GDHARNESS_PROFILE_FROM_START"
28
28
 
29
29
 
30
30
  ## The editor's debugger sessions, numbered as the editor numbers its debugger tabs.
31
- class Sessions:
31
+ class GdhSessions:
32
32
  extends EditorDebuggerPlugin
33
33
 
34
34
  signal session_started(session_id: int)
@@ -53,7 +53,7 @@ class Sessions:
53
53
 
54
54
 
55
55
  var _editor_plugin: EditorPlugin = null
56
- var _sessions: Sessions = null
56
+ var _sessions: GdhSessions = null
57
57
  ## The debugger tabs connected to, by instance id, so none is connected twice.
58
58
  var _hooked: Dictionary[int, bool] = {}
59
59
 
@@ -75,7 +75,7 @@ var _totals: Dictionary[String, PackedFloat64Array] = {}
75
75
 
76
76
  func set_editor_plugin(plugin: EditorPlugin) -> void:
77
77
  _editor_plugin = plugin
78
- _sessions = Sessions.new()
78
+ _sessions = GdhSessions.new()
79
79
  var joined: int = _sessions.session_started.connect(_on_session_started)
80
80
  if joined != OK:
81
81
  push_error("gdharness could not watch debugger sessions start: %d" % joined)
@@ -105,9 +105,9 @@ func profile_start(args: Dictionary) -> Dictionary:
105
105
  ),
106
106
  }
107
107
  _reset()
108
- var asked: int = Read.as_int(args.get("frameFunctions", FRAME_FUNCTIONS))
108
+ var asked: int = GdhRead.as_int(args.get("frameFunctions", FRAME_FUNCTIONS))
109
109
  _frame_functions = asked if asked > 0 else FRAME_FUNCTIONS
110
- if Read.as_bool(args.get("arm", false)):
110
+ if GdhRead.as_bool(args.get("arm", false)):
111
111
  _armed = true
112
112
  # The game the editor starts next inherits the editor's environment, and this tells its
113
113
  # runtime addon to hold its start until the profiler is on, which the session's start
@@ -206,7 +206,7 @@ func _on_debug_data(message: String, data: Array, session_id: int) -> void:
206
206
  if session_id != _session:
207
207
  return
208
208
  if message == "servers:function_signature" and data.size() >= 2:
209
- _names[Read.as_int(data[1])] = str(data[0])
209
+ _names[GdhRead.as_int(data[1])] = str(data[0])
210
210
  elif message == "servers:profile_frame":
211
211
  var carried: int = _add(data, _totals)
212
212
  if carried >= 0:
@@ -231,28 +231,28 @@ func _add(data: Array, into: Dictionary[String, PackedFloat64Array]) -> int:
231
231
  var at: int = 6
232
232
  if data.size() <= at:
233
233
  return -1
234
- var servers: int = Read.as_int(data[at])
234
+ var servers: int = GdhRead.as_int(data[at])
235
235
  at += 1
236
236
  for _server: int in servers:
237
237
  if data.size() <= at + 1:
238
238
  return -1
239
- at += 2 + Read.as_int(data[at + 1])
239
+ at += 2 + GdhRead.as_int(data[at + 1])
240
240
  if data.size() <= at:
241
241
  return -1
242
- var values: int = Read.as_int(data[at])
242
+ var values: int = GdhRead.as_int(data[at])
243
243
  at += 1
244
244
  if values % 5 != 0 or data.size() < at + values:
245
245
  return -1
246
246
  var carried: int = 0
247
247
  for index: int in range(at, at + values, 5):
248
- var id: int = Read.as_int(data[index])
248
+ var id: int = GdhRead.as_int(data[index])
249
249
  var signature: String = _names[id] if _names.has(id) else "#%d" % id
250
250
  var sum: PackedFloat64Array = (
251
251
  into[signature] if into.has(signature) else PackedFloat64Array([0, 0, 0])
252
252
  )
253
- sum[0] += Read.as_float(data[index + 1])
254
- sum[1] += Read.as_float(data[index + 2])
255
- sum[2] += Read.as_float(data[index + 3])
253
+ sum[0] += GdhRead.as_float(data[index + 1])
254
+ sum[1] += GdhRead.as_float(data[index + 2])
255
+ sum[2] += GdhRead.as_float(data[index + 3])
256
256
  into[signature] = sum
257
257
  carried += 1
258
258
  return carried
@@ -3,11 +3,11 @@ extends Node
3
3
 
4
4
  ## Resource files, shaders, tilesets and themes, written through the open editor.
5
5
 
6
- const FileReads = preload("../file_reads.gd")
7
- const HeadlessCheck = preload("../headless_check.gd")
8
- const PropertyValues = preload("../property_values.gd")
9
- const Read = preload("../reading.gd")
10
- const SceneFile = preload("../scene_file.gd")
6
+ const GdhFileReads = preload("../file_reads.gd")
7
+ const GdhHeadlessCheck = preload("../headless_check.gd")
8
+ const GdhPropertyValues = preload("../property_values.gd")
9
+ const GdhRead = preload("../reading.gd")
10
+ const GdhSceneFile = preload("../scene_file.gd")
11
11
 
12
12
  # The minimal shader of a type: its declaration and the one function the engine calls for it.
13
13
  const SHADER_EMPTY: String = """shader_type %s;
@@ -23,7 +23,7 @@ const SHADER_ENTRY: Dictionary[String, String] = {
23
23
  const CELLS_SHOWN: int = 1000
24
24
 
25
25
  var _editor_plugin: EditorPlugin = null
26
- var _properties: PropertyValues = PropertyValues.new()
26
+ var _properties: GdhPropertyValues = GdhPropertyValues.new()
27
27
 
28
28
 
29
29
  func set_editor_plugin(plugin: EditorPlugin) -> void:
@@ -48,7 +48,7 @@ func _written(path: String) -> void:
48
48
  if ResourceLoader.has_cached(path):
49
49
  var _replaced: Resource = ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_REPLACE)
50
50
  if _editor_plugin:
51
- SceneFile.scan_later()
51
+ GdhSceneFile.scan_later()
52
52
 
53
53
 
54
54
  ## Why a tool that creates [param path] must not write there, or "". Saving over a file that was
@@ -89,12 +89,15 @@ func _xy(value: Variant, label: String) -> Array:
89
89
  x = pair[0]
90
90
  y = pair[1]
91
91
  for number: Variant in [x, y]:
92
- if not (number is float or number is int) or Read.as_float(number) != floorf(Read.as_float(number)):
92
+ if (
93
+ not (number is float or number is int)
94
+ or GdhRead.as_float(number) != floorf(GdhRead.as_float(number))
95
+ ):
93
96
  return [
94
97
  false,
95
98
  '%s must be two whole numbers, {"x": .., "y": ..}, not %s.' % [label, JSON.stringify(value)]
96
99
  ]
97
- return [true, Vector2i(Read.as_int(x), Read.as_int(y))]
100
+ return [true, Vector2i(GdhRead.as_int(x), GdhRead.as_int(y))]
98
101
 
99
102
 
100
103
  ## The theme on disk at this path, or null when there is not one.
@@ -119,12 +122,12 @@ func _load_theme(theme_path: String) -> Theme:
119
122
  ## Read back because a property can be set and still not be saved: one without storage, a
120
123
  ## script variable that is not exported. Both were answered as changed.
121
124
  func _save_checked(resource: Resource, path: String, names: Array, previous: Variant) -> String:
122
- var saving: Error = SceneFile.save_keeping_uid(resource, path)
125
+ var saving: Error = GdhSceneFile.save_keeping_uid(resource, path)
123
126
  if saving != OK:
124
127
  return "Failed to save %s: %s" % [path, error_string(saving)]
125
128
  var unkept: String = _unkept_headless(resource, path, names, previous)
126
129
  if not unkept.is_empty():
127
- return "Nothing was written: " + unkept + HeadlessCheck.put_back(path, previous)
130
+ return "Nothing was written: " + unkept + GdhHeadlessCheck.put_back(path, previous)
128
131
  var loaded: Resource = ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_IGNORE)
129
132
  var lost: String = ""
130
133
  if loaded == null:
@@ -133,7 +136,7 @@ func _save_checked(resource: Resource, path: String, names: Array, previous: Var
133
136
  for key: Variant in names:
134
137
  var property: String = str(key)
135
138
  var read: Variant = _properties.read_at(loaded, property)
136
- if not PropertyValues.same(read, _properties.read_at(resource, property)):
139
+ if not GdhPropertyValues.same(read, _properties.read_at(resource, property)):
137
140
  lost = (
138
141
  (
139
142
  "%s.%s would load from the file as %s: it is not a property the file keeps, so "
@@ -145,19 +148,19 @@ func _save_checked(resource: Resource, path: String, names: Array, previous: Var
145
148
  if lost.is_empty():
146
149
  _written(path)
147
150
  return ""
148
- return lost + HeadlessCheck.put_back(path, previous)
151
+ return lost + GdhHeadlessCheck.put_back(path, previous)
149
152
 
150
153
 
151
154
  ## Outside the editor, puts back in the file just saved at [param path] what a script that is not a
152
155
  ## tool changed and the call did not ask for, [param names] being what it asked for, and answers ""
153
- ## or why that did not hold. See [HeadlessCheck].
156
+ ## or why that did not hold. See [GdhHeadlessCheck].
154
157
  func _unkept_headless(resource: Resource, path: String, names: Array, previous: Variant) -> String:
155
158
  if Engine.is_editor_hint():
156
159
  return ""
157
160
  var script: Script = resource.get_script()
158
161
  var scripted: bool = script != null and not script.is_tool()
159
162
  if not path.ends_with(".tres"):
160
- if scripted or HeadlessCheck.holds_scripted_embedded(resource, {}):
163
+ if scripted or GdhHeadlessCheck.holds_scripted_embedded(resource, {}):
161
164
  return (
162
165
  (
163
166
  (
@@ -166,7 +169,7 @@ func _unkept_headless(resource: Resource, path: String, names: Array, previous:
166
169
  )
167
170
  % path
168
171
  )
169
- + HeadlessCheck.REMEDY
172
+ + GdhHeadlessCheck.REMEDY
170
173
  )
171
174
  return ""
172
175
  var before: String = ""
@@ -179,15 +182,15 @@ func _unkept_headless(resource: Resource, path: String, names: Array, previous:
179
182
  var property: String = str(key)
180
183
  asked[property] = true
181
184
  asked[property.get_slice(":", 0)] = true
182
- reached.merge(HeadlessCheck.reached(resource, property))
183
- return HeadlessCheck.settle_saved(
185
+ reached.merge(GdhHeadlessCheck.reached(resource, property))
186
+ return GdhHeadlessCheck.settle_saved(
184
187
  path,
185
188
  before,
186
- HeadlessCheck.stored(resource).values(),
189
+ GdhHeadlessCheck.stored(resource).values(),
187
190
  resource if scripted else null,
188
191
  asked,
189
192
  reached,
190
- func() -> Error: return SceneFile.save_keeping_uid(resource, path)
193
+ func() -> Error: return GdhSceneFile.save_keeping_uid(resource, path)
191
194
  )
192
195
 
193
196
 
@@ -202,7 +205,7 @@ func create_resource(args: Dictionary) -> Dictionary:
202
205
  return {"ok": false, "error": taken}
203
206
 
204
207
  var script_path: String = str(args.get("script", ""))
205
- var made: Dictionary = SceneFile.made_as(
208
+ var made: Dictionary = GdhSceneFile.made_as(
206
209
  resource_type, "" if script_path == "" else _ensure_res_path(script_path), "Resource", "resourceType"
207
210
  )
208
211
  if made.has("error"):
@@ -229,7 +232,7 @@ func create_resource(args: Dictionary) -> Dictionary:
229
232
  var script: Script = load(script_file) as Script
230
233
  if script == null:
231
234
  return {"ok": false, "error": "No script loads from " + script_file}
232
- var uncompiled: String = SceneFile.uncompiled(script, script_file)
235
+ var uncompiled: String = GdhSceneFile.uncompiled(script, script_file)
233
236
  if not uncompiled.is_empty():
234
237
  return {"ok": false, "error": uncompiled}
235
238
  var base: String = str(script.get_instance_base_type())
@@ -245,13 +248,15 @@ func create_resource(args: Dictionary) -> Dictionary:
245
248
  if not refused.is_empty():
246
249
  return {"ok": false, "error": refused}
247
250
 
248
- var folder: String = SceneFile.make_folder_for(res_path)
251
+ var folder: String = GdhSceneFile.make_folder_for(res_path)
249
252
  if not folder.is_empty():
250
253
  return {"ok": false, "error": folder}
254
+ var answer: Dictionary = {"ok": true, "resourcePath": res_path, "resourceType": asked_type}
255
+ _properties.note_also_changed(answer)
251
256
  var failed: String = _save_checked(resource, res_path, properties.keys(), null)
252
257
  if not failed.is_empty():
253
258
  return {"ok": false, "error": failed}
254
- return {"ok": true, "resourcePath": res_path, "resourceType": asked_type}
259
+ return answer
255
260
 
256
261
 
257
262
  func modify_resource(args: Dictionary) -> Dictionary:
@@ -284,11 +289,13 @@ func modify_resource(args: Dictionary) -> Dictionary:
284
289
  var refused: String = _properties.write_all(resource, properties)
285
290
  if not refused.is_empty():
286
291
  return {"ok": false, "error": refused}
292
+ var answer: Dictionary = {"ok": true, "resourcePath": res_path}
293
+ _properties.note_also_changed(answer)
287
294
  var previous: PackedByteArray = FileAccess.get_file_as_bytes(res_path)
288
295
  var failed: String = _save_checked(resource, res_path, properties.keys(), previous)
289
296
  if not failed.is_empty():
290
297
  return {"ok": false, "error": failed}
291
- return {"ok": true, "resourcePath": res_path}
298
+ return answer
292
299
 
293
300
 
294
301
  ## What a resource file holds, read as a headless engine reads it with no editor connected.
@@ -300,7 +307,7 @@ func read_resource(args: Dictionary) -> Dictionary:
300
307
  var inner: String = str(args.get("subResource", ""))
301
308
  if not inner.is_empty():
302
309
  res_path += "::" + inner
303
- return FileReads.resource(res_path, Read.as_bool(args.get("includeDefaults", false)))
310
+ return GdhFileReads.resource(res_path, GdhRead.as_bool(args.get("includeDefaults", false)))
304
311
 
305
312
 
306
313
  func create_shader(args: Dictionary) -> Dictionary:
@@ -316,7 +323,7 @@ func create_shader(args: Dictionary) -> Dictionary:
316
323
  if code == "":
317
324
  code = SHADER_EMPTY % [shader_type, SHADER_ENTRY.get(shader_type, "fragment")]
318
325
 
319
- var folder: String = SceneFile.make_folder_for(shader_path)
326
+ var folder: String = GdhSceneFile.make_folder_for(shader_path)
320
327
  if not folder.is_empty():
321
328
  return {"ok": false, "error": folder}
322
329
  var file: FileAccess = FileAccess.open(shader_path, FileAccess.WRITE)
@@ -371,10 +378,10 @@ func create_tileset(args: Dictionary) -> Dictionary:
371
378
  {"sourceId": added, "texture": atlas.texture.resource_path, "tiles": atlas.get_tiles_count()}
372
379
  )
373
380
 
374
- var folder: String = SceneFile.make_folder_for(tileset_path)
381
+ var folder: String = GdhSceneFile.make_folder_for(tileset_path)
375
382
  if not folder.is_empty():
376
383
  return {"ok": false, "error": folder}
377
- var saving: Error = SceneFile.save_keeping_uid(tileset, tileset_path)
384
+ var saving: Error = GdhSceneFile.save_keeping_uid(tileset, tileset_path)
378
385
  if saving != OK:
379
386
  return {"ok": false, "error": "Failed to save %s: %s" % [tileset_path, error_string(saving)]}
380
387
 
@@ -491,12 +498,12 @@ func set_tilemap_cells(args: Dictionary) -> Dictionary:
491
498
  if placed.is_empty():
492
499
  return {"ok": false, "error": "cells is empty, so there is nothing to place"}
493
500
 
494
- var scene: SceneFile = SceneFile.new()
501
+ var scene: GdhSceneFile = GdhSceneFile.new()
495
502
  var refused: Dictionary = scene.open(scene_path, true)
496
503
  if not refused.is_empty():
497
504
  return refused
498
505
 
499
- var layer: int = Read.as_int(args.get("layer", 0))
506
+ var layer: int = GdhRead.as_int(args.get("layer", 0))
500
507
  var found: Array = _tile_node(scene, node_path, layer)
501
508
  if found[0] == null:
502
509
  return scene.refuse(str(found[1]))
@@ -544,7 +551,7 @@ func set_tilemap_cells(args: Dictionary) -> Dictionary:
544
551
 
545
552
  ## The node at [param node_path] cells are painted on, with a TileSet, as [node, why not].
546
553
  ## TileMapLayer is the node since 4.3, and TileMap the one it replaced, which keeps its layers.
547
- func _tile_node(scene: SceneFile, node_path: String, layer: int) -> Array:
554
+ func _tile_node(scene: GdhSceneFile, node_path: String, layer: int) -> Array:
548
555
  var node: Node = (
549
556
  scene.root if node_path == "." or node_path == "" else scene.root.get_node_or_null(node_path)
550
557
  )
@@ -582,12 +589,12 @@ func _cell(entry: Variant, index: int, tile_set: TileSet) -> Array:
582
589
  var atlas_at: Array = _xy(cell["atlasCoords"], "cells[%d].atlasCoords" % index)
583
590
  if not atlas_at[0]:
584
591
  return atlas_at
585
- var source_id: int = Read.as_int(cell["sourceId"], -1)
592
+ var source_id: int = GdhRead.as_int(cell["sourceId"], -1)
586
593
  if not tile_set.has_source(source_id):
587
594
  return [false, "The TileSet has no source %d; it has %s" % [source_id, _source_ids(tile_set)]]
588
595
  var source: TileSetSource = tile_set.get_source(source_id)
589
596
  var atlas_coords: Vector2i = atlas_at[1]
590
- var alternative: int = Read.as_int(cell.get("alternativeTile", 0))
597
+ var alternative: int = GdhRead.as_int(cell.get("alternativeTile", 0))
591
598
  if not source.has_tile(atlas_coords):
592
599
  return [
593
600
  false,
@@ -691,12 +698,12 @@ func _cell_at(node: Node, layer: int, at: Vector2i) -> Array:
691
698
  ## Saves [param theme] over [param theme_path] with [param item] changed, answering "" or why not.
692
699
  func _save_theme(theme: Theme, theme_path: String, item: String) -> String:
693
700
  var previous: PackedByteArray = FileAccess.get_file_as_bytes(theme_path)
694
- var saving: Error = SceneFile.save_keeping_uid(theme, theme_path)
701
+ var saving: Error = GdhSceneFile.save_keeping_uid(theme, theme_path)
695
702
  if saving != OK:
696
703
  return "Failed to save %s: %s" % [theme_path, error_string(saving)]
697
704
  var unkept: String = _unkept_headless(theme, theme_path, [item], previous)
698
705
  if not unkept.is_empty():
699
- return "Nothing was written: " + unkept + HeadlessCheck.put_back(theme_path, previous)
706
+ return "Nothing was written: " + unkept + GdhHeadlessCheck.put_back(theme_path, previous)
700
707
  _written(theme_path)
701
708
  return ""
702
709
 
@@ -717,10 +724,10 @@ func set_theme_color(args: Dictionary) -> Dictionary:
717
724
 
718
725
  var c: Dictionary = args.get("color", {})
719
726
  var color: Color = Color(
720
- Read.as_float(c.get("r", 1.0), 1.0),
721
- Read.as_float(c.get("g", 1.0), 1.0),
722
- Read.as_float(c.get("b", 1.0), 1.0),
723
- Read.as_float(c.get("a", 1.0), 1.0)
727
+ GdhRead.as_float(c.get("r", 1.0), 1.0),
728
+ GdhRead.as_float(c.get("g", 1.0), 1.0),
729
+ GdhRead.as_float(c.get("b", 1.0), 1.0),
730
+ GdhRead.as_float(c.get("a", 1.0), 1.0)
724
731
  )
725
732
  theme.set_color(color_name, control_type, color)
726
733
 
@@ -760,7 +767,7 @@ func set_theme_font_size(args: Dictionary) -> Dictionary:
760
767
 
761
768
  # Godot reads a size of 0 or less as unset and answers the theme's default, so -3 would be read
762
769
  # back as 16.
763
- var pixels: float = Read.as_float(args.get("size"), 0.0)
770
+ var pixels: float = GdhRead.as_float(args.get("size"), 0.0)
764
771
  if not is_finite(pixels) or pixels < 1 or pixels != floorf(pixels):
765
772
  var shown: String = str(int(pixels)) if pixels == floorf(pixels) else str(pixels)
766
773
  return {
@@ -4,9 +4,9 @@ extends RefCounted
4
4
  ## The two ways a scene keeps its own values for nodes another scene makes: by inheriting that scene,
5
5
  ## or by instancing it with its children editable.
6
6
 
7
- const FileReads = preload("../file_reads.gd")
8
- const Paths = preload("scene_paths.gd")
9
- const SceneFile = preload("../scene_file.gd")
7
+ const GdhFileReads = preload("../file_reads.gd")
8
+ const GdhPaths = preload("scene_paths.gd")
9
+ const GdhSceneFile = preload("../scene_file.gd")
10
10
 
11
11
 
12
12
  ## Why a create at [param scene_path] is refused when a file is there already, which saving over
@@ -45,7 +45,7 @@ static func inherited(
45
45
  script = load(script_path) as Script
46
46
  if script == null:
47
47
  return {"ok": false, "error": "No script loads from " + script_path}
48
- var uncompiled: String = SceneFile.uncompiled(script, script_path)
48
+ var uncompiled: String = GdhSceneFile.uncompiled(script, script_path)
49
49
  if not uncompiled.is_empty():
50
50
  return {"ok": false, "error": uncompiled}
51
51
  return inherit(scene_path, base_path, str(args.get("rootNodeName", "")), script)
@@ -59,12 +59,12 @@ static func inherited(
59
59
  ## the base: a headless engine making that instance runs every script in the base, and the pack would
60
60
  ## keep what they set as this scene's own values.
61
61
  static func inherit(scene_path: String, base_path: String, root_name: String, script: Script) -> Dictionary:
62
- var base: Dictionary = FileReads.scene_node(base_path, ".")
62
+ var base: Dictionary = GdhFileReads.scene_node(base_path, ".")
63
63
  if not base.get("ok", false):
64
64
  return {"ok": false, "error": "inherits: " + str(base.get("error", "%s holds no nodes" % base_path))}
65
65
  var root_type: String = str(base["type"])
66
66
  var name: String = str(base["name"]) if root_name.is_empty() else root_name
67
- var unfit: String = SceneFile.unfit_name(name)
67
+ var unfit: String = GdhSceneFile.unfit_name(name)
68
68
  if not unfit.is_empty():
69
69
  return {"ok": false, "error": unfit}
70
70
  if script != null:
@@ -78,7 +78,7 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
78
78
  % [script.resource_path, extended, root_type, base_path]
79
79
  )
80
80
  }
81
- var folder: String = SceneFile.make_folder_for(scene_path)
81
+ var folder: String = GdhSceneFile.make_folder_for(scene_path)
82
82
  if not folder.is_empty():
83
83
  return {"ok": false, "error": folder}
84
84
 
@@ -87,14 +87,14 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
87
87
  "",
88
88
  (
89
89
  '[ext_resource type="PackedScene"%s path="%s" id="1_base"]'
90
- % [SceneFile.reference_uid(base_path), base_path]
90
+ % [GdhSceneFile.reference_uid(base_path), base_path]
91
91
  ),
92
92
  ]
93
93
  if script != null:
94
94
  var _resourced: bool = lines.append(
95
95
  (
96
96
  '[ext_resource type="Script"%s path="%s" id="2_script"]'
97
- % [SceneFile.reference_uid(script.resource_path), script.resource_path]
97
+ % [GdhSceneFile.reference_uid(script.resource_path), script.resource_path]
98
98
  )
99
99
  )
100
100
  lines.append_array(["", '[node name="%s" instance=ExtResource("1_base")]' % name])
@@ -117,7 +117,7 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
117
117
  "error":
118
118
  "%s did not load back as a scene inheriting %s, so it was removed." % [scene_path, base_path]
119
119
  }
120
- SceneFile.refresh(scene_path)
120
+ GdhSceneFile.refresh(scene_path)
121
121
  return {
122
122
  "ok": true,
123
123
  "scenePath": scene_path,
@@ -130,8 +130,8 @@ static func inherit(scene_path: String, base_path: String, root_name: String, sc
130
130
  ## Makes the children of [param node], an instance in [param scene], editable or not, answering why
131
131
  ## it cannot or "". With them editable the scene keeps its own values for them, as the editor's
132
132
  ## Editable Children does; made not editable again, the values it kept for them are dropped. The
133
- ## caller has had [method SceneFile.foreign] refuse a node inside an instance that is not editable.
134
- static func set_editable(scene: SceneFile, node: Node, editable: bool) -> String:
133
+ ## caller has had [method GdhSceneFile.foreign] refuse a node inside an instance that is not editable.
134
+ static func set_editable(scene: GdhSceneFile, node: Node, editable: bool) -> String:
135
135
  if node.owner == null or node.scene_file_path.is_empty():
136
136
  return (
137
137
  "editableChildren is a setting of an instance in this scene, and %s is not one."
@@ -152,7 +152,7 @@ static func set_editable(scene: SceneFile, node: Node, editable: bool) -> String
152
152
  ## for a node deleted, they are only named. Answers followed, the scenes rewritten, and
153
153
  ## notFollowed, each one left as it was with why, each only when it names any, with what
154
154
  ## [param carried] gives.
155
- static func follow(changed: String, old_path: String, new_path: String, carried: Paths) -> Dictionary:
155
+ static func follow(changed: String, old_path: String, new_path: String, carried: GdhPaths) -> Dictionary:
156
156
  var texts: Dictionary = {}
157
157
  _read_scenes("res://", texts)
158
158
  var kin: Array[String] = [changed]
@@ -176,14 +176,14 @@ static func follow(changed: String, old_path: String, new_path: String, carried:
176
176
  var moves: Dictionary = {}
177
177
  if _inherits(scene_path, changed, texts):
178
178
  moves[old_path] = new_path
179
- var read: Dictionary = FileReads.scene_tree(scene_path, -1, false)
179
+ var read: Dictionary = GdhFileReads.scene_tree(scene_path, -1, false)
180
180
  if not read.get("ok", false):
181
181
  not_followed.append({"scenePath": scene_path, "reason": str(read.get("error", ""))})
182
182
  continue
183
183
  var tree: Dictionary = read["tree"]
184
184
  _instances_of(tree, changed, old_path, new_path, moves)
185
185
  var text: String = texts[scene_path]
186
- var unsaved: String = SceneFile.unsaved_in_editor(scene_path)
186
+ var unsaved: String = GdhSceneFile.unsaved_in_editor(scene_path)
187
187
  var rewritten: String = text
188
188
  if not new_path.is_empty():
189
189
  rewritten = _rewritten(text, moves, old_path.get_base_dir() != new_path.get_base_dir())
@@ -198,7 +198,7 @@ static func follow(changed: String, old_path: String, new_path: String, carried:
198
198
  )
199
199
  continue
200
200
  file.close()
201
- SceneFile.refresh(scene_path)
201
+ GdhSceneFile.refresh(scene_path)
202
202
  followed.append(scene_path)
203
203
  if moves.is_empty() or not text.contains("NodePath("):
204
204
  continue
@@ -335,7 +335,7 @@ static func _attribute_moved(
335
335
  var found: RegExMatch = RegEx.create_from_string(' %s="([^"]*)"' % attribute).search(line)
336
336
  if found == null:
337
337
  return line
338
- var moved: String = Paths.moved(found.get_string(1), moves)
338
+ var moved: String = GdhPaths.moved(found.get_string(1), moves)
339
339
  if moved == found.get_string(1):
340
340
  return line
341
341
  var placed: String = _attribute_set(line, attribute, moved)
@@ -11,9 +11,9 @@ extends RefCounted
11
11
 
12
12
  enum { UNCHANGED, REWRITTEN, DELETED }
13
13
 
14
- const HeadlessCheck = preload("../headless_check.gd")
15
- const Read = preload("../reading.gd")
16
- const SceneFile = preload("../scene_file.gd")
14
+ const GdhHeadlessCheck = preload("../headless_check.gd")
15
+ const GdhRead = preload("../reading.gd")
16
+ const GdhSceneFile = preload("../scene_file.gd")
17
17
  ## PROPERTY_HINT_NO_NODEPATH, which marks a property the editor's rename skips. It is not bound for
18
18
  ## scripts, and follows PROPERTY_HINT_ONESHOT in the engine's list.
19
19
  const HINT_NO_NODEPATH: int = PROPERTY_HINT_ONESHOT + 1
@@ -30,7 +30,7 @@ var _homes: Dictionary = {}
30
30
  ## it had, its record, the file]. The editor shares such a resource with every scene using it, so a
31
31
  ## rewrite that is not saved is put back.
32
32
  var _outside: Array[Array] = []
33
- var _scene: SceneFile = null
33
+ var _scene: GdhSceneFile = null
34
34
  var _moves: Dictionary = {}
35
35
  var _back: Dictionary = {}
36
36
  var _seen: Dictionary = {}
@@ -50,7 +50,7 @@ static func moved(given: String, moves: Dictionary) -> String:
50
50
 
51
51
  ## Carries [param moves], from the root of [param scene], into the paths it holds. Called after the
52
52
  ## move and before the write. Answers how many paths it rewrote.
53
- func carry(scene: SceneFile, moves: Dictionary) -> int:
53
+ func carry(scene: GdhSceneFile, moves: Dictionary) -> int:
54
54
  if moves.is_empty():
55
55
  return 0
56
56
  _scene = scene
@@ -92,7 +92,7 @@ func carry(scene: SceneFile, moves: Dictionary) -> int:
92
92
  ## Opens [param scene_path], carries [param moves] into it, and writes it when that rewrote a path.
93
93
  ## Answers "" or why it was left as it was.
94
94
  func carry_into(scene_path: String, moves: Dictionary) -> String:
95
- var scene: SceneFile = SceneFile.new()
95
+ var scene: GdhSceneFile = GdhSceneFile.new()
96
96
  var refused: Dictionary = scene.open(scene_path, true)
97
97
  if not refused.is_empty():
98
98
  return str(refused.get("error", ""))
@@ -127,7 +127,7 @@ func put_back(scene_path: String, why: String = "") -> void:
127
127
  func answer() -> Dictionary:
128
128
  for file: String in _homes:
129
129
  var resource: Resource = _homes[file]
130
- var saving: Error = SceneFile.save_keeping_uid(resource, file)
130
+ var saving: Error = GdhSceneFile.save_keeping_uid(resource, file)
131
131
  if saving == OK:
132
132
  if Engine.is_editor_hint():
133
133
  EditorInterface.get_resource_filesystem().update_file(file)
@@ -181,11 +181,13 @@ static func _left(record: Dictionary, why: String) -> Dictionary:
181
181
  ## Whether [param property] can hold a node path the editor's rename would follow: one saved or
182
182
  ## shown, of a type that holds paths, and not marked as holding none.
183
183
  static func _may_hold_paths(property: Dictionary) -> bool:
184
- if not Read.as_int(property.get("usage")) & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR):
184
+ if not GdhRead.as_int(property.get("usage")) & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR):
185
185
  return false
186
- if Read.as_int(property.get("hint")) == HINT_NO_NODEPATH:
186
+ if GdhRead.as_int(property.get("hint")) == HINT_NO_NODEPATH:
187
187
  return false
188
- return [TYPE_OBJECT, TYPE_NODE_PATH, TYPE_ARRAY, TYPE_DICTIONARY].has(Read.as_int(property.get("type")))
188
+ return [TYPE_OBJECT, TYPE_NODE_PATH, TYPE_ARRAY, TYPE_DICTIONARY].has(
189
+ GdhRead.as_int(property.get("type"))
190
+ )
189
191
 
190
192
 
191
193
  ## [param value], held by the node that was at [param was] and is at [param now], with each path in
@@ -421,7 +423,7 @@ func _home_of(animation: Animation, library: AnimationLibrary) -> Dictionary:
421
423
  }
422
424
  if not Engine.is_editor_hint():
423
425
  var script: Script = home.get_script()
424
- if (script != null and not script.is_tool()) or HeadlessCheck.holds_scripted_embedded(home, {}):
426
+ if (script != null and not script.is_tool()) or GdhHeadlessCheck.holds_scripted_embedded(home, {}):
425
427
  return {
426
428
  "why":
427
429
  (
@@ -432,7 +434,7 @@ func _home_of(animation: Animation, library: AnimationLibrary) -> Dictionary:
432
434
  )
433
435
  % file
434
436
  )
435
- + HeadlessCheck.REMEDY
437
+ + GdhHeadlessCheck.REMEDY
436
438
  )
437
439
  }
438
440
  return {"file": file, "home": home, "why": ""}
@@ -4,8 +4,8 @@ extends RefCounted
4
4
  ## What a new node in a scene is made or copied from, what the scene owns of it, and where among its
5
5
  ## siblings a node may go.
6
6
 
7
- const Read = preload("../reading.gd")
8
- const PropertyValues = preload("../property_values.gd")
7
+ const GdhRead = preload("../reading.gd")
8
+ const GdhPropertyValues = preload("../property_values.gd")
9
9
 
10
10
 
11
11
  ## The scene to instance for an add, or null for a node of a class, beside why neither can be made
@@ -64,11 +64,11 @@ static func copied(source: Node, root: Node, copies: Dictionary) -> Node:
64
64
  return null
65
65
  copy = packed.instantiate(PackedScene.GEN_EDIT_STATE_INSTANCE)
66
66
  for declared: Dictionary in source.get_property_list():
67
- if not (Read.as_int(declared.get("usage", 0)) & PROPERTY_USAGE_STORAGE):
67
+ if not (GdhRead.as_int(declared.get("usage", 0)) & PROPERTY_USAGE_STORAGE):
68
68
  continue
69
69
  var property: String = str(declared.get("name", ""))
70
70
  var value: Variant = source.get(property)
71
- if not PropertyValues.same(copy.get(property), value):
71
+ if not GdhPropertyValues.same(copy.get(property), value):
72
72
  copy.set(property, value)
73
73
  for group: StringName in source.get_groups():
74
74
  if not copy.is_in_group(group):
@@ -100,7 +100,7 @@ static func reconnect(copies: Dictionary, top: Node) -> void:
100
100
  for info: Dictionary in source.get_signal_list():
101
101
  var signal_name: String = str(info.get("name", ""))
102
102
  for conn: Dictionary in source.get_signal_connection_list(signal_name):
103
- var flags: int = Read.as_int(conn.get("flags", 0))
103
+ var flags: int = GdhRead.as_int(conn.get("flags", 0))
104
104
  var callable: Callable = conn.get("callable", Callable())
105
105
  var target: Object = callable.get_object()
106
106
  if not flags & Object.CONNECT_PERSIST or target == null:
@@ -134,7 +134,7 @@ static func unplaceable(parent: Node, node: Node, asked: Variant) -> String:
134
134
  if asked == null:
135
135
  return ""
136
136
  var others: int = parent.get_child_count() - (1 if node != null and node.get_parent() == parent else 0)
137
- var at: int = Read.as_int(asked, -1)
137
+ var at: int = GdhRead.as_int(asked, -1)
138
138
  if at < 0 or at > others:
139
139
  return (
140
140
  "index %s is not a place among the %d other children of %s: give 0 to %d, 0 for first."
@@ -151,7 +151,7 @@ static func unplaceable(parent: Node, node: Node, asked: Variant) -> String:
151
151
  ## Moves [param node] to [param asked] among its siblings, when a place was asked for.
152
152
  static func place(node: Node, asked: Variant) -> void:
153
153
  if asked != null:
154
- node.get_parent().move_child(node, Read.as_int(asked))
154
+ node.get_parent().move_child(node, GdhRead.as_int(asked))
155
155
 
156
156
 
157
157
  ## Why [param instanced] cannot be instanced into [param scene_path], or "" when it can: a scene