gdharness 1.2.42 → 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 (70) hide show
  1. package/build/cli.js +571 -363
  2. package/build/godot/addons/gdharness_editor/animation_reads.gd +7 -19
  3. package/build/godot/addons/gdharness_editor/bridge_client.gd +9 -9
  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 +124 -62
  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 +57 -50
  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 +82 -78
  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 +32 -32
  27. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +50 -18
  28. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +86 -80
  29. package/build/godot/addons/gdharness_runtime/runtime_input.gd +65 -69
  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 +13 -21
  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 +124 -62
  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/build/keeper.js +10 -4
  69. package/package.json +1 -2
  70. package/build/index.js +0 -45101
@@ -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", "position")
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,20 +349,15 @@ 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", "position")
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
- elif params.has("relative"):
362
- var movement: Variant = Mouse.read_point(params, "relativeX", "relativeY", "relative")
363
- if movement is String:
364
- return {"type": "error", "message": movement}
365
- relative = movement
366
361
 
367
362
  var supplied: bool = _follow_in_the_window(position)
368
363
  Input.parse_input_event(_motion(position, relative))
@@ -390,26 +385,26 @@ func inject_mouse_motion(params: Dictionary) -> Dictionary:
390
385
  ## Each motion goes in a frame of its own because the engine merges the motions it is given within
391
386
  ## one frame into a single event, as it does a real mouse's, and a game counting motions counts one.
392
387
  func inject_mouse_drag(params: Dictionary) -> Dictionary:
393
- var stroke: Variant = Mouse.stroke_of(params)
388
+ var stroke: Variant = GdhMouse.stroke_of(params)
394
389
  if stroke is String:
395
390
  return {"type": "error", "message": stroke}
396
391
  var points: Array[Vector2] = stroke
397
- 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))
398
393
  if button < 0:
399
- return Mouse.no_such_button(params.get("button"))
400
- var own: int = Mouse.mask_of(button)
394
+ return GdhMouse.no_such_button(params.get("button"))
395
+ var own: int = GdhMouse.mask_of(button)
401
396
  if own == 0:
402
397
  return {
403
398
  "type": "error",
404
399
  "message": "A wheel step has no held position to drag from: give left, right or middle."
405
400
  }
406
- var frames: int = Read.as_int(params.get("frames", 0), 0)
407
- 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:
408
403
  return {
409
- "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]
410
405
  }
411
406
 
412
- var lengths: Array[float] = Mouse.lengths_of(points)
407
+ var lengths: Array[float] = GdhMouse.lengths_of(points)
413
408
  var start: Vector2 = points[0]
414
409
  var end: Vector2 = points[points.size() - 1]
415
410
  var _moved: Vector2 = _arrive(start)
@@ -418,7 +413,7 @@ func inject_mouse_drag(params: Dictionary) -> Dictionary:
418
413
  var travelled: Vector2 = Vector2.ZERO
419
414
  for step: int in range(1, frames + 1):
420
415
  await _host.get_tree().process_frame
421
- var at: Vector2 = Mouse.along(points, lengths, float(step) / frames)
416
+ var at: Vector2 = GdhMouse.along(points, lengths, float(step) / frames)
422
417
  var relative: Vector2 = _arrive(at)
423
418
  travelled += relative
424
419
  supplied = _follow_in_the_window(at) or supplied
@@ -512,7 +507,7 @@ func click(params: Dictionary) -> Dictionary:
512
507
  var found: Variant = null
513
508
  var item: Variant = null
514
509
  if not wanted.is_empty():
515
- var picked: Dictionary = Targets.control_saying(
510
+ var picked: Dictionary = GdhTargets.control_saying(
516
511
  _host.get_tree().root, "/root" if node_path.is_empty() else node_path, wanted, params.get("index")
517
512
  )
518
513
  if picked.has("message"):
@@ -523,7 +518,7 @@ func click(params: Dictionary) -> Dictionary:
523
518
  if node_path.is_empty():
524
519
  return {"type": "error", "message": "click needs a path, or says to find the control by its words"}
525
520
 
526
- 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)
527
522
  if standing.has("message"):
528
523
  return standing
529
524
  var node: Node = standing["node"]
@@ -547,7 +542,7 @@ func click(params: Dictionary) -> Dictionary:
547
542
  var item_scrolled: bool = false
548
543
  if item != null:
549
544
  var found_by_words: Dictionary = found
