WIP: added max args checking; working on fixing min args checking and validation in general as commands are validating on prepared args and therefore cannot validate on original user args currently

This commit is contained in:
Duncan Brown
2022-04-09 17:32:50 -04:00
committed by Julian Murgia
parent 157c2f564c
commit b1b301d917
14 changed files with 76 additions and 34 deletions

View File

@@ -15,8 +15,8 @@ class_name DebugCommand
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
1,
[TYPE_STRING],
[""]
[TYPE_ARRAY],
[[""]]
)

View File

@@ -5,7 +5,7 @@
# **Parameters**
#
# - *name*: Name of the global to be changed
# - *value*: Value to be subtracted
# - *value*: Value to be subtracted (default: 1)
#
# @ESC
extends ESCBaseCommand
@@ -15,9 +15,9 @@ class_name DecGlobalCommand
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
1,
[TYPE_STRING, TYPE_INT],
[null, 0]
[null, 1]
)

View File

@@ -5,7 +5,7 @@
# **Parameters**
#
# - *name*: Name of the global to be changed
# - *value*: Value to be added
# - *value*: Value to be added (default: 1)
#
# @ESC
extends ESCBaseCommand
@@ -15,9 +15,9 @@ class_name IncGlobalCommand
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
1,
[TYPE_STRING, TYPE_INT],
[null, 0]
[null, 1]
)

View File

@@ -17,7 +17,7 @@ class_name PlaySndCommand
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
1,
[TYPE_STRING, TYPE_STRING],
[null, "_sound"]
)

View File

@@ -7,7 +7,7 @@
# **Parameters**
#
# - *name*: Name of the global to set
# - *max_value*: Maximum possible integer value (inclusive)
# - *max_value*: Maximum possible integer value (inclusive) (default: 1)
#
# @ESC
extends ESCBaseCommand
@@ -17,7 +17,7 @@ class_name RandGlobalCommand
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
1,
[TYPE_STRING, TYPE_INT],
[null, 1]
)

View File

@@ -16,7 +16,7 @@ class_name TeleportPosCommand
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
2,
3,
[TYPE_STRING, TYPE_INT, TYPE_INT],
[null, null, null]
)

View File

@@ -7,7 +7,7 @@
# - *transition_name*: Name of the transition shader from one of the transition
# directories
# - *mode*: Set to `in` to transition into or `out` to transition out of the room
# - *delay*: Delay in seconds before starting the transition (default: `1`)
# - *delay*: Delay in seconds before starting the transition (default: `1.0`)
#
# @ESC
extends ESCBaseCommand

View File

@@ -8,7 +8,8 @@
#
# - *object*: Global ID of the object to move
# - *target*: Global ID of the target object
# - *walk_fast*: Whether to walk fast (`true`) or normal speed (`false`).
# - *walk_fast*: Whether to walk fast (`true`) or normal speed (`false`)
# (default: false)
#
# @ESC
extends ESCBaseCommand

View File

@@ -9,6 +9,7 @@
# - *object*: Global ID of the object to move
# - *target*: Global ID of the target object
# - *walk_fast*: Whether to walk fast (`true`) or normal speed (`false`).
# (default: false)
#
# @ESC
extends ESCBaseCommand

View File

@@ -11,6 +11,7 @@
# - *x*: X-coordinate of target position
# - *y*: Y-coordinate of target position
# - *walk_fast*: Whether to walk fast (`true`) or normal speed (`false`).
# (default: false)
#
# @ESC
extends ESCBaseCommand

View File

@@ -11,6 +11,7 @@
# - *x*: X-coordinate of target position
# - *y*: Y-coordinate of target position
# - *walk_fast*: Whether to walk fast (`true`) or normal speed (`false`).
# (default: false)
#
# @ESC
extends ESCBaseCommand

View File

@@ -23,12 +23,12 @@ func _init() -> void:
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
escoria.logger.error("Command %s did not override configure." % get_class())
return ESCCommandArgumentDescriptor.new()
return ESCCommandArgumentDescriptor.new(0)
# Validate whether the given arguments match the command descriptor
func validate(arguments: Array) -> bool:
return self.configure().validate(get_class(), arguments)
func validate(user_arguments: Array, default_arguments: Array) -> bool:
return self.configure().validate(get_class(), user_arguments, default_arguments)
# Run the command

