Skip to content

Commit 377123b

Browse files
authored
Merge pull request #47 from XanatosX/feature/45_add-support-for-optional-parameters
feat: add optional arguments
2 parents b4a40f3 + 905ed1a commit 377123b

File tree

7 files changed

+122
-30
lines changed

7 files changed

+122
-30
lines changed

addons/gameconsole/builtin/command_argument_count_not_matching.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ func _argument_count_not_matching(command_name: String) -> String:
1313
var return_data = "";
1414
var command = Console._console_commands[command_name]
1515
var command_arguments = command.get_arguments()
16-
return_data += "[color=red]The arguments provided do not match the arguments %s of command[/color]" % [command_arguments]
16+
return_data += "[color=red]The required arguments provided do not match the number of required arguments %s of command[/color]" % [command_arguments]
1717
return return_data
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extends CommandTemplate
2+
3+
func create_command() -> Command:
4+
var command = Command.new("to_many_arguments",
5+
_to_many_arguments,
6+
[CommandArgument.new(CommandArgument.Type.STRING, "Command Name"),
7+
CommandArgument.new(CommandArgument.Type.INT, "Number of given arguments"),
8+
CommandArgument.new(CommandArgument.Type.INT, "Number of requested arguments")],
9+
"The provided arguments do not match"
10+
)
11+
command.is_hidden = true
12+
return command
13+
14+
func _to_many_arguments(command_name: String, given_argument_count: int, required_argument_count: int) -> String:
15+
return "[color=red]The command %s does require %s arguments, but %s where given![/color]" % [command_name, required_argument_count, given_argument_count]

addons/gameconsole/console/command/command.gd

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ var self_man_link: Interaction
1414
var self_enter_link: Interaction
1515
var self_example_links := {}
1616