550
- var placed_item: Dictionary = await Items.in_view(
545
+ var placed_item: Dictionary = await GdhItems.in_view(
551
546
  _host.get_tree(), control, node_path, item, wanted, found_by_words
552
547
  )
553
548
  if placed_item.has("message"):
@@ -556,7 +551,7 @@ func click(params: Dictionary) -> Dictionary:
556
551
  item_scrolled = placed_item["scrolled"]
557
552
  var rich: RichTextLabel = control as RichTextLabel
558
553
  if found != null and rich != null:
559
- var placed: Dictionary = Targets.point_on_words(rich, wanted)
554
+ var placed: Dictionary = GdhTargets.point_on_words(rich, wanted)
560
555
  var found_here: Dictionary = found
561
556
  if placed.has("point"):
562
557
  aim = placed["point"]
@@ -584,7 +579,7 @@ func click(params: Dictionary) -> Dictionary:
584
579
  var scrolled: bool = item_scrolled
585
580
  if not _in_sight(control, own, local):
586
581
  scrolled = await _scroll_into_view(control) or item_scrolled
587
- var left: String = Values.afterwards(control)
582
+ var left: String = GdhValues.afterwards(control)
588
583
  if left != "in_tree":
589
584
  return {
590
585
  "type": "error",
@@ -596,7 +591,7 @@ func click(params: Dictionary) -> Dictionary:
596
591
  }
597
592
  local = control.get_global_transform_with_canvas() * aim
598
593
 
599
- var reached: Dictionary = Screen.reach(own, local)
594
+ var reached: Dictionary = GdhScreen.reach(own, local)
600
595
  var viewport: Viewport = reached["viewport"]
601
596
  var centre: Vector2 = reached["point"]
602
597
  var position: Vector2 = viewport.get_final_transform() * centre
@@ -607,10 +602,10 @@ func click(params: Dictionary) -> Dictionary:
607
602
  var out_there: String = _out_of_reach(control, node_path, local, reached, scrolled)
608
603
  if not out_there.is_empty():
609
604
  return {"type": "error", "message": out_there}
610
- 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))
611
606
  if button < 0:
612
- return Mouse.no_such_button(params.get("button"))
613
- 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))
614
609
 
615
610
  # Pushed into the viewport rather than through Input: Input accumulates events and flushes
616
611
  # them at the next frame, so the hovered control read below would be the one from before
@@ -659,7 +654,7 @@ func click(params: Dictionary) -> Dictionary:
659
654
  # What became of the control: still in the tree, taken out of it, or freed. A button that
660
655
  # opened another screen is the second or the third, and the caller wants to hear that
661
656
  # rather than guess it from a tree that has changed shape.
662
- var afterwards: String = Values.afterwards(control)
657
+ var afterwards: String = GdhValues.afterwards(control)
663
658
 
664
659
  var answer: Dictionary = {
665
660
  "type": "clicked",
@@ -697,11 +692,11 @@ func click(params: Dictionary) -> Dictionary:
697
692
  ## what is underneath, which answered `landed: false` with nothing saying why.
698
693
  func _takes_no_click(control: Control, node_path: String) -> String:
699
694
  if not control.is_visible_in_tree():
700
- 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)]
701
696
  var button: BaseButton = control as BaseButton
702
697
  if button != null and button.disabled:
703
698
  return "%s is disabled, so clicking it presses nothing" % node_path
704
- var turned_off: Control = Targets.pointer_turned_off_by(control)
699
+ var turned_off: Control = GdhTargets.pointer_turned_off_by(control)
705
700
  if turned_off != null:
706
701
  var on: String = "itself" if turned_off == control else str(turned_off.get_path())
707
702
  return (
@@ -713,7 +708,7 @@ func _takes_no_click(control: Control, node_path: String) -> String:
713
708
  )
714
709
  if not control.can_process():
715
710
  var why: String = _why_it_does_not_process(control, node_path)
716
- var over: Node = Targets.drawn_over(control)
711
+ var over: Node = GdhTargets.drawn_over(control)
717
712
  var cover: String = "" if over == null else "; %s is drawn over it" % over.get_path()
718
713
  if _host.get_tree().paused:
719
714
  return (
@@ -778,7 +773,7 @@ func _out_of_reach(
778
773
 
779
774
 
780
775
  func _no_window_note(viewport: Viewport) -> String:
781
- return Targets.no_window_note(viewport, _host.get_tree().root)
776
+ return GdhTargets.no_window_note(viewport, _host.get_tree().root)
782
777
 
783
778
 
784
779
  ## Sends a click's press or release into [param viewport], through Input when that is the game's
@@ -792,7 +787,7 @@ func _no_window_note(viewport: Viewport) -> String:
792
787
  ## click meant to open it. Games read that state too, through Input.is_mouse_button_pressed.
793
788
  ##
794
789
  ## Any other viewport is pushed into directly: Input reaches only the game's window. That is a
795
- ## 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.
796
791
  func _press_button(viewport: Viewport, event: InputEventMouseButton) -> void:
797
792
  if viewport == _host.get_tree().root:
798
793
  Input.parse_input_event(event)
@@ -818,10 +813,11 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
818
813
  if not item.is_visible_in_tree():
819
814
  return {
820
815
  "type": "error",
821
- "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)]
822
818
  }
823
819
 
824
- var found: Dictionary = Queries.in_frame(item)
820
+ var found: Dictionary = GdhQueries.in_frame(item)
825
821
  if found.is_empty():
826
822
  return {
827
823
  "type": "error",
@@ -846,7 +842,7 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
846
842
  )
847
843
  }
848
844
 
849
- var out: Array[Dictionary] = Screen.steps_out(viewport, aim)
845
+ var out: Array[Dictionary] = GdhScreen.steps_out(viewport, aim)
850
846
  var arriving: Viewport = out.back()["viewport"]
851
847
  var reached_point: Vector2 = out.back()["point"]
852
848
  # Checked where the pointer arrives as well as where the node is drawn: a room in a SubViewport
@@ -862,10 +858,10 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
862
858
  )
