gdharness 1.3.41 → 1.3.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cli.js +131 -47
- package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
- package/build/godot/addons/gdharness_editor/animation_reads.gd +84 -35
- package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
- package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
- package/build/godot/addons/gdharness_editor/file_reads.gd +114 -39
- package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
- package/build/godot/addons/gdharness_editor/headless_check.gd +94 -41
- package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
- package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
- package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
- package/build/godot/addons/gdharness_editor/reading.gd +37 -12
- package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
- package/build/godot/addons/gdharness_editor/scene_file.gd +136 -79
- package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
- package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
- package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
- package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
- package/build/godot/addons/gdharness_editor/tools/animation_states.gd +41 -28
- package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +84 -50
- package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
- package/build/godot/addons/gdharness_editor/tools/class_tools.gd +34 -30
- package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
- package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
- package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
- package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
- package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +181 -107
- package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
- package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +75 -43
- package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
- package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
- package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +66 -0
- package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd.uid +1 -0
- package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +171 -62
- package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
- package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
- package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
- package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
- package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
- package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
- package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
- package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
- package/build/godot/addons/gdharness_runtime/reading.gd +37 -12
- package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
- package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +153 -148
- package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
- package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
- package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
- package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
- package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
- package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
- package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
- package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +38 -20
- package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
- package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
- package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
- package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
- package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
- package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
- package/build/godot/addons/gdharness_runtime/runtime_touch.gd +211 -0
- package/build/godot/addons/gdharness_runtime/runtime_touch.gd.uid +1 -0
- package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
- package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
- package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
- package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
- package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
- package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
- package/build/godot/addons/gdharness_tests/bench.gd +4 -5
- package/build/godot/addons/gdharness_tests/event.gd +10 -5
- package/build/godot/addons/gdharness_tests/share.gd +38 -18
- package/build/godot/addons/gdharness_tests/suites.gd +3 -3
- package/build/godot/addons/gdharness_tests/wait.gd +3 -2
- package/build/godot/loader/loader.gd +9 -9
- package/build/godot/operations/animation_reads.gd +84 -35
- package/build/godot/operations/audio_buses.gd +48 -19
- package/build/godot/operations/class_cache.gd +16 -11
- package/build/godot/operations/classdb_queries.gd +89 -44
- package/build/godot/operations/declared_values.gd +68 -32
- package/build/godot/operations/dependencies.gd +139 -93
- package/build/godot/operations/editor_tools.gd +9 -10
- package/build/godot/operations/export_presets.gd +100 -54
- package/build/godot/operations/file_reads.gd +114 -39
- package/build/godot/operations/file_walk.gd +12 -5
- package/build/godot/operations/gdscript_analysis.gd +105 -66
- package/build/godot/operations/gdscript_authoring.gd +138 -39
- package/build/godot/operations/godot_operations.gd +17 -11
- package/build/godot/operations/import_pipeline.gd +110 -59
- package/build/godot/operations/input_actions.gd +63 -39
- package/build/godot/operations/patterns.gd +3 -1
- package/build/godot/operations/plugins.gd +36 -16
- package/build/godot/operations/project_config.gd +144 -27
- package/build/godot/operations/project_diagnostics.gd +24 -11
- package/build/godot/operations/project_file.gd +16 -16
- package/build/godot/operations/project_validation.gd +71 -44
- package/build/godot/operations/property_paths.gd +22 -12
- package/build/godot/operations/property_values.gd +143 -78
- package/build/godot/operations/reading.gd +37 -12
- package/build/godot/operations/rename_checks.gd +2 -2
- package/build/godot/operations/resource_files.gd +11 -9
- package/build/godot/operations/same_values.gd +4 -4
- package/build/godot/operations/scene_connections.gd +27 -13
- package/build/godot/operations/script_check.gd +52 -49
- package/build/godot/operations/serialisation.gd +75 -51
- package/build/godot/operations/setting_reads.gd +7 -6
- package/build/godot/operations/value_shapes.gd +5 -6
- package/build/godot/tests/listed.gd +321 -268
- package/package.json +1 -1
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
extends RefCounted
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
##
|
|
5
|
-
## back what the engine did rather than trusting that it did it.
|
|
2
|
+
## What the server changes in the running game: a property written, a method called. Both take
|
|
3
|
+
## values from the wire, so both fit them to what the game declares and refuse what cannot fit, and
|
|
4
|
+
## both read back what the engine did rather than trusting that it did it.
|
|
6
5
|
|
|
7
6
|
const GdhCallErrors = preload("call_errors.gd")
|
|
8
7
|
const GdhDeclared = preload("declared_values.gd")
|
|
9
8
|
const GdhPaths = preload("runtime_paths.gd")
|
|
10
9
|
const GdhRead = preload("reading.gd")
|
|
11
10
|
const GdhValues = preload("runtime_values.gd")
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
## of a method reporting one per element of a list of thousands.
|
|
11
|
+
## The most errors a call's answer carries, which is enough to see what the method ran into and
|
|
12
|
+
## short of a method reporting one per element of a list of thousands.
|
|
15
13
|
const ERRORS_KEPT: int = 20
|
|
16
14
|
|
|
17
15
|
var _host: Node
|
|
@@ -31,7 +29,7 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
31
29
|
var value: Variant = params.get("value")
|
|
32
30
|
|
|
33
31
|
if node_path.is_empty() or property.is_empty():
|
|
34
|
-
return {"type": "error", "message": "Node path and property required"}
|
|
32
|
+
return { "type": "error", "message": "Node path and property required" }
|
|
35
33
|
|
|
36
34
|
var standing: Dictionary = GdhValues.target_at(_host.get_tree().root, node_path)
|
|
37
35
|
if standing.has("message"):
|
|
@@ -39,9 +37,9 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
39
37
|
var node: Node = standing["node"]
|
|
40
38
|
var target: Object = standing["object"]
|
|
41
39
|
|
|
42
|
-
# Through a path as well, for the reason [method GdhPaths.walk_to] gives, and read back off the
|
|
43
|
-
# holder afterwards: a set that does not take says so by answering with the old value,
|
|
44
|
-
# how a typed container refusing a write is told from one accepting it.
|
|
40
|
+
# Through a path as well, for the reason [method GdhPaths.walk_to] gives, and read back off the
|
|
41
|
+
# same holder afterwards: a set that does not take says so by answering with the old value,
|
|
42
|
+
# which is how a typed container refusing a write is told from one accepting it.
|
|
45
43
|
var reached: Dictionary = GdhPaths.walk_to(target, node_path, property)
|
|
46
44
|
if reached.has("message"):
|
|
47
45
|
return reached
|
|
@@ -57,10 +55,13 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
57
55
|
(
|
|
58
56
|
"%s:%s is a call, and a call is not a place to write: name a property"
|
|
59
57
|
% [reached["called"], named]
|
|
60
|
-
)
|
|
58
|
+
),
|
|
61
59
|
}
|
|
62
60
|
if not GdhPaths.can_read(holder, named):
|
|
63
|
-
return {
|
|
61
|
+
return {
|
|
62
|
+
"type": "error",
|
|
63
|
+
"message": GdhPaths.nothing_there(holder, named, str(reached["called"])),
|
|
64
|
+
}
|
|
64
65
|
var old_value: Variant = GdhPaths.read_under(holder, named)
|
|
65
66
|
var slot: Dictionary = GdhValues.slot_declared(holder, named)
|
|
66
67
|
var declared: int = slot["type"]
|
|
@@ -77,7 +78,7 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
77
78
|
if copied:
|
|
78
79
|
var unwritable: String = GdhPaths.unwritable_copy(chain)
|
|
79
80
|
if not unwritable.is_empty():
|
|
80
|
-
return {"type": "error", "message": unwritable}
|
|
81
|
+
return { "type": "error", "message": unwritable }
|
|
81
82
|
# The write alone, setter included, which is where a property's cost is. Listened to as a call
|
|
82
83
|
# is, since a setter refusing a value says why only in what it reports.
|
|
83
84
|
var caught: GdhCallErrors = GdhCallErrors.new()
|
|
@@ -102,10 +103,11 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
102
103
|
# And only one that asked for a change: the value the property already held, written again, left
|
|
103
104
|
# it as it was because nothing was asked of it.
|
|
104
105
|
#
|
|
105
|
-
# Said as what was seen, because two causes look the same from here: the engine refusing the
|
|
106
|
-
# and a setter that ran and left the value where it was, clamping it, say. The one this
|
|
107
|
-
# is an object slot checked only by the engine class a script extends (see
|
|
108
|
-
# [method GdhValues.slot_declared]), where an object of that class with another script is
|
|
106
|
+
# Said as what was seen, because two causes look the same from here: the engine refusing the
|
|
107
|
+
# write, and a setter that ran and left the value where it was, clamping it, say. The one this
|
|
108
|
+
# can name is an object slot checked only by the engine class a script extends (see
|
|
109
|
+
# [method GdhValues.slot_declared]), where an object of that class with another script is
|
|
110
|
+
# refused.
|
|
109
111
|
#
|
|
110
112
|
# Judged by what reads back alone, so a value of another kind than the one held, which cannot be
|
|
111
113
|
# compared with it, is still caught when the engine drops it.
|
|
@@ -113,16 +115,16 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
113
115
|
var unmoved: bool = GdhValues.comparable(now, old_value) and now == old_value
|
|
114
116
|
if unmoved and not already:
|
|
115
117
|
var why: String = (
|
|
116
|
-
"the write left it as it was, which is what the engine refusing it and a setter
|
|
117
|
-
+ " value both look like"
|
|
118
|
+
"the write left it as it was, which is what the engine refusing it and a setter "
|
|
119
|
+
+ "keeping the value both look like"
|
|
118
120
|
)
|
|
119
121
|
if declared == TYPE_OBJECT and given is Object and declared_script == null:
|
|
120
122
|
var refused_object: Object = given
|
|
121
123
|
why += (
|
|
122
124
|
(
|
|
123
|
-
". %s is declared as %s, which is also how the engine names a script class
|
|
124
|
-
+ " class_name; if it is one, the object given has the right class and
|
|
125
|
-
+ " it is %s"
|
|
125
|
+
". %s is declared as %s, which is also how the engine names a script class "
|
|
126
|
+
+ "with no class_name; if it is one, the object given has the right class and "
|
|
127
|
+
+ "another script: it is %s"
|
|
126
128
|
)
|
|
127
129
|
% [named, str(slot["class"]), GdhValues.class_of(refused_object)]
|
|
128
130
|
)
|
|
@@ -139,7 +141,7 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
139
141
|
if not caught.raised.is_empty():
|
|
140
142
|
var reported: PackedStringArray = PackedStringArray(caught.raised.slice(0, ERRORS_KEPT))
|
|
141
143
|
refused += " While it was written the game reported: %s" % "; ".join(reported)
|
|
142
|
-
return {"type": "error", "message": refused}
|
|
144
|
+
return { "type": "error", "message": refused }
|
|
143
145
|
|
|
144
146
|
var answer: Dictionary = {
|
|
145
147
|
"type": "property_set",
|
|
@@ -147,14 +149,15 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
147
149
|
"property": property,
|
|
148
150
|
"old_value": _values.serialize(old_value),
|
|
149
151
|
"new_value": _values.serialize(now),
|
|
150
|
-
"elapsed_usec": elapsed
|
|
152
|
+
"elapsed_usec": elapsed,
|
|
151
153
|
}
|
|
152
154
|
if already and unmoved:
|
|
153
155
|
answer["unchanged"] = true
|
|
154
156
|
_keep_reported(answer, "errors", caught.raised)
|
|
155
157
|
_keep_reported(answer, "warnings", caught.warned)
|
|
156
158
|
# The engine stores a number past an export range, or one no enum value has, as given; only the
|
|
157
|
-
# inspector holds a property to them, so the game now holds a value its own script never
|
|
159
|
+
# inspector holds a property to them, so the game now holds a value its own script never
|
|
160
|
+
# expected.
|
|
158
161
|
if holder is Object:
|
|
159
162
|
var owner: Object = holder
|
|
160
163
|
var shown: String = JSON.stringify(_values.serialize(now), "", false)
|
|
@@ -166,9 +169,9 @@ func set_property(params: Dictionary) -> Dictionary:
|
|
|
166
169
|
|
|
167
170
|
|
|
168
171
|
## What [param sent] becomes as argument [param index] of the method [param named] on the holder
|
|
169
|
-
## [param reached] ends at, as [method GdhPaths.walk_to] answered it, as `{"value": ...}`, or the
|
|
170
|
-
## saying why it cannot become one: a number the parameter would have to cut, a value that
|
|
171
|
-
## converted, or a list or map that cannot be built as the typed one the parameter takes.
|
|
172
|
+
## [param reached] ends at, as [method GdhPaths.walk_to] answered it, as `{"value": ...}`, or the
|
|
173
|
+
## refusal saying why it cannot become one: a number the parameter would have to cut, a value that
|
|
174
|
+
## cannot be converted, or a list or map that cannot be built as the typed one the parameter takes.
|
|
172
175
|
func _argument_for(
|
|
173
176
|
sent: Variant, index: int, reached: Dictionary, named: String, node: Node, node_path: String
|
|
174
177
|
) -> Dictionary:
|
|
@@ -185,14 +188,17 @@ func _argument_for(
|
|
|
185
188
|
"message":
|
|
186
189
|
GdhDeclared.enum_argument_refusal(
|
|
187
190
|
"%s.%s" % [called, named], index, str(choices["enum"]), str(sent), values
|
|
188
|
-
)
|
|
191
|
+
),
|
|
189
192
|
}
|
|
190
|
-
return {"value": chosen}
|
|
193
|
+
return { "value": chosen }
|
|
191
194
|
# A packed list's elements are fitted one by one, and one that cannot become what the list holds
|
|
192
|
-
# is named: converted whole, a word or a fraction among them became 0 or was cut, and the call
|
|
195
|
+
# is named: converted whole, a word or a fraction among them became 0 or was cut, and the call
|
|
196
|
+
# ran.
|
|
193
197
|
var packed: Variant = GdhValues.packed_template(wants)
|
|
194
198
|
if packed != null and sent is Array:
|
|
195
|
-
var elements: Dictionary = _values.typed_like(
|
|
199
|
+
var elements: Dictionary = _values.typed_like(
|
|
200
|
+
sent, packed, _element_object.bind(node, node_path)
|
|
201
|
+
)
|
|
196
202
|
if elements.has("message"):
|
|
197
203
|
return {
|
|
198
204
|
"type": "error",
|
|
@@ -200,29 +206,32 @@ func _argument_for(
|
|
|
200
206
|
(
|
|
201
207
|
"%s.%s takes %s as argument %d: %s"
|
|
202
208
|
% [called, named, type_string(wants), index + 1, elements["message"]]
|
|
203
|
-
)
|
|
209
|
+
),
|
|
204
210
|
}
|
|
205
211
|
if GdhValues.cuts(sent, wants):
|
|
206
212
|
return {
|
|
207
213
|
"type": "error",
|
|
208
214
|
"message":
|
|
209
215
|
(
|
|
210
|
-
|
|
216
|
+
(
|
|
217
|
+
"%s.%s takes %s as argument %d and was given %s, which %s cannot hold without "
|
|
218
|
+
+ "changing it"
|
|
219
|
+
)
|
|
211
220
|
% [
|
|
212
221
|
called,
|
|
213
222
|
named,
|
|
214
223
|
type_string(wants),
|
|
215
224
|
index + 1,
|
|
216
225
|
JSON.stringify(sent),
|
|
217
|
-
GdhValues.cut_by(wants)
|
|
226
|
+
GdhValues.cut_by(wants),
|
|
218
227
|
]
|
|
219
|
-
)
|
|
228
|
+
),
|
|
220
229
|
}
|
|
221
230
|
var rounded: String = GdhValues.inexact(sent, wants)
|
|
222
231
|
if not rounded.is_empty():
|
|
223
232
|
return {
|
|
224
233
|
"type": "error",
|
|
225
|
-
"message": "%s.%s takes int as argument %d: %s." % [called, named, index + 1, rounded]
|
|
234
|
+
"message": "%s.%s takes int as argument %d: %s." % [called, named, index + 1, rounded],
|
|
226
235
|
}
|
|
227
236
|
var given: Variant = _values.fitted(sent, wants)
|
|
228
237
|
if not GdhValues.acceptable(given, wants):
|
|
@@ -237,16 +246,18 @@ func _argument_for(
|
|
|
237
246
|
type_string(wants),
|
|
238
247
|
index + 1,
|
|
239
248
|
type_string(typeof(given)),
|
|
240
|
-
GdhValues.remedy(sent, wants)
|
|
249
|
+
GdhValues.remedy(sent, wants),
|
|
241
250
|
]
|
|
242
|
-
)
|
|
251
|
+
),
|
|
243
252
|
}
|
|
244
253
|
# A typed list or map is built as one, since a plain one handed to such a parameter raises
|
|
245
254
|
# inside the game, which is what every check here exists to stop.
|
|
246
255
|
var container: Variant = _values.parameter_container(holder, named, index)
|
|
247
256
|
if container == null:
|
|
248
|
-
return {"value": given}
|
|
249
|
-
var typed: Dictionary = _values.typed_like(
|
|
257
|
+
return { "value": given }
|
|
258
|
+
var typed: Dictionary = _values.typed_like(
|
|
259
|
+
given, container, _element_object.bind(node, node_path)
|
|
260
|
+
)
|
|
250
261
|
if typed.has("message"):
|
|
251
262
|
return {
|
|
252
263
|
"type": "error",
|
|
@@ -254,14 +265,14 @@ func _argument_for(
|
|
|
254
265
|
(
|
|
255
266
|
"%s.%s takes a typed %s as argument %d: %s"
|
|
256
267
|
% [called, named, _sort_of(container), index + 1, typed["message"]]
|
|
257
|
-
)
|
|
268
|
+
),
|
|
258
269
|
}
|
|
259
|
-
return {"value": typed["value"]}
|
|
270
|
+
return { "value": typed["value"] }
|
|
260
271
|
|
|
261
272
|
|
|
262
273
|
## What [param value] becomes written into the slot [param reached] ends on, as
|
|
263
|
-
## [method GdhPaths.walk_to] answered it, as `{"value": ...}`, or the refusal saying why it cannot
|
|
264
|
-
## one.
|
|
274
|
+
## [method GdhPaths.walk_to] answered it, as `{"value": ...}`, or the refusal saying why it cannot
|
|
275
|
+
## become one.
|
|
265
276
|
##
|
|
266
277
|
## The same rule the call path holds: a value that cannot become what the property holds is
|
|
267
278
|
## refused rather than written. Writing it means the engine picks something, and what it picks
|
|
@@ -276,7 +287,12 @@ func _argument_for(
|
|
|
276
287
|
## the number, not its text. The text null empties it when it holds an object or nothing, as a wait
|
|
277
288
|
## reads it on the same slot.
|
|
278
289
|
func _value_for(
|
|
279
|
-
value: Variant,
|
|
290
|
+
value: Variant,
|
|
291
|
+
slot: Dictionary,
|
|
292
|
+
old_value: Variant,
|
|
293
|
+
reached: Dictionary,
|
|
294
|
+
node: Node,
|
|
295
|
+
node_path: String
|
|
280
296
|
) -> Dictionary:
|
|
281
297
|
var named: String = reached["name"]
|
|
282
298
|
var called: String = reached["called"]
|
|
@@ -284,27 +300,33 @@ func _value_for(
|
|
|
284
300
|
var declared_script: Script = slot["script"]
|
|
285
301
|
var wanted: int = declared if declared != TYPE_NIL else typeof(old_value)
|
|
286
302
|
var declaration: Dictionary = slot["declared"]
|
|
287
|
-
var enum_hint: bool =
|
|
303
|
+
var enum_hint: bool = (
|
|
304
|
+
GdhRead.as_int(declaration.get("hint", PROPERTY_HINT_NONE)) == PROPERTY_HINT_ENUM
|
|
305
|
+
)
|
|
288
306
|
if declared == TYPE_INT and enum_hint and value is String and reached["holder"] is Object:
|
|
289
307
|
var owner: Object = reached["holder"]
|
|
290
308
|
var by_name: Array = GdhDeclared.enum_by_name(owner, declaration, str(value), called)
|
|
291
309
|
if by_name[0]:
|
|
292
|
-
return {"value": by_name[1]}
|
|
310
|
+
return { "value": by_name[1] }
|
|
293
311
|
if not str(by_name[1]).is_empty():
|
|
294
|
-
return {"type": "error", "message": by_name[1]}
|
|
312
|
+
return { "type": "error", "message": by_name[1] }
|
|
295
313
|
var packed: Variant = GdhValues.packed_template(wanted)
|
|
296
314
|
if packed != null and value is Array:
|
|
297
|
-
var elements: Dictionary = _values.typed_like(
|
|
315
|
+
var elements: Dictionary = _values.typed_like(
|
|
316
|
+
value, packed, _element_object.bind(node, node_path)
|
|
317
|
+
)
|
|
298
318
|
if elements.has("message"):
|
|
299
319
|
return {
|
|
300
320
|
"type": "error",
|
|
301
|
-
"message":
|
|
321
|
+
"message":
|
|
322
|
+
"%s.%s holds %s: %s" % [called, named, type_string(wanted), elements["message"]],
|
|
302
323
|
}
|
|
303
324
|
var holds_objects: bool = (
|
|
304
|
-
declared == TYPE_OBJECT
|
|
325
|
+
declared == TYPE_OBJECT
|
|
326
|
+
or (declared == TYPE_NIL and (old_value == null or old_value is Object))
|
|
305
327
|
)
|
|
306
328
|
if holds_objects and names_no_object(value):
|
|
307
|
-
return {"value": null}
|
|
329
|
+
return { "value": null }
|
|
308
330
|
if wanted == TYPE_OBJECT and (value is String or value is Dictionary):
|
|
309
331
|
var named_object: Dictionary = _object_named(
|
|
310
332
|
node, node_path, value, str(slot["class"]), declared_script
|
|
@@ -312,12 +334,12 @@ func _value_for(
|
|
|
312
334
|
if named_object.has("message"):
|
|
313
335
|
return {
|
|
314
336
|
"type": "error",
|
|
315
|
-
"message": "%s.%s holds an object: %s" % [called, named, named_object["message"]]
|
|
337
|
+
"message": "%s.%s holds an object: %s" % [called, named, named_object["message"]],
|
|
316
338
|
}
|
|
317
|
-
return {"value": named_object["object"]}
|
|
339
|
+
return { "value": named_object["object"] }
|
|
318
340
|
var rounded: String = GdhValues.inexact(value, wanted)
|
|
319
341
|
if not rounded.is_empty():
|
|
320
|
-
return {"type": "error", "message": "%s.%s holds int: %s." % [called, named, rounded]}
|
|
342
|
+
return { "type": "error", "message": "%s.%s holds int: %s." % [called, named, rounded] }
|
|
321
343
|
var as_sent: Variant = _values.fitted(value, TYPE_NIL)
|
|
322
344
|
var cut: bool = GdhValues.cuts(value, wanted)
|
|
323
345
|
var given: Variant = as_sent
|
|
@@ -327,8 +349,14 @@ func _value_for(
|
|
|
327
349
|
"message":
|
|
328
350
|
(
|
|
329
351
|
"%s.%s holds %s and the value given is %s, which %s cannot hold without changing it"
|
|
330
|
-
% [
|
|
331
|
-
|
|
352
|
+
% [
|
|
353
|
+
called,
|
|
354
|
+
named,
|
|
355
|
+
type_string(wanted),
|
|
356
|
+
JSON.stringify(value),
|
|
357
|
+
GdhValues.cut_by(wanted),
|
|
358
|
+
]
|
|
359
|
+
),
|
|
332
360
|
}
|
|
333
361
|
if declared != TYPE_NIL or (not cut and GdhValues.acceptable(as_sent, wanted)):
|
|
334
362
|
given = _values.fitted(value, wanted)
|
|
@@ -343,17 +371,20 @@ func _value_for(
|
|
|
343
371
|
named,
|
|
344
372
|
type_string(wanted),
|
|
345
373
|
type_string(typeof(given)),
|
|
346
|
-
GdhValues.remedy(value, wanted)
|
|
374
|
+
GdhValues.remedy(value, wanted),
|
|
347
375
|
]
|
|
348
|
-
)
|
|
376
|
+
),
|
|
349
377
|
}
|
|
350
|
-
var typed: Dictionary = _values.typed_like(
|
|
378
|
+
var typed: Dictionary = _values.typed_like(
|
|
379
|
+
given, old_value, _element_object.bind(node, node_path)
|
|
380
|
+
)
|
|
351
381
|
if typed.has("message"):
|
|
352
382
|
return {
|
|
353
383
|
"type": "error",
|
|
354
|
-
"message":
|
|
384
|
+
"message":
|
|
385
|
+
"%s.%s is a typed %s: %s" % [called, named, _sort_of(old_value), typed["message"]],
|
|
355
386
|
}
|
|
356
|
-
return {"value": typed["value"]}
|
|
387
|
+
return { "value": typed["value"] }
|
|
357
388
|
|
|
358
389
|
|
|
359
390
|
## Whether [param given] is the value [param held] already is, at the precision the property keeps.
|
|
@@ -376,9 +407,9 @@ static func held_already(given: Variant, held: Variant) -> bool:
|
|
|
376
407
|
return PackedFloat32Array([given])[0] == PackedFloat32Array([held])[0]
|
|
377
408
|
|
|
378
409
|
|
|
379
|
-
## What to do instead of the call [param method] makes on [param sort], the list or map
|
|
380
|
-
## reached] ends on, which a path does not make. A method of the list itself is the likelier
|
|
381
|
-
## than one of what it holds when the list has it: told to call append() on an element, a caller
|
|
410
|
+
## What to do instead of the call [param method] makes on [param sort], the list or map
|
|
411
|
+
## [param reached] ends on, which a path does not make. A method of the list itself is the likelier
|
|
412
|
+
## aim than one of what it holds when the list has it: told to call append() on an element, a caller
|
|
382
413
|
## adding to a list has nowhere to go.
|
|
383
414
|
static func _instead_of_a_call(reached: Dictionary, method: String, sort: String) -> String:
|
|
384
415
|
var own: String = GdhPaths.method_of(str(reached["name"]))
|
|
@@ -396,23 +427,25 @@ static func _instead_of_a_call(reached: Dictionary, method: String, sort: String
|
|
|
396
427
|
if through_a_call:
|
|
397
428
|
return (
|
|
398
429
|
(
|
|
399
|
-
"%s() changes %s: to change it, call a method of the game that changes it,
|
|
400
|
-
+ " is returned by a call, and runtime_invoke set does not write
|
|
430
|
+
"%s() changes %s: to change it, call a method of the game that changes it, "
|
|
431
|
+
+ "since %s is returned by a call, and runtime_invoke set does not write "
|
|
432
|
+
+ "into what a call returns"
|
|
401
433
|
)
|
|
402
434
|
% [own, the, reached["called"]]
|
|
403
435
|
)
|
|
404
436
|
return (
|
|
405
437
|
(
|
|
406
|
-
"%s() changes %s: to change it, give %s its new value whole with
|
|
407
|
-
+ " property %s, or call a method of the game that changes
|
|
438
|
+
"%s() changes %s: to change it, give %s its new value whole with "
|
|
439
|
+
+ "runtime_invoke set, property %s, or call a method of the game that changes "
|
|
440
|
+
+ "it"
|
|
408
441
|
)
|
|
409
442
|
% [own, the, reached["called"], holding]
|
|
410
443
|
)
|
|
411
444
|
"reads":
|
|
412
445
|
return (
|
|
413
446
|
(
|
|
414
|
-
"To look in %s with %s(), read %s whole with runtime_inspect property,
|
|
415
|
-
+ " look in what comes back"
|
|
447
|
+
"To look in %s with %s(), read %s whole with runtime_inspect property, "
|
|
448
|
+
+ "property %s, and look in what comes back"
|
|
416
449
|
)
|
|
417
450
|
% [the, own, reached["called"], holding]
|
|
418
451
|
)
|
|
@@ -428,7 +461,7 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
428
461
|
var args: Array = params.get("args", [])
|
|
429
462
|
|
|
430
463
|
if node_path.is_empty() or method.is_empty():
|
|
431
|
-
return {"type": "error", "message": "Node path and method required"}
|
|
464
|
+
return { "type": "error", "message": "Node path and method required" }
|
|
432
465
|
|
|
433
466
|
var root: Node = _host.get_tree().root
|
|
434
467
|
var standing: Dictionary = GdhValues.class_at(root, node_path)
|
|
@@ -441,8 +474,8 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
441
474
|
var close: PackedStringArray = GdhRead.nearest(node_path, PackedStringArray(classes))
|
|
442
475
|
standing["message"] = (
|
|
443
476
|
(
|
|
444
|
-
"%s. No global class is called %s either%s; a static function is called with
|
|
445
|
-
+ " class's name or its script's res:// path as the path."
|
|
477
|
+
"%s. No global class is called %s either%s; a static function is called with "
|
|
478
|
+
+ "its class's name or its script's res:// path as the path."
|
|
446
479
|
)
|
|
447
480
|
% [
|
|
448
481
|
str(standing["message"]).trim_suffix("."),
|
|
@@ -462,8 +495,8 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
462
495
|
var node: Node = standing["node"]
|
|
463
496
|
var target: Object = standing["object"]
|
|
464
497
|
|
|
465
|
-
# Through a path as well, for the reason [method GdhPaths.walk_to] gives. What a game does hangs
|
|
466
|
-
# nodes as much as its state does, so reading `_game:run:day` while being unable to call
|
|
498
|
+
# Through a path as well, for the reason [method GdhPaths.walk_to] gives. What a game does hangs
|
|
499
|
+
# off its nodes as much as its state does, so reading `_game:run:day` while being unable to call
|
|
467
500
|
# `_game:run:advance` answers half of what a node holds and refuses the other half.
|
|
468
501
|
var reached: Dictionary = GdhPaths.walk_to(target, node_path, method)
|
|
469
502
|
if reached.has("message"):
|
|
@@ -471,7 +504,8 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
471
504
|
|
|
472
505
|
# A list or a map answers the calls a path makes on one, and nothing else: said in those terms
|
|
473
506
|
# rather than as "has no method", which reads as a misspelling of a method that was never going
|
|
474
|
-
# to be there, and with the element spelled out, since a method on what it holds is the usual
|
|
507
|
+
# to be there, and with the element spelled out, since a method on what it holds is the usual
|
|
508
|
+
# aim.
|
|
475
509
|
if not reached["holder"] is Object:
|
|
476
510
|
var sort: String = "a list"
|
|
477
511
|
if reached["holder"] is Dictionary:
|
|
@@ -481,8 +515,8 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
481
515
|
var spelled: String = str(reached["name"])
|
|
482
516
|
if GdhPaths.method_of(spelled).is_empty():
|
|
483
517
|
spelled += "()"
|
|
484
|
-
# A vector or a transform has no element to call a method on, so a call it does not answer
|
|
485
|
-
# refused without the advice about elements below.
|
|
518
|
+
# A vector or a transform has no element to call a method on, so a call it does not answer
|
|
519
|
+
# is refused without the advice about elements below.
|
|
486
520
|
var answers: bool = GdhPaths.can_read(reached["holder"], spelled)
|
|
487
521
|
var called_on: Variant = reached["holder"]
|
|
488
522
|
if (
|
|
@@ -496,7 +530,7 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
496
530
|
"%s:%s takes no arguments" % [reached["called"], spelled]
|
|
497
531
|
if answers
|
|
498
532
|
else GdhPaths.nothing_there(reached["holder"], spelled, str(reached["called"]))
|
|
499
|
-
)
|
|
533
|
+
),
|
|
500
534
|
}
|
|
501
535
|
if args.is_empty() and answers:
|
|
502
536
|
var read_from: int = Time.get_ticks_usec()
|
|
@@ -518,7 +552,9 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
518
552
|
if GdhPaths.can_read(reached["holder"], spelled)
|
|
519
553
|
else GdhPaths.nothing_there(reached["holder"], spelled, str(reached["called"]))
|
|
520
554
|
)
|
|
521
|
-
return {
|
|
555
|
+
return {
|
|
556
|
+
"type": "error", "message": "%s. %s" % [why, _instead_of_a_call(reached, method, sort)],
|
|
557
|
+
}
|
|
522
558
|
var holder: Object = reached["holder"]
|
|
523
559
|
var named: String = reached["name"]
|
|
524
560
|
# The method a call ends on is the one being called whether or not it carries the brackets a
|
|
@@ -532,7 +568,7 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
532
568
|
if not_called.is_empty():
|
|
533
569
|
not_called = _not_a_method_to_call(holder, named, str(reached["called"]))
|
|
534
570
|
if not not_called.is_empty():
|
|
535
|
-
return {"type": "error", "message": not_called}
|
|
571
|
+
return { "type": "error", "message": not_called }
|
|
536
572
|
if not GdhPaths.method_of(named).is_empty():
|
|
537
573
|
named = GdhPaths.method_of(named)
|
|
538
574
|
|
|
@@ -542,10 +578,10 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
542
578
|
# nowhere near the argument. A wrong argument costs a refusal, never the session's game.
|
|
543
579
|
var count: String = _argument_count_refused(holder, named, args.size())
|
|
544
580
|
if not count.is_empty():
|
|
545
|
-
return {"type": "error", "message": "%s.%s %s" % [reached["called"], named, count]}
|
|
581
|
+
return { "type": "error", "message": "%s.%s %s" % [reached["called"], named, count] }
|
|
546
582
|
var deserialized_args: Array = []
|
|
547
|
-
# The object arguments checked only against the engine class, by position from 1, for the
|
|
548
|
-
# the engine may still make: see [method GdhValues.slot_declared].
|
|
583
|
+
# The object arguments checked only against the engine class, by position from 1, for the
|
|
584
|
+
# refusal the engine may still make: see [method GdhValues.slot_declared].
|
|
549
585
|
var by_engine_class: Dictionary = {}
|
|
550
586
|
# The enum arguments given a number none of their values has, said beside the answer: the engine
|
|
551
587
|
# passes any number on, and a write of the same number to a property already said so.
|
|
@@ -559,14 +595,19 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
559
595
|
return {
|
|
560
596
|
"type": "error",
|
|
561
597
|
"message":
|
|
562
|
-
|
|
598
|
+
(
|
|
599
|
+
"%s.%s argument %d: %s"
|
|
600
|
+
% [reached["called"], named, index + 1, named_object["message"]]
|
|
601
|
+
),
|
|
563
602
|
}
|
|
564
603
|
var resolved: Object = named_object["object"]
|
|
565
604
|
if resolved != null and ClassDB.class_exists(declared):
|
|
566
605
|
by_engine_class[index + 1] = [declared, GdhValues.class_of(resolved)]
|
|
567
606
|
deserialized_args.append(named_object["object"])
|
|
568
607
|
continue
|
|
569
|
-
var argument: Dictionary = _argument_for(
|
|
608
|
+
var argument: Dictionary = _argument_for(
|
|
609
|
+
args[index], index, reached, named, node, node_path
|
|
610
|
+
)
|
|
570
611
|
if argument.has("message"):
|
|
571
612
|
return argument
|
|
572
613
|
deserialized_args.append(argument["value"])
|
|
@@ -601,27 +642,27 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
601
642
|
"%s.%s did not run: the engine refused the call: %s"
|
|
602
643
|
% [reached["called"], named, caught.refused.trim_suffix(".")]
|
|
603
644
|
)
|
|
604
|
-
var position: RegExMatch =
|
|
605
|
-
caught.refused
|
|
645
|
+
var position: RegExMatch = (
|
|
646
|
+
RegEx.create_from_string(r"Cannot convert argument (\d+)").search(caught.refused)
|
|
606
647
|
)
|
|
607
648
|
if position != null and by_engine_class.has(int(position.get_string(1))):
|
|
608
649
|
var checked: Array = by_engine_class[int(position.get_string(1))]
|
|
609
650
|
message += (
|
|
610
651
|
(
|
|
611
|
-
". The parameter is declared as %s, which is also how the engine names a
|
|
612
|
-
+ " with no class_name; if it is one, the object given has the
|
|
613
|
-
+ " script: it is %s"
|
|
652
|
+
". The parameter is declared as %s, which is also how the engine names a "
|
|
653
|
+
+ "script class with no class_name; if it is one, the object given has the "
|
|
654
|
+
+ "right class and another script: it is %s"
|
|
614
655
|
)
|
|
615
656
|
% checked
|
|
616
657
|
)
|
|
617
|
-
return {"type": "error", "message": message + "."}
|
|
658
|
+
return { "type": "error", "message": message + "." }
|
|
618
659
|
|
|
619
660
|
var answer: Dictionary = {
|
|
620
661
|
"type": "method_result",
|
|
621
662
|
"path": node_path,
|
|
622
663
|
"method": method,
|
|
623
664
|
"result": _values.serialize(result),
|
|
624
|
-
"elapsed_usec": elapsed
|
|
665
|
+
"elapsed_usec": elapsed,
|
|
625
666
|
}
|
|
626
667
|
if awaited:
|
|
627
668
|
answer["awaited"] = true
|
|
@@ -629,7 +670,8 @@ func call_method(params: Dictionary) -> Dictionary:
|
|
|
629
670
|
answer["outside_declared"] = " ".join(outside)
|
|
630
671
|
_keep_reported(answer, "errors", caught.raised)
|
|
631
672
|
_keep_reported(answer, "warnings", caught.warned)
|
|
632
|
-
# Main.explode, ended at a null it called into, answered result 0 as if it had counted
|
|
673
|
+
# Main.explode, ended at a null it called into, answered result 0 as if it had counted
|
|
674
|
+
# something.
|
|
633
675
|
if caught.ended_at.has(named):
|
|
634
676
|
answer["ended_by_error_at"] = caught.ended_at[named]
|
|
635
677
|
var asked: Variant = params.get("properties")
|
|
@@ -648,9 +690,9 @@ static func _keep_reported(answer: Dictionary, field: String, reported: Array[St
|
|
|
648
690
|
answer[field + "_not_shown"] = reported.size() - ERRORS_KEPT
|
|
649
691
|
|
|
650
692
|
|
|
651
|
-
## Why [param named], the last step of a call's method, names no method of [param holder] to call,
|
|
652
|
-
## "" when it does. Brackets on it holding arguments are refused rather than read: the arguments
|
|
653
|
-
## taken from args alone, so a call is never made with half of them in one place and half in the
|
|
693
|
+
## Why [param named], the last step of a call's method, names no method of [param holder] to call,
|
|
694
|
+
## or "" when it does. Brackets on it holding arguments are refused rather than read: the arguments
|
|
695
|
+
## are taken from args alone, so a call is never made with half of them in one place and half in the
|
|
654
696
|
## other, or with the bracketed ones quietly dropped.
|
|
655
697
|
static func _not_a_method_to_call(holder: Object, named: String, called: String) -> String:
|
|
656
698
|
var method: String = named
|
|
@@ -659,7 +701,10 @@ static func _not_a_method_to_call(holder: Object, named: String, called: String)
|
|
|
659
701
|
var in_brackets: Array = bracketed.get("args", [])
|
|
660
702
|
if bracketed.has("message") or not in_brackets.is_empty():
|
|
661
703
|
return (
|
|
662
|
-
|
|
704
|
+
(
|
|
705
|
+
"%s:%s: the method a call ends on takes its arguments under args, not in its "
|
|
706
|
+
+ "brackets"
|
|
707
|
+
)
|
|
663
708
|
% [called, named]
|
|
664
709
|
)
|
|
665
710
|
method = GdhPaths.method_of(named)
|
|
@@ -675,12 +720,15 @@ static func _instance_method(holder: Object, method: String, called: String) ->
|
|
|
675
720
|
return ""
|
|
676
721
|
var script: Script = holder
|
|
677
722
|
for entry: Dictionary in script.get_script_method_list():
|
|
678
|
-
if
|
|
723
|
+
if (
|
|
724
|
+
str(entry.get("name", "")) != method
|
|
725
|
+
or GdhRead.as_int(entry.get("flags", 0)) & METHOD_FLAG_STATIC
|
|
726
|
+
):
|
|
679
727
|
continue
|
|
680
728
|
return (
|
|
681
729
|
(
|
|
682
|
-
"%s.%s is not static, so it runs on an instance of the class: call it on a node
|
|
683
|
-
+ " or on an object a path from one reaches"
|
|
730
|
+
"%s.%s is not static, so it runs on an instance of the class: call it on a node "
|
|
731
|
+
+ "carrying %s, or on an object a path from one reaches"
|
|
684
732
|
)
|
|
685
733
|
% [called, method, script.resource_path]
|
|
686
734
|
)
|
|
@@ -726,21 +774,25 @@ func _read_off_result(result: Variant, asked: Variant) -> Dictionary:
|
|
|
726
774
|
read_by_key[str(key)] = got
|
|
727
775
|
else:
|
|
728
776
|
entries.append([shown, got])
|
|
729
|
-
var shaped: Variant = read_by_key if texts else {
|
|
777
|
+
var shaped: Variant = read_by_key if texts else {
|
|
778
|
+
"_type": "Dictionary",
|
|
779
|
+
"entries": entries,
|
|
780
|
+
}
|
|
730
781
|
return _read_off_many(shaped, map.values(), "Dictionary", missing)
|
|
731
782
|
if result is Object and not is_instance_valid(result):
|
|
732
783
|
return {
|
|
733
|
-
"properties_note":
|
|
784
|
+
"properties_note":
|
|
785
|
+
"the call answered an object that has since been freed, so nothing was read",
|
|
734
786
|
}
|
|
735
787
|
if not result is Object:
|
|
736
788
|
return {
|
|
737
789
|
"properties_note":
|
|
738
|
-
"the call answered %s, which has no properties to read" % type_string(typeof(result))
|
|
790
|
+
"the call answered %s, which has no properties to read" % type_string(typeof(result)),
|
|
739
791
|
}
|
|
740
792
|
var object: Object = result
|
|
741
793
|
var one: Dictionary = _read_off_object(object, asked)
|
|
742
794
|
missing = one["missing"]
|
|
743
|
-
var answered: Dictionary = {"result_properties": one["read"]}
|
|
795
|
+
var answered: Dictionary = { "result_properties": one["read"] }
|
|
744
796
|
if not missing.is_empty():
|
|
745
797
|
answered["result_properties_missing"] = missing
|
|
746
798
|
return answered
|
|
@@ -748,7 +800,9 @@ func _read_off_result(result: Variant, asked: Variant) -> Dictionary:
|
|
|
748
800
|
|
|
749
801
|
## What was read off one element of a list or a dictionary a call answered with, or null for one
|
|
750
802
|
## that is no object; why a name was not there goes into [param missing], led by [param named].
|
|
751
|
-
func _read_off_element(
|
|
803
|
+
func _read_off_element(
|
|
804
|
+
element: Variant, named: String, asked: Variant, missing: Array[String]
|
|
805
|
+
) -> Variant:
|
|
752
806
|
if not element is Object:
|
|
753
807
|
return null
|
|
754
808
|
if not is_instance_valid(element):
|
|
@@ -770,9 +824,9 @@ static func _read_off_many(
|
|
|
770
824
|
if not elements.any(func(element: Variant) -> bool: return element is Object):
|
|
771
825
|
return {
|
|
772
826
|
"properties_note":
|
|
773
|
-
"the call answered %s with no object in it, so there are no properties to read" % shape
|
|
827
|
+
"the call answered %s with no object in it, so there are no properties to read" % shape,
|
|
774
828
|
}
|
|
775
|
-
var answered: Dictionary = {"result_properties": read}
|
|
829
|
+
var answered: Dictionary = { "result_properties": read }
|
|
776
830
|
if not missing.is_empty():
|
|
777
831
|
answered["result_properties_missing"] = missing
|
|
778
832
|
return answered
|
|
@@ -795,7 +849,7 @@ func _read_off_object(object: Object, asked: Variant) -> Dictionary:
|
|
|
795
849
|
missing.append(str(walked["message"]))
|
|
796
850
|
else:
|
|
797
851
|
read[path] = _values.serialize(walked["value"])
|
|
798
|
-
return {"read": read, "missing": missing}
|
|
852
|
+
return { "read": read, "missing": missing }
|
|
799
853
|
|
|
800
854
|
|
|
801
855
|
## The variables the script attached to [param object] declares, in the order it declares them.
|
|
@@ -817,13 +871,16 @@ static func _walk_from(object: Object, path: String) -> Dictionary:
|
|
|
817
871
|
if not GdhPaths.can_hold(holder):
|
|
818
872
|
return {
|
|
819
873
|
"message":
|
|
820
|
-
|
|
874
|
+
(
|
|
875
|
+
"%s holds %s, which has nothing to read %s off"
|
|
876
|
+
% [called, type_string(typeof(holder)), named]
|
|
877
|
+
),
|
|
821
878
|
}
|
|
822
879
|
if not GdhPaths.can_read(holder, named):
|
|
823
|
-
return {"message": GdhPaths.nothing_there(holder, named, called)}
|
|
880
|
+
return { "message": GdhPaths.nothing_there(holder, named, called) }
|
|
824
881
|
holder = GdhPaths.read_under(holder, named)
|
|
825
882
|
called = "%s:%s" % [called, named]
|
|
826
|
-
return {"value": holder}
|
|
883
|
+
return { "value": holder }
|
|
827
884
|
|
|
828
885
|
|
|
829
886
|
## Why [param given] arguments are the wrong number for [param method], or "" when they are not.
|
|
@@ -832,8 +889,9 @@ static func _walk_from(object: Object, path: String) -> Dictionary:
|
|
|
832
889
|
## null, and the method list says how many a method takes: its parameters less those with defaults,
|
|
833
890
|
## up to all of them, or any number past that for one taking varargs.
|
|
834
891
|
static func _argument_count_refused(holder: Object, method: String, given: int) -> String:
|
|
835
|
-
# A node's method list runs to hundreds of entries, and walking it costs a couple of
|
|
836
|
-
# of the game's frame; a call giving exactly the arguments the method declares
|
|
892
|
+
# A node's method list runs to hundreds of entries, and walking it costs a couple of
|
|
893
|
+
# milliseconds of the game's frame; a call giving exactly the arguments the method declares
|
|
894
|
+
# needs no walk.
|
|
837
895
|
if given == holder.get_method_argument_count(method):
|
|
838
896
|
return ""
|
|
839
897
|
for entry: Dictionary in GdhValues.methods_of(holder):
|
|
@@ -856,8 +914,8 @@ static func _argument_count_refused(holder: Object, method: String, given: int)
|
|
|
856
914
|
return ""
|
|
857
915
|
|
|
858
916
|
|
|
859
|
-
## [method _object_named] with the path first, which is the order [method GdhValues.typed_like]
|
|
860
|
-
## an element resolver in.
|
|
917
|
+
## [method _object_named] with the path first, which is the order [method GdhValues.typed_like]
|
|
918
|
+
## calls an element resolver in.
|
|
861
919
|
func _element_object(
|
|
862
920
|
given: Variant, declared: String, script: Script, node: Node, node_path: String
|
|
863
921
|
) -> Dictionary:
|
|
@@ -886,7 +944,7 @@ func _object_named(
|
|
|
886
944
|
node: Node, node_path: String, given: Variant, declared: String, script: Script = null
|
|
887
945
|
) -> Dictionary:
|
|
888
946
|
if names_no_object(given):
|
|
889
|
-
return {"object": null}
|
|
947
|
+
return { "object": null }
|
|
890
948
|
var found: Dictionary = GdhPaths.object_at(_host.get_tree().root, node, node_path, given)
|
|
891
949
|
if found.has("message"):
|
|
892
950
|
return found
|
|
@@ -895,9 +953,13 @@ func _object_named(
|
|
|
895
953
|
var wanted: String = "an instance of %s" % GdhValues.script_named(script)
|
|
896
954
|
if not script.get_global_name().is_empty():
|
|
897
955
|
wanted = "a %s" % script.get_global_name()
|
|
898
|
-
return {
|
|
956
|
+
return {
|
|
957
|
+
"message": "%s is %s, not %s" % [str(given), GdhValues.class_of(instance), wanted],
|
|
958
|
+
}
|
|
899
959
|
if script == null and not declared.is_empty() and not GdhValues.is_a(instance, declared):
|
|
900
|
-
return {
|
|
960
|
+
return {
|
|
961
|
+
"message": "%s is %s, not a %s" % [str(given), GdhValues.class_of(instance), declared],
|
|
962
|
+
}
|
|
901
963
|
return found
|
|
902
964
|
|
|
903
965
|
|