gdharness 1.3.0 → 1.3.2

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 (72) hide show
  1. package/build/cli.js +322 -96
  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/declared_values.gd +116 -0
  5. package/build/godot/addons/gdharness_editor/declared_values.gd.uid +1 -0
  6. package/build/godot/addons/gdharness_editor/file_reads.gd +65 -25
  7. package/build/godot/addons/gdharness_editor/headless_check.gd +7 -7
  8. package/build/godot/addons/gdharness_editor/plugin.gd +6 -6
  9. package/build/godot/addons/gdharness_editor/property_values.gd +222 -59
  10. package/build/godot/addons/gdharness_editor/reading.gd +65 -0
  11. package/build/godot/addons/gdharness_editor/scene_file.gd +28 -23
  12. package/build/godot/addons/gdharness_editor/serialisation.gd +49 -94
  13. package/build/godot/addons/gdharness_editor/tool_executor.gd +24 -24
  14. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +52 -41
  15. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +4 -4
  16. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +2 -2
  17. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +14 -14
  18. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +175 -74
  19. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +17 -17
  20. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +14 -12
  21. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +7 -7
  22. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +88 -84
  23. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +4 -4
  24. package/build/godot/addons/gdharness_editor/value_shapes.gd +118 -0
  25. package/build/godot/addons/gdharness_editor/value_shapes.gd.uid +1 -0
  26. package/build/godot/addons/gdharness_runtime/reading.gd +65 -0
  27. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +18 -18
  28. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +29 -29
  29. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +21 -18
  30. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +86 -80
  31. package/build/godot/addons/gdharness_runtime/runtime_input.gd +65 -64
  32. package/build/godot/addons/gdharness_runtime/runtime_items.gd +6 -6
  33. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +8 -8
  34. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +6 -6
  35. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +10 -10
  36. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +7 -7
  37. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +41 -41
  38. package/build/godot/addons/gdharness_runtime/runtime_says.gd +3 -3
  39. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +33 -33
  40. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +20 -20
  41. package/build/godot/addons/gdharness_runtime/runtime_values.gd +52 -25
  42. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +56 -50
  43. package/build/godot/addons/gdharness_runtime/serialisation.gd +49 -94
  44. package/build/godot/addons/gdharness_runtime/value_shapes.gd +118 -0
  45. package/build/godot/addons/gdharness_runtime/value_shapes.gd.uid +1 -0
  46. package/build/godot/operations/animation_reads.gd +7 -19
  47. package/build/godot/operations/audio_buses.gd +10 -10
  48. package/build/godot/operations/class_cache.gd +16 -16
  49. package/build/godot/operations/classdb_queries.gd +25 -15
  50. package/build/godot/operations/declared_values.gd +116 -0
  51. package/build/godot/operations/dependencies.gd +141 -33
  52. package/build/godot/operations/editor_tools.gd +12 -12
  53. package/build/godot/operations/export_presets.gd +14 -14
  54. package/build/godot/operations/file_reads.gd +65 -25
  55. package/build/godot/operations/file_walk.gd +34 -0
  56. package/build/godot/operations/gdscript_analysis.gd +27 -22
  57. package/build/godot/operations/gdscript_authoring.gd +122 -17
  58. package/build/godot/operations/godot_operations.gd +66 -63
  59. package/build/godot/operations/import_pipeline.gd +59 -20
  60. package/build/godot/operations/input_actions.gd +90 -18
  61. package/build/godot/operations/logger.gd +1 -1
  62. package/build/godot/operations/plugins.gd +8 -8
  63. package/build/godot/operations/project_config.gd +83 -20
  64. package/build/godot/operations/project_diagnostics.gd +36 -11
  65. package/build/godot/operations/property_values.gd +222 -59
  66. package/build/godot/operations/reading.gd +65 -0
  67. package/build/godot/operations/rename_checks.gd +3 -3
  68. package/build/godot/operations/resource_files.gd +9 -6
  69. package/build/godot/operations/script_check.gd +23 -7
  70. package/build/godot/operations/serialisation.gd +49 -94
  71. package/build/godot/operations/value_shapes.gd +118 -0
  72. package/package.json +1 -1
@@ -4,18 +4,18 @@ extends RefCounted
4
4
  ## a whole click on a Control or a 3D node found by path. Typing and choosing from a menu, which
5
5
  ## reach the game the way a keyboard does, are in runtime_typing.gd.
6
6
 
7
- const Values = preload("runtime_values.gd")
7
+ const GdhValues = preload("runtime_values.gd")
8
8
 
9
9
  ## Where a 3D node is drawn, which is what a click aimed at one has to work out first. Asked of the
10
10
  ## query module rather than worked out again here, so the place this aims at and the place a rect
11
11
  ## reports are the same place by construction rather than by agreement.
12
- const Queries = preload("runtime_queries.gd")
13
- const Read = preload("reading.gd")
14
- const Hover = preload("runtime_hover.gd")
15
- const Items = preload("runtime_items.gd")
16
- const Screen = preload("runtime_screen.gd")
17
- const Targets = preload("runtime_targets.gd")
18
- const Mouse = preload("runtime_mouse.gd")
12
+ const GdhQueries = preload("runtime_queries.gd")
13
+ const GdhRead = preload("reading.gd")
14
+ const GdhHover = preload("runtime_hover.gd")
15
+ const GdhItems = preload("runtime_items.gd")
16
+ const GdhScreen = preload("runtime_screen.gd")
17
+ const GdhTargets = preload("runtime_targets.gd")
18
+ const GdhMouse = preload("runtime_mouse.gd")
19
19
 
