Skip to content

Commit b4a40f3

Browse files
authored
Merge pull request #46 from XanatosX/feature/43_add-custom-command-require-data-type
feat: add data types to command arguments
2 parents 8ed67e5 + d2c8479 commit b4a40f3

File tree

11 files changed

+207
-48
lines changed

11 files changed

+207
-48
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,30 @@ func _reload() -> String:
3434
get_tree().reload_current_scene()
3535
return "reloaded scene"
3636
```
37+
> This will add an command where the arguments are provided as Strings, your method accepting those arguments will get strings as well
38+
> you will need to convert to the correct data type all by yourself.
39+
40+
### Register a strong argument command
41+
42+
```gdscript
43+
Console.register_custom_strong_command("spawn_entity",
44+
_spawn_entity,
45+
[CommandArgument.new(CommandArgument.Type.INT, "X Position", "The x position on screen for the entity"),
46+
CommandArgument.new(CommandArgument.Type.INT, "y Position", "The y position on screen for the entity"),
47+
CommandArgument.new(CommandArgument.Type.FLOAT, "time to life", "The time the entity should life in seconds")
48+
],
49+
"Spawn an example entity at a global position",
50+
"",
51+
["spawn_entity 200 300 4"]
52+
)
53+
54+
func _spawn_entity(pos_x: int, pos_y: int, ttl: float) -> String:
55+
pass
56+
57+
```
58+
> This will add a new argument but the argument types are defined, this will parse the input data automatically making it easier to use in your method. If a wrong type was provided to any
59+
> of the arguments an error will be thrown preventing the method execution.
60+
3761

3862
### Unregister a command
3963

addons/gameconsole/builtin/command_argument_count_not_matching.gd

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
extends CommandTemplate
22

33
func create_command() -> Command:
4-
var command = Command.new("argument not matching", _argument_count_not_matching, ["command_name"], "The provided arguments do not match")
4+
var command = Command.new("argument not matching",
5+
_argument_count_not_matching,
6+
[CommandArgument.new(CommandArgument.Type.STRING, "Command Name", "")],
7+
"The provided arguments do not match"
8+
)
59
command.is_hidden = true
610
return command
711

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
extends CommandTemplate
2+
3+
func create_command() -> Command:
4+
var command = Command.new("argument_not_valid",
5+
_argument_is_not_valid,
6+
[CommandArgument.new(CommandArgument.Type.STRING, "Command Name", ""),
7+
CommandArgument.new(CommandArgument.Type.STRING, "Argument Name", ""),
8+
CommandArgument.new(CommandArgument.Type.STRING, "Expected Type", ""),
9+
CommandArgument.new(CommandArgument.Type.STRING, "Provided Data", "")
10+
],
11+
"The type of the given argument is not correct"
12+
)
13+
command.is_hidden = true
14+
return command
15+
16+
func _argument_is_not_valid(command_name: String, argument_name: String, expected_type: String, provided_data: String) -> String:
17+
argument_name = argument_name.replace("_", " ")
18+
return "[color=red]Command \"%s\" does require (%s) type for argument \"%s\" but provided value was \"%s\"[/color]" % [command_name, expected_type, argument_name, provided_data]

addons/gameconsole/builtin/command_man.gd

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
extends CommandTemplate
22

33
func create_command() -> Command:
4-
var command = Command.new("man", manual, ["Name of the command"], "Command to get a manual for an command", "", ["man list_commands"])
4+
var command = Command.new("man",
5+
_manual,
6+
[CommandArgument.new(CommandArgument.Type.STRING, "Name of the command", "")],
7+
"Command to get a manual for an command",
8+
"",
9+
["man list_commands"])
510
return command
611

7-
func manual(command_name: String) -> String:
12+
func _manual(command_name: String) -> String:
813
var command = Console.get_specific_command(command_name)
914
if command == null or command.is_hidden:
1015
return "[color=red]No command with name %s was found[/color]" % command_name

addons/gameconsole/builtin/command_not_found.gd

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
extends CommandTemplate
22

33
func create_command() -> Command:
4-
var command = Command.new("not found", _not_found, ["Command name"], "Command was not found")
4+
var command = Command.new("not found",
5+
_not_found,
6+
[CommandArgument.new(CommandArgument.Type.STRING, "Command Name", "")],
7+
"Command was not found"
8+
)
59
command.is_hidden = true
610
return command
711

addons/gameconsole/console/command/command.gd

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class_name Command extends Node
22

33
var command: String
44
var function: Callable
5-
var arguments : PackedStringArray
5+
var arguments : Array[CommandArgument]
66

77
var short_description: String
88
var description: String
@@ -16,7 +16,7 @@ var self_example_links := {}
1616

1717
func _init(command_name: String,
1818
functionality: Callable,
19-
in_arguments : PackedStringArray = [],
19+
in_arguments : Array[CommandArgument] = [],
2020
command_description: String = "",
2121
long_description: String = "",
2222
command_examples: PackedStringArray = []
@@ -41,8 +41,32 @@ func _init(command_name: String,
4141
func get_command_name() -> String :
4242
return command
4343

44-
func execute(arguments: Array) -> String:
45-
var data = function.callv(arguments)
44+
func execute(in_arguments: Array) -> String:
45+
if in_arguments.size() != arguments.size():
46+
Console.search_and_execute_command("argument_not_matching %s" % command)
47+
return ""
48+
49+
var is_valid: bool = true
50+
for i in in_arguments.size():
51+
var current_argument_type = arguments[i]
52+
if not current_argument_type.is_valid_for(in_arguments[i]):
53+
is_valid = false
54+
var data = "%s %s %s %s %s" % ["argument_not_valid",
55+
command,
56+
current_argument_type.get_display_name().to_snake_case(),
57+
current_argument_type.Type.keys()[current_argument_type.get_type()],
58+
in_arguments[i]
59+
]
60+
Console.search_and_execute_command(data)
61+
return ""
62+
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)
4670
if data == null:
4771
data = ""
4872
return data
@@ -57,7 +81,7 @@ func get_command_short_description():
5781
func get_arguments() -> String:
5882
var return_arguments = ""
5983
for argument in arguments:
60-
return_arguments += "[%s]" % argument
84+
return_arguments += "[%s]" % argument.get_display_name()
6185
return return_arguments
6286

6387
func as_stripped() -> StrippedCommand:
@@ -77,7 +101,12 @@ func get_man_page() -> String:
77101
return_text += "\n[i][b]Arguments[/b][/i]\n\n"
78102
return_text += "[ul]"
79103
for argument in arguments:
80-
return_text += "%s\n" % argument
104+
return_text += "%s" % argument.get_display_name()
105+
var argument_description = argument.get_description()
106+
if not argument_description.is_empty():
107+
return_text += " -> %s" % argument_description
108+
return_text += "\n"
109+
81110
return_text += "[/ul]"
82111
if examples.size() > 0:
83112
return_text += "\n\n[i][b]Examples[/b][/i]\n\n"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
class_name CommandArgument extends Resource
2+
3+
enum Type
4+
{
5+
UNKNOWN,
6+
STRING,
7+
INT,
8+
FLOAT,
9+
BOOL,
10+
}
11+
12+
var _argument_type: Type
13+
var _argument_name: String
14+
var _argument_description: String = ""
15+
16+
func _init(type: Type, name: String, description: String):
17+
_argument_type = type
18+
_argument_name = name
19+
_argument_description = description
20+
21+
func get_type() -> Type:
22+
return _argument_type
23+
24+
func get_display_name() -> String:
25+
var prefix: String = "(%s)"
26+
match _argument_type:
27+
Type.UNKNOWN:
28+
prefix = ""
29+
Type.STRING:
30+
prefix = prefix % "String"
31+
Type.INT:
32+
prefix = prefix % "Int"
33+
Type.FLOAT:
34+
prefix = prefix % "Float"
35+
Type.BOOL:
36+
prefix = prefix % "Bool 0/1"
37+
return "%s %s" % [prefix, _argument_name]
38+
39+
func get_description() -> String:
40+
return _argument_description
41+
42+
func is_valid_for(data: String) -> bool:
43+
match _argument_type:
44+
Type.UNKNOWN:
45+
return true
46+
Type.STRING:
47+
return true
48+
Type.INT:
49+
return data.is_valid_int()
50+
Type.FLOAT:
51+
return data.is_valid_float()
52+
Type.BOOL:
53+
if not data.is_valid_int():
54+
return false
55+
var converted_data = int(data)
56+
return converted_data == 0 or converted_data == 1
57+
_:
58+
return false
59+
60+
func convert_data(data: String) -> Variant:
61+
if not is_valid_for(data):
62+
return null
63+
match _argument_type:
64+
Type.UNKNOWN:
65+
return data
66+
Type.STRING:
67+
return data
68+
Type.INT:
69+
return int(data)
70+
Type.FLOAT:
71+
return float(data)
72+
Type.BOOL:
73+
return int(data) == 1
74+
_:
75+
return null
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
class_name StrippedCommand extends Resource
22

33
var command: String
4-
var arguments: PackedStringArray
4+
var arguments: Array[CommandArgument]

addons/gameconsole/console/console.gd

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,29 @@ func _register_builtin_command(command: Command):
150150
command.built_in = true
151151
_console_commands[command.get_command_name()] = command
152152

153-
func register_custom_command(command: String,
154-
function: Callable,
155-
in_arguments : PackedStringArray = [],
156-
short_description: String = "",
157-
description: String = "",
158-
example: PackedStringArray = []):
153+
## Register a custom command with strong typed parameters
154+
func register_custom_strong_command(command: String,
155+
function: Callable,
156+
in_arguments: Array[CommandArgument],
157+
short_description: String = "",
158+
description: String = "",
159+
example: PackedStringArray = []):
159160
var real_command = Command.new(command, function, in_arguments, short_description, description, example)
160161
register_command(real_command)
161162

163+
## Register a custom command without using the new parameter types
164+
func register_custom_command(command: String,
165+
function: Callable,
166+
in_arguments : PackedStringArray = [],
167+
short_description: String = "",
168+
description: String = "",
169+
example: PackedStringArray = []):
170+
var converted_arguments: Array[CommandArgument] = []
171+
for argument in in_arguments:
172+
converted_arguments.append(CommandArgument.new(CommandArgument.Type.UNKNOWN, argument, ""))
173+
register_custom_strong_command(command, function, converted_arguments, short_description, description, example)
174+
175+
## Register a new command you already created the object instance for
162176
func register_command(command: Command):
163177
var name = command.get_command_name()
164178
command.built_in = false
@@ -180,8 +194,6 @@ func search_and_execute_command(command_text: String):
180194
if command_to_run == null:
181195
search_and_execute_command("not_found %s" % executer.command)
182196
return
183-
if executer.arguments.size() != command_to_run.arguments.size():
184-
search_and_execute_command("argument_not_matching %s" % executer.command)
185197
var result = command_to_run.execute(executer.arguments)
186198
if result != "":
187199
console_output.emit(result + "\n")

addons/gameconsole/console/console/autocomplete_label.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ 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]
46+
arguments += "[color=%s]%s[/color] " % [color.to_html(), argument.get_display_name()]
4747
argument_counter += 1
4848
arguments = arguments.trim_suffix(" ")
4949

0 commit comments

Comments
 (0)