gdharness 1.1.47 → 1.1.49
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.
|
@@ -502,9 +502,11 @@ func click(params: Dictionary) -> Dictionary:
|
|
|
502
502
|
var landed: bool = hovered == control or (hovered != null and control.is_ancestor_of(hovered))
|
|
503
503
|
|
|
504
504
|
# The link a rich label says was pressed, which is its own word for what the press reached.
|
|
505
|
-
var links: Array
|
|
506
|
-
var heard: Callable = func(meta: Variant) -> void: links.append(
|
|
507
|
-
|
|
505
|
+
var links: Array = []
|
|
506
|
+
var heard: Callable = func(meta: Variant) -> void: links.append(meta)
|
|
507
|
+
# Read before the press, which may free the label.
|
|
508
|
+
var on_rich_text: bool = rich != null
|
|
509
|
+
if on_rich_text:
|
|
508
510
|
var _listening: int = rich.meta_clicked.connect(heard)
|
|
509
511
|
_press_button(viewport, _button(position, button, true, double))
|
|
510
512
|
await _host.get_tree().process_frame
|
|
@@ -533,8 +535,12 @@ func click(params: Dictionary) -> Dictionary:
|
|
|
533
535
|
}
|
|
534
536
|
if found != null:
|
|
535
537
|
answer["found"] = found
|
|
536
|
-
|
|
537
|
-
|
|
538
|
+
# Whether a link was pressed apart from what it carries: a bare [url] reports an empty meta,
|
|
539
|
+
# and given as the meta alone that press read exactly like one that reached no link.
|
|
540
|
+
if on_rich_text:
|
|
541
|
+
answer["link_pressed"] = not links.is_empty()
|
|
542
|
+
if not links.is_empty():
|
|
543
|
+
answer["link_meta"] = _values.serialize(links.back())
|
|
538
544
|
return _pointer_noted(answer)
|
|
539
545
|
|
|
540
546
|
|
|
@@ -16,6 +16,9 @@ const SPLITS_KEPT: int = 8
|
|
|
16
16
|
## Each `says` split into alternatives, by what was written; see [method alternatives].
|
|
17
17
|
static var _splits: Dictionary[String, Array] = {}
|
|
18
18
|
|
|
19
|
+
## Each `says` as the globs [method matches] tries first, by what was written; see [method _loose].
|
|
20
|
+
static var _globs: Dictionary[String, Array] = {}
|
|
21
|
+
|
|
19
22
|
## Every space separator Unicode has besides the plain space, built once; see [method spaced].
|
|
20
23
|
static var _spaces: RegEx = null
|
|
21
24
|
|
|
@@ -37,19 +40,51 @@ static func says(node: Node, wanted: String) -> bool:
|
|
|
37
40
|
## wait for the end of a turn is a wait for whichever of "won", "lost" or the next turn's words comes
|
|
38
41
|
## first, and read as one glob with the bars in it, it waited out its whole timeout for words no
|
|
39
42
|
## screen says.
|
|
43
|
+
##
|
|
44
|
+
## A space in the words matches any space separator in [param said], which is how they were typed.
|
|
45
|
+
## Each node's words are spaced only once a looser match says they may be the ones: this runs for
|
|
46
|
+
## every node on every look a wait takes, and spacing them all made a look over 16,000 labels half
|
|
47
|
+
## as slow again, which took a game under half its speed on a macOS runner.
|
|
40
48
|
static func matches(said: String, wanted: String) -> bool:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
for glob: String in _loose(wanted):
|
|
50
|
+
if said.matchn(glob):
|
|
51
|
+
var shown: String = spaced(said)
|
|
52
|
+
for words: String in alternatives(wanted):
|
|
53
|
+
if shown.containsn(words) if is_plain(words) else shown.matchn(words):
|
|
54
|
+
return true
|
|
55
|
+
return false
|
|
45
56
|
return false
|
|
46
57
|
|
|
47
58
|
|
|
59
|
+
## Each alternative of [param wanted] as a glob, open at both ends for words written plain, with
|
|
60
|
+
## every space as `?`. Words that match once spaced match this as written, since spacing changes
|
|
61
|
+
## only the characters a `?` stands for, so a text that does not is answered without being spaced.
|
|
62
|
+
## Kept by what was written, as [method alternatives] keeps its split.
|
|
63
|
+
static func _loose(wanted: String) -> Array[String]:
|
|
64
|
+
var kept: Variant = _globs.get(wanted)
|
|
65
|
+
if kept != null:
|
|
66
|
+
var globs: Array[String] = kept
|
|
67
|
+
return globs
|
|
68
|
+
var found: Array[String] = []
|
|
69
|
+
for words: String in alternatives(wanted):
|
|
70
|
+
found.append((("*%s*" % words) if is_plain(words) else words).replace(" ", "?"))
|
|
71
|
+
if _globs.size() >= SPLITS_KEPT:
|
|
72
|
+
_globs.clear()
|
|
73
|
+
_globs[wanted] = found
|
|
74
|
+
return found
|
|
75
|
+
|
|
76
|
+
|
|
48
77
|
## [param text] with every Unicode space separator written as a plain space, which is what a caller
|
|
49
78
|
## types for any of them. A game keeping a name on one line writes it with a non-breaking space, and
|
|
50
79
|
## "Deskanem Bonituk" typed with a plain one found nothing while the screen showed exactly those
|
|
51
80
|
## words. One character for one, so a place found in the result is the same place in [param text].
|
|
81
|
+
##
|
|
82
|
+
## Text that is all ASCII holds none of them and is handed back as it is, which is most of a screen.
|
|
83
|
+
## Its UTF-8 is one byte to a character only when every character is ASCII, and counting that costs
|
|
84
|
+
## a quarter of the substitution.
|
|
52
85
|
static func spaced(text: String) -> String:
|
|
86
|
+
if text.to_utf8_buffer().size() == text.length():
|
|
87
|
+
return text
|
|
53
88
|
if _spaces == null:
|
|
54
89
|
var separators: String = (
|
|
55
90
|
String.chr(0x00A0)
|