20
20
  ## The distance from a capital letter to its small one in Unicode. A keycode holds the capital.
21
21
  const TO_SMALL: int = 32
@@ -40,8 +40,8 @@ static var _pointer_explained: bool = false
40
40
  static var _hover_explained: bool = false
41
41
 
42
42
  var _host: Node
43
- var _values: Values
44
- var _hover: Hover = Hover.new()
43
+ var _values: GdhValues
44
+ var _hover: GdhHover = GdhHover.new()
45
45
 
46
46
  ## Where the last injected pointer event put the pointer, once one has.
47
47
  ##
@@ -59,7 +59,7 @@ var _pointer_at_usec: int = 0
59
59
  var _arrival_seconds: float = 1.0 / 60.0
60
60
 
61
61
 
62
- func _init(host: Node, values: Values) -> void:
62
+ func _init(host: Node, values: GdhValues) -> void:
63
63
  _host = host
64
64
  _values = values
65
65
 
@@ -146,16 +146,16 @@ func _arrive(position: Vector2) -> Vector2:
146
146
  ## `pressed` is how a caller says otherwise: true holds it down, false lets go of one being held.
147
147
  func inject_action(params: Dictionary) -> Dictionary:
148
148
  var action: String = str(params.get("action", ""))
149
- var held: bool = Read.as_bool(params.get("pressed", true), true)
149
+ var held: bool = GdhRead.as_bool(params.get("pressed", true), true)
150
150
  var whole: bool = not params.has("pressed")
151
- var strength: float = Read.as_float(params.get("strength", 1.0), 1.0)
151
+ var strength: float = GdhRead.as_float(params.get("strength", 1.0), 1.0)
152
152
 
153
153
  if action.is_empty():
154
154
  return {"type": "error", "message": "Action name required"}
155
155
 
156
156
  if not InputMap.has_action(action):
157
157
  return {"type": "error", "message": "Action not found: " + action}
158
- var holding: Variant = Values.held_for(params)
158
+ var holding: Variant = GdhValues.held_for(params)
159
159
  if holding is String:
160
160
  return {"type": "error", "message": holding}
161
161
  var frames: int = holding
@@ -174,7 +174,7 @@ func inject_action(params: Dictionary) -> Dictionary:
174
174
  "action": action,
175
175
  "pressed": held and not whole,
176
176
  "whole": whole,
177
- "held_frames": Values.held_answer(whole, frames),
177
+ "held_frames": GdhValues.held_answer(whole, frames),
178
178
  }
179
179
 
180
180
 
@@ -195,7 +195,7 @@ func _say_action(action: String, down: bool, strength: float) -> void:
195
195
  ## Presses one key, and lets go of it again unless asked to hold it. See [method inject_action].
196
196
  func inject_key(params: Dictionary) -> Dictionary:
197
197
  var keycode_raw: Variant = params.get("keycode", 0)
198
- var held: bool = Read.as_bool(params.get("pressed", true), true)
198
+ var held: bool = GdhRead.as_bool(params.get("pressed", true), true)
199
199
  var whole: bool = not params.has("pressed")
200
200
  var key_label: String = str(params.get("key_label", ""))
201
201
 
@@ -203,8 +203,8 @@ func inject_key(params: Dictionary) -> Dictionary:
203
203
  var named: String = keycode_raw
204
204
  if not named.is_empty() and key_label.is_empty():
205
205
  key_label = named
206
- var keycode: int = 0 if keycode_raw is String else Read.as_int(keycode_raw)
207
- var holding: Variant = Values.held_for(params)
206
+ var keycode: int = 0 if keycode_raw is String else GdhRead.as_int(keycode_raw)
207
+ var holding: Variant = GdhValues.held_for(params)
208
208
  if holding is String:
209
209
  return {"type": "error", "message": holding}
210
210
  var frames: int = holding
@@ -229,9 +229,9 @@ func inject_key(params: Dictionary) -> Dictionary:
229
229
  event.physical_keycode = event.keycode
230
230
  event.key_label = event.keycode
231
231
 
232
- event.shift_pressed = Read.as_bool(params.get("shift", false))
233
- event.ctrl_pressed = Read.as_bool(params.get("ctrl", false))
234
- event.alt_pressed = Read.as_bool(params.get("alt", false))
232
+ event.shift_pressed = GdhRead.as_bool(params.get("shift", false))
233
+ event.ctrl_pressed = GdhRead.as_bool(params.get("ctrl", false))
234
+ event.alt_pressed = GdhRead.as_bool(params.get("alt", false))
235
235
 
236
236
  # The fourth thing a real event carries, and the only one a text field reads: LineEdit and
237
237
  # TextEdit insert `unicode` and never consult the keycode, so an injected key could press any
