fix: implement varargs for ESC commands. 'custom' makes use of this #592
This commit is contained in:
@@ -1,16 +1,17 @@
|
|||||||
# `custom object node func_name [params]`
|
# `custom object node func_name [params...]`
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Executes the specified Godot function. This function must be in a script
|
# Executes the specified Godot function. This function must be in a script
|
||||||
# attached to a child node of a registered `ESCitem`.
|
# attached to a child node of a registered `ESCItem`.
|
||||||
#
|
#
|
||||||
# **Parameters**
|
# **Parameters**
|
||||||
#
|
#
|
||||||
# - *object*: Global ID of the target `ESCItem`
|
# - *object*: Global ID of the target `ESCItem`
|
||||||
# - *node*: Name of the child node of the target `ESCItem`
|
# - *node*: Name of the child node of the target `ESCItem`
|
||||||
# - *func_name*: Name of the function to be called
|
# - *func_name*: Name of the function to be called
|
||||||
# - params: Any arguments to be passed to the function (array and object parameters are not supported). Multiple
|
# - params: Any arguments to be passed to the function (array and object parameters are not supported).
|
||||||
# parameters can be passed by using comma-separated values inside a string
|
# Multiple parameters can be passed by simply passing them in as additional arguments separated by
|
||||||
|
# spaces, e.g. `custom the_object the_node the_function arg1 arg2 arg3`
|
||||||
#
|
#
|
||||||
# @ESC
|
# @ESC
|
||||||
extends ESCBaseCommand
|
extends ESCBaseCommand
|
||||||
@@ -22,7 +23,9 @@ func configure() -> ESCCommandArgumentDescriptor:
|
|||||||
return ESCCommandArgumentDescriptor.new(
|
return ESCCommandArgumentDescriptor.new(
|
||||||
3,
|
3,
|
||||||
[TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_ARRAY],
|
[TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_ARRAY],
|
||||||
[null, null, null, []]
|
[null, null, null, []],
|
||||||
|
[true],
|
||||||
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ func _init(command_string):
|
|||||||
).strip_edges()
|
).strip_edges()
|
||||||
)
|
)
|
||||||
for parameter in parsed_parameters.split(" "):
|
for parameter in parsed_parameters.split(" "):
|
||||||
if parameter.begins_with('"') and parameter.ends_with('"'):
|
if len(parameter) > 1 and parameter.begins_with('"') and parameter.ends_with('"'):
|
||||||
parameters.append(
|
parameters.append(
|
||||||
parameter
|
parameter
|
||||||
)
|
)
|
||||||
elif ":" in parameter and '"' in parameter:
|
elif ":" in parameter and '"' in parameter:
|
||||||
quote_open = true
|
quote_open = true
|
||||||
parameter_values.append(parameter)
|
parameter_values.append(parameter)
|
||||||
elif parameter.begins_with('"'):
|
elif not quote_open and parameter.begins_with('"'):
|
||||||
quote_open = true
|
quote_open = true
|
||||||
parameter_values.append(parameter)
|
parameter_values.append(parameter)
|
||||||
elif parameter.ends_with('"'):
|
elif parameter.ends_with('"'):
|
||||||
|
|||||||
@@ -30,24 +30,30 @@ var defaults: Array = []
|
|||||||
# Whether to strip quotes on specific arguments
|
# Whether to strip quotes on specific arguments
|
||||||
var strip_quotes: Array = []
|
var strip_quotes: Array = []
|
||||||
|
|
||||||
|
# Whether the final argument is a series of varargs
|
||||||
|
var has_varargs: bool = false
|
||||||
|
|
||||||
|
|
||||||
# Initialize the descriptor
|
# Initialize the descriptor
|
||||||
func _init(
|
func _init(
|
||||||
p_min_args: int = 0,
|
p_min_args: int = 0,
|
||||||
p_types: Array = [],
|
p_types: Array = [],
|
||||||
p_defaults: Array = [],
|
p_defaults: Array = [],
|
||||||
p_strip_quotes: Array = [true]
|
p_strip_quotes: Array = [true],
|
||||||
|
p_has_varargs: bool = false
|
||||||
):
|
):
|
||||||
max_args = p_types.size()
|
max_args = p_types.size()
|
||||||
min_args = p_min_args
|
min_args = p_min_args
|
||||||
types = p_types
|
types = p_types
|
||||||
defaults = p_defaults
|
defaults = p_defaults
|
||||||
strip_quotes = p_strip_quotes
|
strip_quotes = p_strip_quotes
|
||||||
|
has_varargs = p_has_varargs
|
||||||
|
|
||||||
|
|
||||||
# Combine the default argument values with the given arguments
|
# Combine the default argument values with the given arguments
|
||||||
func prepare_arguments(arguments: Array) -> Array:
|
func prepare_arguments(arguments: Array) -> Array:
|
||||||
var complete_arguments = defaults
|
var complete_arguments = defaults
|
||||||
|
var varargs = []
|
||||||
|
|
||||||
for index in range(arguments.size()):
|
for index in range(arguments.size()):
|
||||||
# If we have too many arguments passed in, complete_arguments won't
|
# If we have too many arguments passed in, complete_arguments won't
|
||||||
@@ -55,22 +61,32 @@ func prepare_arguments(arguments: Array) -> Array:
|
|||||||
# to avoid duplicating validation code, just grow complete_arguments
|
# to avoid duplicating validation code, just grow complete_arguments
|
||||||
# since the arguments won't be used anyway.
|
# since the arguments won't be used anyway.
|
||||||
if index >= complete_arguments.size():
|
if index >= complete_arguments.size():
|
||||||
complete_arguments.append(arguments[index])
|
if has_varargs:
|
||||||
continue
|
varargs.append(arguments[index])
|
||||||
|
else:
|
||||||
complete_arguments[index] = escoria.utils.get_typed_value(
|
complete_arguments.append(arguments[index])
|
||||||
arguments[index],
|
elif index == complete_arguments.size() - 1 and has_varargs:
|
||||||
types[index]
|
# Varargs are a special case and need to be gathered and added at
|
||||||
)
|
# the end as an array, untyped and unchecked. They should also only
|
||||||
var strip = strip_quotes[0]
|
# appear at the very end of a command's argument list.
|
||||||
if strip_quotes.size() == complete_arguments.size():
|
varargs.append(arguments[index])
|
||||||
strip = strip_quotes[index]
|
else:
|
||||||
|
complete_arguments[index] = escoria.utils.get_typed_value(
|
||||||
if strip and typeof(complete_arguments[index]) == TYPE_STRING:
|
arguments[index],
|
||||||
complete_arguments[index] = complete_arguments[index].replace(
|
types[index]
|
||||||
'"',
|
|
||||||
''
|
|
||||||
)
|
)
|
||||||
|
var strip = strip_quotes[0]
|
||||||
|
if strip_quotes.size() == complete_arguments.size():
|
||||||
|
strip = strip_quotes[index]
|
||||||
|
|
||||||
|
if strip and typeof(complete_arguments[index]) == TYPE_STRING:
|
||||||
|
complete_arguments[index] = complete_arguments[index].replace(
|
||||||
|
'"',
|
||||||
|
''
|
||||||
|
)
|
||||||
|
|
||||||
|
if has_varargs:
|
||||||
|
complete_arguments[complete_arguments.size() - 1] = varargs
|
||||||
|
|
||||||
return complete_arguments
|
return complete_arguments
|
||||||
|
|
||||||
@@ -91,7 +107,7 @@ func validate(command: String, arguments: Array) -> bool:
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
if arguments.size() > self.max_args:
|
if arguments.size() > self.max_args and not has_varargs:
|
||||||
escoria.logger.report_errors(
|
escoria.logger.report_errors(
|
||||||
"ESCCommandArgumentDescriptor:validate()",
|
"ESCCommandArgumentDescriptor:validate()",
|
||||||
[
|
[
|
||||||
@@ -104,6 +120,11 @@ func validate(command: String, arguments: Array) -> bool:
|
|||||||
if arguments[index] == null:
|
if arguments[index] == null:
|
||||||
# No type checking for null values
|
# No type checking for null values
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if has_varargs and index == arguments.size() - 1:
|
||||||
|
# If we have varargs at the end, do not validate them.
|
||||||
|
continue
|
||||||
|
|
||||||
var correct = false
|
var correct = false
|
||||||
var types_index = index
|
var types_index = index
|
||||||
if types_index > types.size():
|
if types_index > types.size():
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ func set_scene(p_scene: Node) -> void:
|
|||||||
#
|
#
|
||||||
# - p_scene: The scene currently being initialized by set_scene.
|
# - p_scene: The scene currently being initialized by set_scene.
|
||||||
func finish_current_scene_init(p_scene: Node) -> void:
|
func finish_current_scene_init(p_scene: Node) -> void:
|
||||||
move_child(p_scene, 0)
|
if is_a_parent_of(p_scene):
|
||||||
|
move_child(p_scene, 0)
|
||||||
|
|
||||||
current_scene = p_scene
|
current_scene = p_scene
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
:setup
|
:setup
|
||||||
|
custom r3_r_exit door_enabler enable_door a b c 1 2 345
|
||||||
|
|
||||||
# If the room hasn't been visited previously, open the bridge and break the button
|
# If the room hasn't been visited previously, open the bridge and break the button
|
||||||
> [!room3_visited]
|
> [!room3_visited]
|
||||||
|
|||||||
Reference in New Issue
Block a user