863
859
  }
864
860
  var position: Vector2 = arriving.get_final_transform() * reached_point
865
- 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))
866
862
  if button < 0:
867
- return Mouse.no_such_button(params.get("button"))
868
- 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))
869
865
 
870
866
  arriving.push_input(_motion(position, _arrive(position)))
871
867
  var supplied: bool = _hover.follow(arriving, reached_point)
@@ -899,7 +895,7 @@ func _click_in_the_world(node_path: String, item: Node3D, params: Dictionary) ->
899
895
  )
900
896
 
901
897
 
902
- ## 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]
903
899
  ## answers, gets past the interface in every viewport, as {"landed", "hovered"}: the path of the
904
900
  ## control that took it, or of the one under it that let it by, or null.
905
901
  ##
@@ -984,6 +980,6 @@ func _button(position: Vector2, button: int, pressed: bool, double: bool) -> Inp
984
980
  event.pressed = pressed
985
981
  event.double_click = double
986
982
  var held: int = Input.get_mouse_button_mask()
987
- var own: int = Mouse.mask_of(button)
983
+ var own: int = GdhMouse.mask_of(button)
988
984
  event.button_mask = (held | own) if pressed else (held & ~own)
989
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,23 +3,15 @@ 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")
7
-
8
-
9
- ## A point the tool schema sends as two flat numbers, or the older form of one [x, y] value.
10
- ## Answers a Vector2, or the String that says what was wrong with it.
11
- static func read_point(params: Dictionary, x_key: String, y_key: String, pair_key: String) -> Variant:
12
- if params.has(x_key) and params.has(y_key):
13
- return Vector2(Read.as_float(params[x_key]), Read.as_float(params[y_key]))
14
- var raw: Variant = params.get(pair_key, Vector2.ZERO)
15
- if raw is Vector2:
16
- return raw
17
- if raw is Array:
18
- var pair: Array = raw
19
- if pair.size() < 2:
20
- return "%s array must contain [x, y]" % pair_key
21
- return Vector2(Read.as_float(pair[0]), Read.as_float(pair[1]))
22
- return "%s must be Vector2 or [x, y]" % pair_key
6
+ const GdhRead = preload("reading.gd")
7
+
8
+
9
+ ## A point the tool schema sends as two flat numbers. Answers a Vector2, or the String that says
10
+ ## which was missing.
11
+ static func read_point(params: Dictionary, x_key: String, y_key: String) -> Variant:
12
+ if not params.has(x_key) or not params.has(y_key):
13
+ return "%s and %s are both needed." % [x_key, y_key]
14
+ return Vector2(GdhRead.as_float(params[x_key]), GdhRead.as_float(params[y_key]))
23
15
 
24
16
 
25
17
  ## The points of a drag: x, y, then each of via, then toX, toY. Answers the String saying what is
@@ -28,7 +20,7 @@ static func stroke_of(params: Dictionary) -> Variant:
28
20
  for key: String in ["x", "y", "toX", "toY"]:
29
21
  if not params.has(key):
30
22
  return "mouse_drag needs x, y, toX and toY: %s is missing." % key
31
- 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"]))]
32
24
  var via: Variant = params.get("via", [])
33
25
  if not via is Array:
34
26
  return "via must be a list of [x, y] points."
@@ -37,8 +29,8 @@ static func stroke_of(params: Dictionary) -> Variant:
37
29
  var pair: Array = point if point is Array else []
38
30
  if pair.size() < 2:
39
31
  return "via must be a list of [x, y] points, and holds %s." % JSON.stringify(point)
40
- points.append(Vector2(Read.as_float(pair[0]), Read.as_float(pair[1])))
41
- 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"])))
42
34
  return points
43
35
 
44
36
 
@@ -108,5 +100,5 @@ static func button_of(raw: Variant) -> int:
108
100
  return -1
109
101
  # The engine's buttons run from 1 to 9: 0 is MOUSE_BUTTON_NONE, which no event carries, and a
110
102
  # number past the two extra buttons names nothing a mask bit can be made for.
111
- var number: int = Read.as_int(raw, -1)
103
+ var number: int = GdhRead.as_int(raw, -1)
112
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"