View File

@@ -117,10 +117,13 @@ func run() -> int:
return ESCExecution.RC_ERROR
else:
var argument_descriptor = command_object.configure()
if command_object.validate(self.parameters):
var prepared_arguments = argument_descriptor.prepare_arguments(
self.parameters
)
var prepared_arguments = argument_descriptor.prepare_arguments(
self.parameters
)
var missing_arguments = argument_descriptor.get_missing_args_from_prepared(
prepared_arguments
)
if command_object.validate(self.parameters, missing_arguments):
escoria.logger.debug("Running command %s with parameters %s" % [
self.name,
prepared_arguments

View File

@@ -12,7 +12,11 @@ const GODOT_TYPE_LIST = ["nil", "bool", "int", "real", "string", \
"raw_array", "int_array", "real_array", "string_array", \
"vector2_array", "vector3_array", "color_array", "max"]
# Number of arguments the command expects
# Maximum number of total arugments the command can handle
var max_args: int = 0
# Number of required arguments the command expects
var min_args: int = 0
# The types the arguments as TYPE_ constants. If the command is called with
@@ -34,6 +38,7 @@ func _init(
p_defaults: Array = [],
p_strip_quotes: Array = [true]
):
max_args = p_types.size()
min_args = p_min_args
types = p_types
defaults = p_defaults
@@ -62,22 +67,52 @@ func prepare_arguments(arguments: Array) -> Array:
return complete_arguments
# Splits out any missing (default) arguments (in order) for a given set of
# prepared arguments
func get_missing_args_from_prepared(user_arguments:Array, \
prepared_arguments: Array) -> Array:
for index in range(user_arguments.size()):
# Arrays are passed in by value, so this is safe
prepared_arguments.pop_front()
return prepared_arguments
# Validate whether the given arguments match the command descriptor
func validate(command: String, arguments: Array) -> bool:
if arguments.size() < self.min_args:
func validate(command: String, user_arguments: Array, default_arguments: Array) -> bool:
if user_arguments.size() < self.min_args:
escoria.logger.report_errors(
"Invalid command arguments for command %s" % command,
"ESCCommandArgumentDescriptor:validate()",
[
"Arguments didn't match minimum size {num}: {args}".format({"num":self.min_args,"args":arguments})
"Invalid command arguments for command %s" % command,
"Arguments didn't match minimum size {num}: {args}".format({"num":self.min_args,"args":user_arguments})
]
)
# We also validate the arguments as they'll appear being passed in to the
# command in question, including any default values.
arguments = self.prepare_arguments(arguments)
if user_arguments.size() > self.max_args:
escoria.logger.report_errors(
"ESCCommandArgumentDescriptor:validate()",
[
"Invalid command arguments for command %s" % command,
"Maximum number of arguments ({num}) exceeded: {args}".format({"num":self.max_args,"args":user_arguments})
]
)
for index in range(arguments.size()):
if arguments[index] == null:
var all_arguments: Array = user_arguments
all_arguments.append_array(default_arguments)
if all_arguments.size() > self.max_args:
escoria.logger.report_errors(
"ESCCommandArgumentDescriptor:validate()",
[
"Invalid command arguments for command %s" % command,
"Maximum number of arguments ({num}) exceeded: {args}".format({"num":self.max_args,"args":all_arguments})
]
)
for index in range(all_arguments.size()):
if all_arguments[index] == null:
# No type checking for null values
continue
var correct = false
@@ -88,7 +123,7 @@ func validate(command: String, arguments: Array) -> bool:
self.types[types_index] = [self.types[index]]
for type in self.types[types_index]:
if not correct:
correct = self._is_type(arguments[index], type)
correct = self._is_type(all_arguments[index], type)
if not correct:
var allowed_types = "[ "
@@ -101,8 +136,8 @@ func validate(command: String, arguments: Array) -> bool:
[
"Argument %d (\"%s\") is of type %s. Expected %s" % [
index,
arguments[index],
GODOT_TYPE_LIST[typeof(arguments[index])],
all_arguments[index],
GODOT_TYPE_LIST[typeof(all_arguments[index])],
allowed_types
]
]