From b1b301d917582d5a7620dd611d39c7434bb88e14 Mon Sep 17 00:00:00 2001 From: Duncan Brown Date: Sat, 9 Apr 2022 17:32:50 -0400 Subject: [PATCH] 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 --- .../game/core-scripts/esc/commands/debug.gd | 4 +- .../core-scripts/esc/commands/dec_global.gd | 6 +- .../core-scripts/esc/commands/inc_global.gd | 6 +- .../core-scripts/esc/commands/play_snd.gd | 2 +- .../core-scripts/esc/commands/rand_global.gd | 4 +- .../core-scripts/esc/commands/teleport_pos.gd | 2 +- .../core-scripts/esc/commands/transition.gd | 2 +- .../game/core-scripts/esc/commands/walk.gd | 3 +- .../core-scripts/esc/commands/walk_block.gd | 1 + .../core-scripts/esc/commands/walk_to_pos.gd | 1 + .../esc/commands/walk_to_pos_block.gd | 1 + .../esc/types/esc_base_command.gd | 6 +- .../core-scripts/esc/types/esc_command.gd | 11 ++-- .../types/esc_command_argument_descriptor.gd | 61 +++++++++++++++---- 14 files changed, 76 insertions(+), 34 deletions(-) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/debug.gd b/addons/escoria-core/game/core-scripts/esc/commands/debug.gd index 530272fb..5b41540f 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/debug.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/debug.gd @@ -15,8 +15,8 @@ class_name DebugCommand func configure() -> ESCCommandArgumentDescriptor: return ESCCommandArgumentDescriptor.new( 1, - [TYPE_STRING], - [""] + [TYPE_ARRAY], + [[""]] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/dec_global.gd b/addons/escoria-core/game/core-scripts/esc/commands/dec_global.gd index 05ea6398..acd0c42a 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/dec_global.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/dec_global.gd @@ -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] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/inc_global.gd b/addons/escoria-core/game/core-scripts/esc/commands/inc_global.gd index 214c8693..9c3971e0 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/inc_global.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/inc_global.gd @@ -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] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/play_snd.gd b/addons/escoria-core/game/core-scripts/esc/commands/play_snd.gd index 540cf625..66a58052 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/play_snd.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/play_snd.gd @@ -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"] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/rand_global.gd b/addons/escoria-core/game/core-scripts/esc/commands/rand_global.gd index 1f93c798..0d4056d0 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/rand_global.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/rand_global.gd @@ -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] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd b/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd index ae15e842..1b987613 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/teleport_pos.gd @@ -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] ) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/transition.gd b/addons/escoria-core/game/core-scripts/esc/commands/transition.gd index 2e754426..19b89fb4 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/transition.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/transition.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk.gd index 69a8c378..263d47f3 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd index 8695633d..5efc9623 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk_block.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd index cccd5fa1..fa596d39 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd index 7abd7036..85eca24c 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/walk_to_pos_block.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/types/esc_base_command.gd b/addons/escoria-core/game/core-scripts/esc/types/esc_base_command.gd index 3e5c5c91..e43b6136 100644 --- a/addons/escoria-core/game/core-scripts/esc/types/esc_base_command.gd +++ b/addons/escoria-core/game/core-scripts/esc/types/esc_base_command.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd b/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd index bc2bd595..c76fca99 100644 --- a/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd +++ b/addons/escoria-core/game/core-scripts/esc/types/esc_command.gd @@ -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 diff --git a/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd b/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd index 2342803e..4f6a7d2f 100644 --- a/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd +++ b/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd @@ -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 ] ]