@@ -250,7 +250,7 @@ func inject_key(params: Dictionary) -> Dictionary:
250
250
  return {
251
251
  "type": "input_injected",
252
252
  "input_type": "key",
253
- "held_frames": Values.held_answer(whole, frames),
253
+ "held_frames": GdhValues.held_answer(whole, frames),
254
254
  "keycode": event.keycode,
255
255
  "physical_keycode": event.physical_keycode,
256
256
  "shift": event.shift_pressed,
@@ -284,22 +284,22 @@ func _glyph_of(keycode: Key, shifted: bool) -> int:
284
284
  ## `pressed` is how a caller asks for one half, the way a drag is made: true holds the button down,
285
285
  ## false lets go of one being held.
286
286
  func inject_mouse_click(params: Dictionary) -> Dictionary:
287
- var point: Variant = Mouse.read_point(params, "x", "y")
287
+ var point: Variant = GdhMouse.read_point(params, "x", "y")
288
288
  if point is String:
289
289
  return {"type": "error", "message": point}
290
290
  var position: Vector2 = point
291
- var button: int = Mouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
291
+ var button: int = GdhMouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
292
292
  if button < 0:
293
- return Mouse.no_such_button(params.get("button"))
294
- var held: bool = Read.as_bool(params.get("pressed", true), true)
295
- var double: bool = Read.as_bool(params.get("doubleClick", false))
293
+ return GdhMouse.no_such_button(params.get("button"))
294
+ var held: bool = GdhRead.as_bool(params.get("pressed", true), true)
295
+ var double: bool = GdhRead.as_bool(params.get("doubleClick", false))
296
296
  # A wheel step is a press and a release together, as a mouse sends one: there is no holding a
297
297
  # wheel. A lone wheel press left the viewport's mouse focus on the control that took it, with
298
298
  # the wheel's bit in the focus mask, and every click after it landed on that control rather
299
299
  # than under the pointer, landing true and doing nothing, until a release was sent by hand.
300
- var notch: bool = held and Mouse.mask_of(button) == 0
300
+ var notch: bool = held and GdhMouse.mask_of(button) == 0
301
301
  var whole: bool = notch or not params.has("pressed")
302
- var holding: Variant = Values.held_for(params)
302
+ var holding: Variant = GdhValues.held_for(params)
303
303
  if holding is String:
304
304
  return {"type": "error", "message": holding}
305
305
  var frames: int = holding
@@ -328,7 +328,7 @@ func inject_mouse_click(params: Dictionary) -> Dictionary:
328
328
  {
329
329
  "type": "input_injected",
330
330
  "input_type": "mouse_click",
331
- "held_frames": Values.held_answer(whole and not notch, frames),
331
+ "held_frames": GdhValues.held_answer(whole and not notch, frames),
332
332
  "position": [position.x, position.y],
333
333
  "button": button,
334
334
  "pressed": held and not whole,
@@ -349,14 +349,14 @@ func inject_mouse_click(params: Dictionary) -> Dictionary:
349
349
  ## would have carried. A relative the caller gives is kept, since a game may want to read a motion
350
350
  ## the position does not show.
351
351
  func inject_mouse_motion(params: Dictionary) -> Dictionary:
352
- var point: Variant = Mouse.read_point(params, "x", "y")
352
+ var point: Variant = GdhMouse.read_point(params, "x", "y")
353
353
  if point is String:
354
354
  return {"type": "error", "message": point}
355
355
  var position: Vector2 = point
356
356
  var relative: Vector2 = _arrive(position)
357
357
  if params.has("relativeX") or params.has("relativeY"):
358
358
  relative = Vector2(
359
- Read.as_float(params.get("relativeX", 0.0)), Read.as_float(params.get("relativeY", 0.0))
359
+ GdhRead.as_float(params.get("relativeX", 0.0)), GdhRead.as_float(params.get("relativeY", 0.0))
360
360
  )
361
361
 
362
362
  var supplied: bool = _follow_in_the_window(position)
@@ -385,26 +385,26 @@ func inject_mouse_motion(params: Dictionary) -> Dictionary:
385
385
  ## Each motion goes in a frame of its own because the engine merges the motions it is given within
386
386
  ## one frame into a single event, as it does a real mouse's, and a game counting motions counts one.
387
387
  func inject_mouse_drag(params: Dictionary) -> Dictionary:
388
- var stroke: Variant = Mouse.stroke_of(params)
388
+ var stroke: Variant = GdhMouse.stroke_of(params)
389
389
  if stroke is String:
390
390
  return {"type": "error", "message": stroke}
391
391
  var points: Array[Vector2] = stroke
392
- var button: int = Mouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
392
+ var button: int = GdhMouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
393
393
  if button < 0:
394
- return Mouse.no_such_button(params.get("button"))
395
- var own: int = Mouse.mask_of(button)
394
+ return GdhMouse.no_such_button(params.get("button"))
395
+ var own: int = GdhMouse.mask_of(button)
396
396
  if own == 0:
397
397
  return {
398
398
  "type": "error",
399
399
  "message": "A wheel step has no held position to drag from: give left, right or middle."
400
400
  }
401
- var frames: int = Read.as_int(params.get("frames", 0), 0)
402
- if frames < 1 or frames > Values.MOST_HELD:
401
+ var frames: int = GdhRead.as_int(params.get("frames", 0), 0)
402
+ if frames < 1 or frames > GdhValues.MOST_HELD:
403
403
  return {
404
- "type": "error", "message": "frames is %d, and it takes 1 to %d." % [frames, Values.MOST_HELD]
404
+ "type": "error", "message": "frames is %d, and it takes 1 to %d." % [frames, GdhValues.MOST_HELD]
405
405
  }
406
406
 
407
- var lengths: Array[float] = Mouse.lengths_of(points)
407
+ var lengths: Array[float] = GdhMouse.lengths_of(points)
408
408
  var start: Vector2 = points[0]
409
409
  var end: Vector2 = points[points.size() - 1]
410
410
  var _moved: Vector2 = _arrive(start)
@@ -413,7 +413,7 @@ func inject_mouse_drag(params: Dictionary) -> Dictionary:
413
413
  var travelled: Vector2 = Vector2.ZERO
414
414
  for step: int in range(1, frames + 1):
415
415
  await _host.get_tree().process_frame
416
- var at: Vector2 = Mouse.along(points, lengths, float(step) / frames)
416
+ var at: Vector2 = GdhMouse.along(points, lengths, float(step) / frames)
417
417
  var relative: Vector2 = _arrive(at)
418
418
  travelled += relative
419
419
  supplied = _follow_in_the_window(at) or supplied
@@ -507,7 +507,7 @@ func click(params: Dictionary) -> Dictionary:
507
507
  var found: Variant = null
508
508
  var item: Variant = null
509
509
  if not wanted.is_empty():
510
- var picked: Dictionary = Targets.control_saying(
510
+ var picked: Dictionary = GdhTargets.control_saying(
511
511
  _host.get_tree().root, "/root" if node_path.is_empty() else node_path, wanted, params.get("index")
512
512
  )
513
513
  if picked.has("message"):
@@ -518,7 +518,7 @@ func click(params: Dictionary) -> Dictionary:
518
518
  if node_path.is_empty():
519
519
  return {"type": "error", "message": "click needs a path, or says to find the control by its words"}
520
520
 
521
- var standing: Dictionary = Values.node_at(_host.get_tree().root, node_path)
521
+ var standing: Dictionary = GdhValues.node_at(_host.get_tree().root, node_path)
522
522
  if standing.has("message"):
523
523
  return standing
524
524
  var node: Node = standing["node"]
@@ -542,7 +542,7 @@ func click(params: Dictionary) -> Dictionary:
542
542
  var item_scrolled: bool = false
543
543
  if item != null:
544
544
  var found_by_words: Dictionary = found
545
- var placed_item: Dictionary = await Items.in_view(
545
+ var placed_item: Dictionary = await GdhItems.in_view(
546
546
  _host.get_tree(), control, node_path, item, wanted, found_by_words
547
547
  )
548
548
  if placed_item.has("message"):
@@ -551,7 +551,7 @@ func click(params: Dictionary) -> Dictionary:
551
551
  item_scrolled = placed_item["scrolled"]
552
552
  var rich: RichTextLabel = control as RichTextLabel
553
553
  if found != null and rich != null:
554
- var placed: Dictionary = Targets.point_on_words(rich, wanted)
554
+ var placed: Dictionary = GdhTargets.point_on_words(rich, wanted)
555
555
  var found_here: Dictionary = found
556
556
  if placed.has("point"):
557
557
  aim = placed["point"]
@@ -579,7 +579,7 @@ func click(params: Dictionary) -> Dictionary:
579
579
  var scrolled: bool = item_scrolled
580
580
  if not _in_sight(control, own, local):
581
581
  scrolled = await _scroll_into_view(control) or item_scrolled
582
- var left: String = Values.afterwards(control)
582
+ var left: String = GdhValues.afterwards(control)
583
583
  if left != "in_tree":
584
584
  return {
585
585
  "type": "error",
@@ -591,7 +591,7 @@ func click(params: Dictionary) -> Dictionary:
591
591
  }
592
592
  local = control.get_global_transform_with_canvas() * aim
593
593
 
594
- var reached: Dictionary = Screen.reach(own, local)
594
+ var reached: Dictionary = GdhScreen.reach(own, local)
595
595
  var viewport: Viewport = reached["viewport"]
596
596
  var centre: Vector2 = reached["point"]
597
597
  var position: Vector2 = viewport.get_final_transform() * centre
@@ -602,10 +602,10 @@ func click(params: Dictionary) -> Dictionary:
602
602
  var out_there: String = _out_of_reach(control, node_path, local, reached, scrolled)
603
603
  if not out_there.is_empty():
604
604
  return {"type": "error", "message": out_there}
605
- var button: int = Mouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
605
+ var button: int = GdhMouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
606
606
  if button < 0:
607
- return Mouse.no_such_button(params.get("button"))
608
- var double: bool = Read.as_bool(params.get("double", false))
607
+ return GdhMouse.no_such_button(params.get("button"))
608
+ var double: bool = GdhRead.as_bool(params.get("double", false))
609
609
 
610
610
  # Pushed into the viewport rather than through Input: Input accumulates events and flushes
611
611
  # them at the next frame, so the hovered control read below would be the one from before
@@ -654,7 +654,7 @@ func click(params: Dictionary) -> Dictionary:
654
654
  # What became of the control: still in the tree, taken out of it, or freed. A button that
655
655
  # opened another screen is the second or the third, and the caller wants to hear that
656
656
  # rather than guess it from a tree that has changed shape.
657
- var afterwards: String = Values.afterwards(control)
657
+ var afterwards: String = GdhValues.afterwards(control)
658
658
 
659
659
  var answer: Dictionary = {
660
660
  "type": "clicked",
@@ -692,11 +692,11 @@ func click(params: Dictionary) -> Dictionary:
692
692
  ## what is underneath, which answered `landed: false` with nothing saying why.
693
693
  func _takes_no_click(control: Control, node_path: String) -> String:
694
694
  if not control.is_visible_in_tree():
695
- return "%s is not visible%s, so nothing can click it" % [node_path, Targets.why_hidden(control)]
695
+ return "%s is not visible%s, so nothing can click it" % [node_path, GdhTargets.why_hidden(control)]
696
696
  var button: BaseButton = control as BaseButton
697
697
  if button != null and button.disabled:
698
698
  return "%s is disabled, so clicking it presses nothing" % node_path
699
- var turned_off: Control = Targets.pointer_turned_off_by(control)
699
+ var turned_off: Control = GdhTargets.pointer_turned_off_by(control)
700
700
  if turned_off != null:
701
701
  var on: String = "itself" if turned_off == control else str(turned_off.get_path())
702
702
  return (
@@ -708,7 +708,7 @@ func _takes_no_click(control: Control, node_path: String) -> String:
708
708
  )
709
709
  if not control.can_process():
710
710
  var why: String = _why_it_does_not_process(control, node_path)
711
- var over: Node = Targets.drawn_over(control)
711
+ var over: Node = GdhTargets.drawn_over(control)
712
712
  var cover: String = "" if over == null else "; %s is drawn over it" % over.get_path()
713
713
  if _host.get_tree().paused:
714
714
  return (
@@ -773,7 +773,7 @@ func _out_of_reach(
773
773
 
774
774
 
775
775
  func _no_window_note(viewport: Viewport) -> String:
776
- return Targets.no_window_note(viewport, _host.get_tree().root)
776
+ return GdhTargets.no_window_note(viewport, _host.get_tree().root)
777
777
 
778
778
 
779
779
  ## Sends a click's press or release into [param viewport], through Input when that is the game's
@@ -787,7 +787,7 @@ func _no_window_note(viewport: Viewport) -> String:
787
787
  ## click meant to open it. Games read that state too, through Input.is_mouse_button_pressed.
788
788
  ##
789
789
  ## Any other viewport is pushed into directly: Input reaches only the game's window. That is a
790
- ## viewport with no place on the screen, since `Screen.reach` carries every other one there.
790
+ ## viewport with no place on the screen, since `GdhScreen.reach` carries every other one there.
791
791
  func _press_button(viewport: Viewport, event: InputEventMouseButton) -> void:
792
792
  if viewport == _host.get_tree().root:
793
793
  Input.parse_input_event(event)
@@ -813,10 +813,11 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
813
813
  if not item.is_visible_in_tree():
814
814
  return {
815
815
  "type": "error",
816
- "message": "%s is not visible%s, so nothing can click it" % [node_path, Targets.why_hidden(item)]
816
+ "message":
817
+ "%s is not visible%s, so nothing can click it" % [node_path, GdhTargets.why_hidden(item)]
817
818
  }
818
819
 
819
- var found: Dictionary = Queries.in_frame(item)
820
+ var found: Dictionary = GdhQueries.in_frame(item)
820
821
  if found.is_empty():
821
822
  return {
822
823
  "type": "error",
@@ -841,7 +842,7 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
841
842
  )
842
843
  }
843
844
 
844
- var out: Array[Dictionary] = Screen.steps_out(viewport, aim)
845
+ var out: Array[Dictionary] = GdhScreen.steps_out(viewport, aim)
845
846
  var arriving: Viewport = out.back()["viewport"]
846
847
  var reached_point: Vector2 = out.back()["point"]
847
848
  # Checked where the pointer arrives as well as where the node is drawn: a room in a SubViewport
@@ -857,10 +858,10 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
857
858
  )
858
859
  }
859
860
  var position: Vector2 = arriving.get_final_transform() * reached_point
860
- var button: int = Mouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
861
+ var button: int = GdhMouse.button_of(params.get("button", MOUSE_BUTTON_LEFT))
861
862
  if button < 0:
862
- return Mouse.no_such_button(params.get("button"))
863
- var double: bool = Read.as_bool(params.get("double", false))
863
+ return GdhMouse.no_such_button(params.get("button"))
864
+ var double: bool = GdhRead.as_bool(params.get("double", false))
864
865
 
865
866
  arriving.push_input(_motion(position, _arrive(position)))
866
867
  var supplied: bool = _hover.follow(arriving, reached_point)
@@ -894,7 +895,7 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
894
895
  )
895
896
 
896
897
 
897
- ## Whether a pointer on its way out through [param out], the steps [method Screen.steps_out]
898
+ ## Whether a pointer on its way out through [param out], the steps [method GdhScreen.steps_out]
898
899
  ## answers, gets past the interface in every viewport, as {"landed", "hovered"}: the path of the
899
900
  ## control that took it, or of the one under it that let it by, or null.
900
901
  ##
@@ -979,6 +980,6 @@ func _button(position: Vector2, button: int, pressed: bool, double: bool) -> Inp
979
980
  event.pressed = pressed
980
981
  event.double_click = double
981
982
  var held: int = Input.get_mouse_button_mask()
982
- var own: int = Mouse.mask_of(button)
983
+ var own: int = GdhMouse.mask_of(button)
983
984
  event.button_mask = (held | own) if pressed else (held & ~own)
984
985
  return event
@@ -4,12 +4,12 @@ extends RefCounted
4
4
  ## a tree row or a menu bar title. Each is drawn by the control rather than held as a node, so a click
5
5
  ## on the control's path presses its middle, which is whichever item happens to sit there.
6
6
 
7
- const Says = preload("runtime_says.gd")
8
- const Values = preload("runtime_values.gd")
9
- const Words = preload("runtime_words.gd")
7
+ const GdhSays = preload("runtime_says.gd")
8
+ const GdhValues = preload("runtime_values.gd")
9
+ const GdhWords = preload("runtime_words.gd")
10
10
 
11
11
 
12
- ## Where [param control] draws [param item], one of [method Words.items_of], in the control's own
12
+ ## Where [param control] draws [param item], one of [method GdhWords.items_of], in the control's own
13
13
  ## space, or an empty rectangle while it draws it nowhere a pointer reaches: a tab scrolled off its
14
14
  ## bar, an entry or a row scrolled out of its list, a menu bar the operating system draws. A tree
15
15
  ## row is the cell saying [param wanted] when one does, and the whole row otherwise.
@@ -54,7 +54,7 @@ static func item_rect(control: Control, item: Variant, wanted: String) -> Rect2:
54
54
  ## does, its cells read together.
55
55
  static func tree_column(tree: Tree, row: TreeItem, wanted: String) -> int:
56
56
  for column: int in tree.columns:
57
- if Says.matches(Words.cell_says(tree, row, column), wanted):
57
+ if GdhSays.matches(GdhWords.cell_says(tree, row, column), wanted):
58
58
  return column
59
59
  return -1
60
60
 
@@ -96,7 +96,7 @@ static func in_view(
96
96
  if scrolled:
97
97
  # A tree places its rows by the scroll it last drew with.
98
98
  await scene.process_frame
99
- var left: String = Values.afterwards(control)
99
+ var left: String = GdhValues.afterwards(control)
100
100
  if left != "in_tree" or (typeof(item) == TYPE_OBJECT and not is_instance_valid(item)):
101
101
  return {
102
102
  "type": "error",
@@ -3,9 +3,9 @@ extends RefCounted
3
3
  ## The menu a choice is made from and the item in it, for a choice made by what an item says or by
4
4
  ## where it is in the list.
5
5
 
6
- const Read = preload("reading.gd")
7
- const Says = preload("runtime_says.gd")
8
- const Words = preload("runtime_words.gd")
6
+ const GdhRead = preload("reading.gd")
7
+ const GdhSays = preload("runtime_says.gd")
8
+ const GdhWords = preload("runtime_words.gd")
9
9
 
10
10
 
11
11
  ## The menu [param node] is, or the one it holds. An [OptionButton] and a [MenuButton] both keep
@@ -38,7 +38,7 @@ static func menu_of(node: Node) -> PopupMenu:
38
38
  ## still count after them, for a caller that has the key from the source.
39
39
  static func wanted_items(menu: PopupMenu, params: Dictionary) -> Array[int]:
40
40
  if params.has("index"):
41
- var asked: int = Read.as_int(params.get("index", -1), -1)
41
+ var asked: int = GdhRead.as_int(params.get("index", -1), -1)
42
42
  return _items([asked] if asked >= 0 and asked < menu.get_item_count() else [])
43
43
  var wanted: String = str(params.get("text", ""))
44
44
  if wanted.is_empty():
@@ -54,14 +54,14 @@ static func wanted_items(menu: PopupMenu, params: Dictionary) -> Array[int]:
54
54
  var shown: Array[String] = []
55
55
  var held: Array[String] = []
56
56
  for index: int in order:
57
- shown.append(Words.item_says(menu, index))
57
+ shown.append(GdhWords.item_says(menu, index))
58
58
  held.append(menu.get_item_text(index))
59
59
  for words: Array[String] in [shown, held]:
60
60
  for at: int in words.size():
61
61
  if words[at] == wanted:
62
62
  return _items([order[at]])
63
63
  for at: int in words.size():
64
- if Says.spaced(words[at]).nocasecmp_to(Says.spaced(wanted)) == 0:
64
+ if GdhSays.spaced(words[at]).nocasecmp_to(GdhSays.spaced(wanted)) == 0:
65
65
  return _items([order[at]])
66
66
  # Separators are left out here: a heading is refused when named in full, and a pattern that
67
67
  # matched one beside the item it heads would tie the two.
@@ -70,7 +70,7 @@ static func wanted_items(menu: PopupMenu, params: Dictionary) -> Array[int]:
70
70
  var enabled: Array[int] = []
71
71
  for at: int in words.size():
72
72
  var index: int = order[at]
73
- if menu.is_item_separator(index) or not Says.matches(words[at], wanted):
73
+ if menu.is_item_separator(index) or not GdhSays.matches(words[at], wanted):
74
74
  continue
75
75
  matched.append(index)
76
76
  if not menu.is_item_disabled(index):
@@ -93,7 +93,7 @@ static func _items(indices: Array) -> Array[int]:
93
93
  static func items_of(menu: PopupMenu) -> Array[String]:
94
94
  var said: Array[String] = []
95
95
  for index: int in menu.get_item_count():
96
- var words: String = Words.item_says(menu, index)
96
+ var words: String = GdhWords.item_says(menu, index)
97
97
  if not menu.is_item_separator(index):
98
98
  said.append("%d: %s" % [index, words])
99
99
  elif not words.strip_edges().is_empty():
@@ -3,7 +3,7 @@ extends RefCounted
3
3
  ## What a pointer call names: a point, the stroke of a drag, a mouse button and its mask bit. Read
4
4
  ## here and sent from runtime_input.gd, which keeps where the pointer is.
5
5
 
6
- const Read = preload("reading.gd")
6
+ const GdhRead = preload("reading.gd")
7
7
 
8
8
 
9
9
  ## A point the tool schema sends as two flat numbers. Answers a Vector2, or the String that says
@@ -11,7 +11,7 @@ const Read = preload("reading.gd")
11
11
  static func read_point(params: Dictionary, x_key: String, y_key: String) -> Variant:
12
12
  if not params.has(x_key) or not params.has(y_key):
13
13
  return "%s and %s are both needed." % [x_key, y_key]
14
- return Vector2(Read.as_float(params[x_key]), Read.as_float(params[y_key]))
14
+ return Vector2(GdhRead.as_float(params[x_key]), GdhRead.as_float(params[y_key]))
15
15
 
16
16
 
17
17
  ## The points of a drag: x, y, then each of via, then toX, toY. Answers the String saying what is
@@ -20,7 +20,7 @@ static func stroke_of(params: Dictionary) -> Variant:
20
20
  for key: String in ["x", "y", "toX", "toY"]:
21
21
  if not params.has(key):
22
22
  return "mouse_drag needs x, y, toX and toY: %s is missing." % key
23
- var points: Array[Vector2] = [Vector2(Read.as_float(params["x"]), Read.as_float(params["y"]))]
23
+ var points: Array[Vector2] = [Vector2(GdhRead.as_float(params["x"]), GdhRead.as_float(params["y"]))]
24
24
  var via: Variant = params.get("via", [])
25
25
  if not via is Array:
26
26
  return "via must be a list of [x, y] points."
@@ -29,8 +29,8 @@ static func stroke_of(params: Dictionary) -> Variant:
29
29
  var pair: Array = point if point is Array else []
30
30
  if pair.size() < 2:
31
31
  return "via must be a list of [x, y] points, and holds %s." % JSON.stringify(point)
32
- points.append(Vector2(Read.as_float(pair[0]), Read.as_float(pair[1])))
33
- points.append(Vector2(Read.as_float(params["toX"]), Read.as_float(params["toY"])))
32
+ points.append(Vector2(GdhRead.as_float(pair[0]), GdhRead.as_float(pair[1])))
33
+ points.append(Vector2(GdhRead.as_float(params["toX"]), GdhRead.as_float(params["toY"])))
34
34
  return points
35
35
 
36
36
 
@@ -100,5 +100,5 @@ static func button_of(raw: Variant) -> int:
100
100
  return -1
101
101
  # The engine's buttons run from 1 to 9: 0 is MOUSE_BUTTON_NONE, which no event carries, and a
102
102
  # number past the two extra buttons names nothing a mask bit can be made for.
103
- var number: int = Read.as_int(raw, -1)
103
+ var number: int = GdhRead.as_int(raw, -1)
104
104
  return number if number >= MOUSE_BUTTON_LEFT and number <= MOUSE_BUTTON_XBUTTON2 else -1
@@ -8,8 +8,8 @@ extends RefCounted
8
8
  ## reached it as an InputEventAction it never reads, so a controller layout could only be driven by
9
9
  ## calling the game's own methods. The engine still fires the actions bound to a button from these.
10
10
 
11
- const Read = preload("reading.gd")
12
- const Values = preload("runtime_values.gd")
11
+ const GdhRead = preload("reading.gd")
12
+ const GdhValues = preload("runtime_values.gd")
13
13
 
14
14
  ## Controller buttons by the names Godot gives them, for a caller naming one rather than numbering it.
15
15
  const JOY_BUTTONS: Dictionary[String, int] = {
@@ -60,10 +60,10 @@ func inject_joypad_button(params: Dictionary) -> Dictionary:
60
60
  var button: int = _named_or_numbered(given, JOY_BUTTONS, JOY_BUTTON_MAX)
61
61
  if button < 0:
62
62
  return {"type": "error", "message": _not_one_of("button", given, JOY_BUTTONS, JOY_BUTTON_MAX)}
63
- var device: int = Read.as_int(params.get("device", 0), 0)
64
- var held: bool = Read.as_bool(params.get("pressed", true), true)
63
+ var device: int = GdhRead.as_int(params.get("device", 0), 0)
64
+ var held: bool = GdhRead.as_bool(params.get("pressed", true), true)
65
65
  var whole: bool = not params.has("pressed")
66
- var holding: Variant = Values.held_for(params)
66
+ var holding: Variant = GdhValues.held_for(params)
67
67
  if holding is String:
68
68
  return {"type": "error", "message": holding}
69
69
  var frames: int = holding
@@ -80,7 +80,7 @@ func inject_joypad_button(params: Dictionary) -> Dictionary:
80
80
  return {
81
81
  "type": "input_injected",
82
82
  "input_type": "joypad_button",
83
- "held_frames": Values.held_answer(whole, frames),
83
+ "held_frames": GdhValues.held_answer(whole, frames),
84
84
  "button": button,
85
85
  "button_name": _name_of(button, JOY_BUTTONS),
86
86
  "device": device,
@@ -98,12 +98,12 @@ func inject_joypad_motion(params: Dictionary) -> Dictionary:
98
98
  return {"type": "error", "message": _not_one_of("axis", given, JOY_AXES, JOY_AXIS_MAX)}
99
99
  if not params.has("value"):
100
100
  return {"type": "error", "message": "joypad_motion needs value, where the axis is, -1 to 1"}
101
- var value: float = Read.as_float(params.get("value"), 0.0)
101
+ var value: float = GdhRead.as_float(params.get("value"), 0.0)
102
102
  if value < -1.0 or value > 1.0:
103
103
  return {
104
104
  "type": "error", "message": "value %s is outside -1 to 1, the whole travel of an axis" % value
105
105
  }
106
- var device: int = Read.as_int(params.get("device", 0), 0)
106
+ var device: int = GdhRead.as_int(params.get("device", 0), 0)
107
107
 
108
108
  var event: InputEventJoypadMotion = InputEventJoypadMotion.new()
109
109
  event.axis = axis as JoyAxis
@@ -133,9 +133,9 @@ static func _button(button: int, device: int, down: bool) -> InputEventJoypadBut
133
133
  static func _named_or_numbered(given: Variant, names: Dictionary[String, int], count: int) -> int:
134
134
  if given is String:
135
135
  var named: String = given
136
- return Read.as_int(names.get(named.strip_edges().to_lower(), -1), -1)
136
+ return GdhRead.as_int(names.get(named.strip_edges().to_lower(), -1), -1)
137
137
  if given is int or given is float:
138
- var number: int = Read.as_int(given, -1)
138
+ var number: int = GdhRead.as_int(given, -1)
139
139
  return number if number >= 0 and number < count else -1
140
140
  return -1
141
141
 
@@ -4,8 +4,8 @@ extends RefCounted
4
4
  ## run off the game the node keeps. Every op that reads, writes, calls or waits on a game's state
5
5
  ## walks the same way, so the walk and what it says when a step is not there live in one place.
6
6
 
7
- const Serialisation = preload("serialisation.gd")
8
- const Values = preload("runtime_values.gd")
7
+ const GdhSerialisation = preload("serialisation.gd")
8
+ const GdhValues = preload("runtime_values.gd")
9
9
 
10
10
  ## The calls a path makes on a list or a map: those that take no arguments and change nothing.
11
11
  ##
@@ -96,7 +96,7 @@ const READS_ONLY: String = ", and a path, which a wait reads every frame, only c
96
96
  ##
97
97
  ## A step into a vector, a colour, a rectangle or a transform reads one of its components,
98
98
  ## "size:x" or "global_transform:origin:y", by the names GDScript gives them; see
99
- ## [method Serialisation.components_of].
99
+ ## [method GdhSerialisation.components_of].
100
100
  ##
101
101
  ## Answers with a `message` instead when a step along the way is not there or holds something that
102
102
  ## is not an object, naming the step rather than the whole path: "/root/Main:_game has no property
@@ -151,7 +151,7 @@ static func object_at(root: Node, node: Node, node_path: String, given: Variant)
151
151
  if path.begins_with("/"):
152
152
  var colon: int = path.find(":")
153
153
  start_path = path if colon == -1 else path.substr(0, colon)
154
- var standing: Dictionary = Values.node_at(root, start_path)
154
+ var standing: Dictionary = GdhValues.node_at(root, start_path)
155
155
  if standing.has("message"):
156
156
  return {"message": str(standing["message"])}
157
157
  start = standing["node"]
@@ -185,7 +185,7 @@ static func can_hold(value: Variant) -> bool:
185
185
  ## Whether [param value] is read by its components, a vector or a colour or a transform, and is a
186
186
  ## copy wherever it is read from.
187
187
  static func composite(value: Variant) -> bool:
188
- return not Serialisation.components_of(value).is_empty()
188
+ return not GdhSerialisation.components_of(value).is_empty()
189
189
 
190
190
 
191
191
  ## Whether [param value] is a packed list. Stepped into the way a list is, by index, and a write into
@@ -235,7 +235,7 @@ static func can_read(holder: Variant, named: String) -> bool:
235
235
  return args.is_empty() and method in MAP_CALLS
236
236
  return not _key_in(map, named).is_empty()
237
237
  if composite(holder):
238
- return method.is_empty() and named in Serialisation.components_of(holder)
238
+ return method.is_empty() and named in GdhSerialisation.components_of(holder)
239
239
  if holder is Object:
240
240
  var object: Object = holder
241
241
  if not method.is_empty():
@@ -620,7 +620,7 @@ static func nothing_there(holder: Variant, named: String, called_as: String) ->
620
620
  if composite(holder):
621
621
  var kind: String = type_string(typeof(holder))
622
622
  var sort: String = ("an " if kind.left(1) in ["A", "E", "I", "O", "U"] else "a ") + kind
623
- var has: String = ", ".join(Serialisation.components_of(holder))
623
+ var has: String = ", ".join(GdhSerialisation.components_of(holder))
624
624
  if not container_call.is_empty():
625
625
  return (
626
626
  "%s is %s, which a path reads by its components, %s, and makes no call on"