17+
var _is_valid: bool = true
18+
1719
func _init(command_name: String,
1820
functionality: Callable,
1921
in_arguments : Array[CommandArgument] = [],
@@ -33,43 +35,83 @@ func _init(command_name: String,
3335
self_man_link.from_raw("man", command)
3436
self_enter_link.from_raw("enter", command)
3537

38+
_validate_self()
39+
3640
for example in examples:
3741
var example_link = Interaction.new()
3842
example_link.from_raw("enter", example)
3943
self_example_links[example] = example_link
4044

45+
func _validate_self():
46+
var optional_mode: bool = false
47+
for argument in arguments:
48+
if optional_mode and not argument.is_optional():
49+
_is_valid = false
50+
return
51+
if argument.is_optional():
52+
optional_mode = true
53+
54+
func is_valid_command():
55+
return _is_valid
56+
4157
func get_command_name() -> String :
4258
return command
4359

4460
func execute(in_arguments: Array) -> String:
45-
if in_arguments.size() != arguments.size():
61+
if arguments.size() > 0 and in_arguments.size() < arguments.filter(func(argument): return not argument.is_optional()).size():
4662
Console.search_and_execute_command("argument_not_matching %s" % command)
4763
return ""
4864

65+
if arguments.size() > 0 and in_arguments.size() > arguments.size():
66+
Console.search_and_execute_command("to_many_arguments %s %s %s" % [command, in_arguments.size(), arguments.size()])
67+
Console.search_and_execute_command("man %s" % [command])
68+
return ""
69+
70+
if !_validate_arguments(in_arguments):
71+
return ""
72+
73+
74+
var converted_data: Array[Variant] = []
75+
for i in arguments.size():
76+
var raw_data: String = _get_data_at_position(in_arguments, arguments[i], i)
77+
var data = arguments[i].convert_data(raw_data)
78+
converted_data.append(data)
79+
80+
var data = function.callv(converted_data)
81+
if data == null:
82+
data = ""
83+
return data
84+
85+
func _get_data_at_position(in_arguments: Array, current_argument: CommandArgument, data_index: int) -> String:
86+
var value: String = ""
87+
if current_argument.is_optional():
88+
value = current_argument.get_default_value()
89+
if data_index < in_arguments.size():
90+
value = in_arguments[data_index]
91+
return value
92+
93+
94+
95+
func _validate_arguments(in_arguments: Array) -> bool:
4996
var is_valid: bool = true
50-
for i in in_arguments.size():
97+
for i in arguments.size():
5198
var current_argument_type = arguments[i]
52-
if not current_argument_type.is_valid_for(in_arguments[i]):
99+
100+
var value: String = _get_data_at_position(in_arguments, current_argument_type, i)
101+
102+
if not current_argument_type.is_valid_for(value):
53103
is_valid = false
54104
var data = "%s %s %s %s %s" % ["argument_not_valid",
55105
command,
56106
current_argument_type.get_display_name().to_snake_case(),
57107
current_argument_type.Type.keys()[current_argument_type.get_type()],
58-
in_arguments[i]
108+
value
59109
]
60110
Console.search_and_execute_command(data)
61-
return ""
111+
return is_valid
62112

63-
64-
var converted_data: Array[Variant] = []
65-
for i in in_arguments.size():
66-
var data = arguments[i].convert_data(in_arguments[i])
67-
converted_data.append(data)
68-
69-
var data = function.callv(converted_data)
70-
if data == null:
71-
data = ""
72-
return data
113+
return is_valid
114+
73115

74116
func get_interactive_command():
75117
var url_part = "[url=%s]" % self_man_link.get_as_string()
@@ -101,10 +143,13 @@ func get_man_page() -> String:
101143
return_text += "\n[i][b]Arguments[/b][/i]\n\n"
102144
return_text += "[ul]"
103145
for argument in arguments:
146+
if argument.is_optional():
147+
return_text += "[Optional] "
104148
return_text += "%s" % argument.get_display_name()
105149
var argument_description = argument.get_description()
106150
if not argument_description.is_empty():
107151
return_text += " -> %s" % argument_description
152+
108153
return_text += "\n"
109154

110155
return_text += "[/ul]"

addons/gameconsole/console/command/command_argument.gd

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,25 @@ var _argument_type: Type
1313
var _argument_name: String
1414
var _argument_description: String = ""
1515

16-
func _init(type: Type, name: String, description: String):
16+
var _is_optional: bool = false
17+
var _default_value: String = ""
18+
19+
## Create a new command argument, if you provide a default value this command will be optional
20+
func _init(type: Type, name: String, description: String = "", default_value: String = ""):
1721
_argument_type = type
1822
_argument_name = name
1923
_argument_description = description
20-
24+
25+
make_optional(default_value)
26+
27+
func make_optional(default_value: String) -> bool:
28+
if default_value.is_empty() or not is_valid_for(default_value):
29+
return false
30+
31+
_default_value = default_value
32+
_is_optional = true
33+
return true
34+
2135
func get_type() -> Type:
2236
return _argument_type
2337

@@ -72,4 +86,10 @@ func convert_data(data: String) -> Variant:
7286
Type.BOOL:
7387
return int(data) == 1
7488
_:
75-
return null
89+
return null
90+
91+
func is_optional() -> bool:
92+
return _is_optional
93+
94+
func get_default_value() -> String:
95+
return _default_value

addons/gameconsole/console/console.gd

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,28 +156,36 @@ func register_custom_strong_command(command: String,
156156
in_arguments: Array[CommandArgument],
157157
short_description: String = "",
158158
description: String = "",
159-
example: PackedStringArray = []):
159+
example: PackedStringArray = []) -> bool:
160160
var real_command = Command.new(command, function, in_arguments, short_description, description, example)
161-
register_command(real_command)
161+
162+
return register_command(real_command)
162163

163164
## Register a custom command without using the new parameter types
164165
func register_custom_command(command: String,
165166
function: Callable,
166167
in_arguments : PackedStringArray = [],
167168
short_description: String = "",
168169
description: String = "",
169-
example: PackedStringArray = []):
170+
example: PackedStringArray = []) -> bool:
170171
var converted_arguments: Array[CommandArgument] = []
171172
for argument in in_arguments:
172173
converted_arguments.append(CommandArgument.new(CommandArgument.Type.UNKNOWN, argument, ""))
173-
register_custom_strong_command(command, function, converted_arguments, short_description, description, example)
174+
return register_custom_strong_command(command, function, converted_arguments, short_description, description, example)
174175

175176
## Register a new command you already created the object instance for
176-
func register_command(command: Command):
177+
func register_command(command: Command) -> bool:
178+
if not command.is_valid_command():
179+
var message = "Tried to register command %s which does use an invalid configuration!" % command.get_command_name()
180+
print(message)
181+
print_as_error(message)
182+
return false
177183
var name = command.get_command_name()
178184
command.built_in = false
179185
_console_commands[command.get_command_name()] = command
180186

187+
return true
188+
181189
func remove_command(name: String) -> bool:
182190
name = name.to_snake_case()
183191
if !_console_commands.has(name):
@@ -189,6 +197,7 @@ func remove_command(name: String) -> bool:
189197
return _console_commands.erase(name)
190198

191199
func search_and_execute_command(command_text: String):
200+
command_text = command_text.strip_edges()
192201
var executer = CommandDefinition.new(command_text)
193202
var command_to_run = _console_commands.get(executer.command)
194203
if command_to_run == null:

addons/gameconsole/console/console/autocomplete_label.gd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ func _display_autocomplete(data: StrippedCommand):
4343
var color: Color = Console.console_settings.autocomplete_argument_color_odd
4444
if argument_counter % 2 == 0:
4545
color = Console.console_settings.autocomplete_argument_color_even
46-
arguments += "[color=%s]%s[/color] " % [color.to_html(), argument.get_display_name()]
46+
var optional = ""
47+
if argument.is_optional():
48+
optional = "[optional]"
49+
arguments += "[color=%s]%s%s[/color] " % [color.to_html(), optional, argument.get_display_name()]
4750
argument_counter += 1
4851
arguments = arguments.trim_suffix(" ")
4952

example/console_example.gd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ func _register_commands():
3636
"Increase the counter",
3737
"Command will increase a local counter",
3838
["count_up 1", "count_up 3"])
39-
39+
4040
var count_down_command = Command.new("count_down",
4141
_count_down,
42-
[CommandArgument.new(CommandArgument.Type.INT, "amount", "The amount to count down from the current counter")],
42+
[CommandArgument.new(CommandArgument.Type.INT, "amount", "The amount to count down from the current counter", "1")],
4343
"Decrease the internal counter",
4444
"Command will decrease a local counter",
45-
["count_down 1", "count_down 5"])
45+
["count_down", "count_down 2", "count_down 5"])
4646

4747
Console.register_command(count_down_command)
4848
Console.register_custom_command("reload", _reload, [], "Reload current scene")
4949
Console.register_custom_strong_command("spawn_entity",
5050
_spawn_entity,
5151
[CommandArgument.new(CommandArgument.Type.INT, "X Position", "The x position on screen for the entity"),
5252
CommandArgument.new(CommandArgument.Type.INT, "y Position", "The y position on screen for the entity"),
53-
CommandArgument.new(CommandArgument.Type.FLOAT, "time to life", "The time the entity should life in seconds")
53+
CommandArgument.new(CommandArgument.Type.FLOAT, "time to life", "The time the entity should life in seconds", "1"),
5454
],
5555
"Spawn an example entity at a global position",
5656
"",
@@ -62,7 +62,7 @@ func _register_commands():
6262

6363
if !always_use_custom_console:
6464
Console.register_custom_command("custom_console", _open_custom_console, [], "Open your custom console", "", [])
65-
Console.register_custom_command("default_console", _open_default_console, [], "Open the default console", "", [])
65+
Console.register_custom_command("default_console", _open_default_console, [], "Open the default console")
6666

6767
func _spawn_entity(pos_x: int, pos_y: int, ttl: float) -> String:
6868
_trigger_spawn_entity(pos_x, pos_y, ttl)

0 commit comments

Comments
 (0)