Refactor console and scene structure; update resource paths and add configuration handling
This commit is contained in:
@@ -1,21 +1,22 @@
|
||||
extends Node
|
||||
|
||||
var enabled := true
|
||||
var enable_on_release_build := false : set = set_enable_on_release_build
|
||||
var pause_enabled := false
|
||||
|
||||
var enabled := true
|
||||
var enable_on_release_build := false: set = set_enable_on_release_build
|
||||
var pause_enabled := false
|
||||
signal console_opened
|
||||
signal console_closed
|
||||
signal console_unknown_command
|
||||
|
||||
|
||||
class ConsoleCommand:
|
||||
var function : Callable
|
||||
var arguments : PackedStringArray
|
||||
var required : int
|
||||
var description : String
|
||||
var hidden : bool
|
||||
func _init(in_function : Callable, in_arguments : PackedStringArray, in_required : int = 0, in_description : String = ""):
|
||||
var function: Callable
|
||||
var arguments: PackedStringArray
|
||||
var required: int
|
||||
var description: String
|
||||
var hidden: bool
|
||||
|
||||
|
||||
func _init(in_function: Callable, in_arguments: PackedStringArray, in_required: int = 0, in_description: String = ""):
|
||||
function = in_function
|
||||
arguments = in_arguments
|
||||
required = in_required
|
||||
@@ -23,49 +24,48 @@ class ConsoleCommand:
|
||||
|
||||
|
||||
var control := Control.new()
|
||||
|
||||
# If you want to customize the way the console looks, you can direcly modify
|
||||
# the properties of the rich text and line edit here:
|
||||
var rich_label := RichTextLabel.new()
|
||||
var line_edit := LineEdit.new()
|
||||
|
||||
var console_commands := {}
|
||||
var command_parameters := {}
|
||||
var console_history := []
|
||||
var rich_label := RichTextLabel.new()
|
||||
var line_edit := LineEdit.new()
|
||||
var console_commands := {}
|
||||
var command_parameters := {}
|
||||
var console_history := []
|
||||
var console_history_index := 0
|
||||
var was_paused_already := false
|
||||
var was_paused_already := false
|
||||
|
||||
|
||||
## Usage: Console.add_command("command_name", <function to call>, <number of arguments or array of argument names>, <required number of arguments>, "Help description")
|
||||
func add_command(command_name : String, function : Callable, arguments = [], required: int = 0, description : String = "") -> void:
|
||||
func add_command(command_name: String, function: Callable, arguments = [], required: int = 0, description: String = "") -> void:
|
||||
if (arguments is int):
|
||||
# Legacy call using an argument number
|
||||
var param_array : PackedStringArray
|
||||
var param_array: PackedStringArray
|
||||
for i in range(arguments):
|
||||
param_array.append("arg_" + str(i + 1))
|
||||
console_commands[command_name] = ConsoleCommand.new(function, param_array, required, description)
|
||||
elif (arguments is Array):
|
||||
# New array argument system
|
||||
var str_args : PackedStringArray
|
||||
var str_args: PackedStringArray
|
||||
for argument in arguments:
|
||||
str_args.append(str(argument))
|
||||
console_commands[command_name] = ConsoleCommand.new(function, str_args, required, description)
|
||||
|
||||
|
||||
## Adds a secret command that will not show up in the help or auto-complete.
|
||||
func add_hidden_command(command_name : String, function : Callable, arguments = [], required : int = 0) -> void:
|
||||
func add_hidden_command(command_name: String, function: Callable, arguments = [], required: int = 0) -> void:
|
||||
add_command(command_name, function, arguments, required)
|
||||
console_commands[command_name].hidden = true
|
||||
|
||||
|
||||
## Removes a command from the console. This should be called on a script's _exit_tree()
|
||||
## if you have console commands for things that are unloaded before the project closes.
|
||||
func remove_command(command_name : String) -> void:
|
||||
func remove_command(command_name: String) -> void:
|
||||
console_commands.erase(command_name)
|
||||
command_parameters.erase(command_name)
|
||||
|
||||
|
||||
## Useful if you have a list of possible parameters (ex: level names).
|
||||
func add_command_autocomplete_list(command_name : String, param_list : PackedStringArray):
|
||||
func add_command_autocomplete_list(command_name: String, param_list: PackedStringArray):
|
||||
command_parameters[command_name] = param_list
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ func _enter_tree() -> void:
|
||||
style.bg_color = Color("000000d7")
|
||||
rich_label.selection_enabled = true
|
||||
rich_label.context_menu_enabled = true
|
||||
rich_label.bbcode_enabled = true
|
||||
rich_label.bbcode_enabled = false
|
||||
rich_label.scroll_following = true
|
||||
rich_label.anchor_right = 1.0
|
||||
rich_label.anchor_bottom = 0.5
|
||||
@@ -108,7 +108,7 @@ func _enter_tree() -> void:
|
||||
func _exit_tree() -> void:
|
||||
var console_history_file := FileAccess.open("user://console_history.txt", FileAccess.WRITE)
|
||||
if (console_history_file):
|
||||
var write_index := 0
|
||||
var write_index := 0
|
||||
var start_write_index := console_history.size() - 100 # Max lines to write
|
||||
for line in console_history:
|
||||
if (write_index >= start_write_index):
|
||||
@@ -133,7 +133,8 @@ func _ready() -> void:
|
||||
add_command("unpause", unpause, 0, 0, "Unpauses node processing.")
|
||||
add_command("exec", exec, 1, 1, "Execute a script.")
|
||||
|
||||
func _input(event : InputEvent) -> void:
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if (event is InputEventKey):
|
||||
if (event.get_physical_keycode_with_modifiers() == KEY_QUOTELEFT): # ~ key.
|
||||
if (event.pressed):
|
||||
@@ -173,22 +174,23 @@ func _input(event : InputEvent) -> void:
|
||||
reset_autocomplete()
|
||||
if (event.get_physical_keycode_with_modifiers() == KEY_PAGEUP):
|
||||
var scroll := rich_label.get_v_scroll_bar()
|
||||
var tween := create_tween()
|
||||
tween.tween_property(scroll, "value", scroll.value - (scroll.page - scroll.page * 0.1), 0.1)
|
||||
var tween := create_tween()
|
||||
tween.tween_property(scroll, "value", scroll.value - (scroll.page - scroll.page * 0.1), 0.1)
|
||||
get_tree().get_root().set_input_as_handled()
|
||||
if (event.get_physical_keycode_with_modifiers() == KEY_PAGEDOWN):
|
||||
var scroll := rich_label.get_v_scroll_bar()
|
||||
var tween := create_tween()
|
||||
tween.tween_property(scroll, "value", scroll.value + (scroll.page - scroll.page * 0.1), 0.1)
|
||||
var tween := create_tween()
|
||||
tween.tween_property(scroll, "value", scroll.value + (scroll.page - scroll.page * 0.1), 0.1)
|
||||
get_tree().get_root().set_input_as_handled()
|
||||
if (event.get_physical_keycode_with_modifiers() == KEY_TAB):
|
||||
autocomplete()
|
||||
get_tree().get_root().set_input_as_handled()
|
||||
|
||||
|
||||
var suggestions := []
|
||||
var suggestions := []
|
||||
var current_suggest := 0
|
||||
var suggesting := false
|
||||
var suggesting := false
|
||||
|
||||
|
||||
func autocomplete() -> void:
|
||||
if (suggesting):
|
||||
@@ -203,11 +205,11 @@ func autocomplete() -> void:
|
||||
return
|
||||
else:
|
||||
suggesting = true
|
||||
|
||||
|
||||
if (" " in line_edit.text): # We're searching for a parameter to autocomplete
|
||||
var split_text := parse_line_input(line_edit.text)
|
||||
if (split_text.size() > 1):
|
||||
var command := split_text[0]
|
||||
var command := split_text[0]
|
||||
var param_input := split_text[1]
|
||||
if (command_parameters.has(command)):
|
||||
for param in command_parameters[command]:
|
||||
@@ -220,11 +222,11 @@ func autocomplete() -> void:
|
||||
sorted_commands.append(str(command))
|
||||
sorted_commands.sort()
|
||||
sorted_commands.reverse()
|
||||
|
||||
|
||||
var prev_index := 0
|
||||
for command in sorted_commands:
|
||||
if (!line_edit.text || command.contains(line_edit.text)):
|
||||
var index : int = command.find(line_edit.text)
|
||||
var index: int = command.find(line_edit.text)
|
||||
if (index <= prev_index):
|
||||
suggestions.push_front(command)
|
||||
else:
|
||||
@@ -284,23 +286,25 @@ func scroll_to_bottom() -> void:
|
||||
scroll.value = scroll.max_value - scroll.page
|
||||
|
||||
|
||||
func print_error(text : Variant, print_godot := false) -> void:
|
||||
func print_error(text: Variant, print_godot := false) -> void:
|
||||
if not text is String:
|
||||
text = str(text)
|
||||
print_line("[color=light_coral] ERROR:[/color] %s" % text, print_godot)
|
||||
|
||||
func print_info(text : Variant, print_godot := false) -> void:
|
||||
|
||||
func print_info(text: Variant, print_godot := false) -> void:
|
||||
if not text is String:
|
||||
text = str(text)
|
||||
print_line("[color=light_blue] INFO:[/color] %s" % text, print_godot)
|
||||
|
||||
func print_warning(text : Variant, print_godot := false) -> void:
|
||||
|
||||
|
||||
func print_warning(text: Variant, print_godot := false) -> void:
|
||||
if not text is String:
|
||||
text = str(text)
|
||||
print_line("[color=gold] WARNING:[/color] %s" % text, print_godot)
|
||||
|
||||
|
||||
func print_line(text : Variant, print_godot := false) -> void:
|
||||
func print_line(text: Variant, print_godot := false) -> void:
|
||||
if not text is String:
|
||||
text = str(text)
|
||||
if (!rich_label): # Tried to print something before the console was loaded.
|
||||
@@ -312,12 +316,12 @@ func print_line(text : Variant, print_godot := false) -> void:
|
||||
print(text)
|
||||
|
||||
|
||||
func parse_line_input(text : String) -> PackedStringArray:
|
||||
var out_array : PackedStringArray
|
||||
func parse_line_input(text: String) -> PackedStringArray:
|
||||
var out_array: PackedStringArray
|
||||
var first_char := true
|
||||
var in_quotes := false
|
||||
var escaped := false
|
||||
var token : String
|
||||
var in_quotes := false
|
||||
var escaped := false
|
||||
var token: String
|
||||
for c in text:
|
||||
if (c == '\\'):
|
||||
escaped = true
|
||||
@@ -349,23 +353,23 @@ func parse_line_input(text : String) -> PackedStringArray:
|
||||
return out_array
|
||||
|
||||
|
||||
func on_text_entered(new_text : String) -> void:
|
||||
func on_text_entered(new_text: String) -> void:
|
||||
scroll_to_bottom()
|
||||
reset_autocomplete()
|
||||
line_edit.clear()
|
||||
if (line_edit.has_method(&"edit")):
|
||||
line_edit.call_deferred(&"edit")
|
||||
|
||||
|
||||
if not new_text.strip_edges().is_empty():
|
||||
add_input_history(new_text)
|
||||
print_line("[i]> " + new_text + "[/i]")
|
||||
var text_split := parse_line_input(new_text)
|
||||
var text_split := parse_line_input(new_text)
|
||||
var text_command := text_split[0]
|
||||
|
||||
|
||||
if console_commands.has(text_command):
|
||||
var arguments := text_split.slice(1)
|
||||
var console_command : ConsoleCommand = console_commands[text_command]
|
||||
|
||||
var arguments := text_split.slice(1)
|
||||
var console_command: ConsoleCommand = console_commands[text_command]
|
||||
|
||||
# calc is a especial command that needs special treatment
|
||||
if (text_command.match("calc")):
|
||||
var expression := ""
|
||||
@@ -390,7 +394,7 @@ func on_text_entered(new_text : String) -> void:
|
||||
print_error("Command not found.")
|
||||
|
||||
|
||||
func on_line_edit_text_changed(new_text : String) -> void:
|
||||
func on_line_edit_text_changed(new_text: String) -> void:
|
||||
reset_autocomplete()
|
||||
|
||||
|
||||
@@ -409,30 +413,51 @@ func delete_history() -> void:
|
||||
|
||||
|
||||
func help() -> void:
|
||||
rich_label.append_text(" Built in commands:
|
||||
rich_label.append_text(" Built in commands:
|
||||
[color=light_green]calc[/color]: Calculates a given expresion
|
||||
[color=light_green]clear[/color]: Clears the registry view
|
||||
[color=light_green]commands[/color]: Shows a reduced list of all the currently registered commands
|
||||
[color=light_green]commands_list[/color]: Shows a detailed list of all the currently registered commands
|
||||
[color=light_green]delete_history[/color]: Deletes the commands history
|
||||
[color=light_green]echo[/color]: Prints a given string to the console
|
||||
[color=light_green]echo_error[/color]: Prints a given string as an error to the console
|
||||
[color=light_green]echo_info[/color]: Prints a given string as info to the console
|
||||
[color=light_green]echo_warning[/color]: Prints a given string as warning to the console
|
||||
[color=light_green]pause[/color]: Pauses node processing
|
||||
[color=light_green]unpause[/color]: Unpauses node processing
|
||||
[color=light_green]quit[/color]: Quits the game
|
||||
Controls:
|
||||
[color=light_blue]Up[/color] and [color=light_blue]Down[/color] arrow keys to navigate commands history
|
||||
[color=light_blue]PageUp[/color] and [color=light_blue]PageDown[/color] to scroll registry
|
||||
[[color=light_blue]Ctrl[/color] + [color=light_blue]~[/color]] to change console size between half screen and full screen
|
||||
[color=light_blue]~[/color] or [color=light_blue]Esc[/color] key to close the console
|
||||
[color=light_blue]Tab[/color] key to autocomplete, [color=light_blue]Tab[/color] again to cycle between matching suggestions\n\n")
|
||||
[color=light_green]clear[/color]: Clears the registry view
|
||||
[color=light_green]commands[/color]: Shows a reduced list of all the currently registered commands
|
||||
[color=light_green]commands_list[/color]: Shows a detailed list of all the currently registered commands
|
||||
[color=light_green]delete_history[/color]: Deletes the commands history
|
||||
[color=light_green]echo[/color]: Prints a given string to the console
|
||||
[color=light_green]echo_error[/color]: Prints a given string as an error to the console
|
||||
[color=light_green]echo_info[/color]: Prints a given string as info to the console
|
||||
[color=light_green]echo_warning[/color]: Prints a given string as warning to the console
|
||||
[color=light_green]pause[/color]: Pauses node processing
|
||||
[color=light_green]unpause[/color]: Unpauses node processing
|
||||
[color=light_green]quit[/color]: Quits the game
|
||||
Controls:
|
||||
[color=light_blue]Up[/color] and [color=light_blue]Down[/color] arrow keys to navigate commands history
|
||||
[color=light_blue]PageUp[/color] and [color=light_blue]PageDown[/color] to scroll registry
|
||||
[[color=light_blue]Ctrl[/color] + [color=light_blue]~[/color]] to change console size between half screen and full screen
|
||||
[color=light_blue]~[/color] or [color=light_blue]Esc[/color] key to close the console
|
||||
[color=light_blue]Tab[/color] key to autocomplete, [color=light_blue]Tab[/color] again to cycle between matching suggestions\n\n")
|
||||
|
||||
|
||||
func calculate(command : String) -> void:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func calculate(command: String) -> void:
|
||||
var expression := Expression.new()
|
||||
var error = expression.parse(command)
|
||||
var error = expression.parse(command)
|
||||
if error:
|
||||
print_error("%s" % expression.get_error_text())
|
||||
return
|
||||
@@ -459,10 +484,10 @@ func commands_list() -> void:
|
||||
if (!console_commands[command].hidden):
|
||||
commands.append(str(command))
|
||||
commands.sort()
|
||||
|
||||
|
||||
for command in commands:
|
||||
var arguments_string := ""
|
||||
var description : String = console_commands[command].description
|
||||
var arguments_string := ""
|
||||
var description: String = console_commands[command].description
|
||||
for i in range(console_commands[command].arguments.size()):
|
||||
if i < console_commands[command].required:
|
||||
arguments_string += " [color=cornflower_blue]<" + console_commands[command].arguments[i] + ">[/color]"
|
||||
@@ -472,13 +497,13 @@ func commands_list() -> void:
|
||||
rich_label.append_text("\n")
|
||||
|
||||
|
||||
func add_input_history(text : String) -> void:
|
||||
func add_input_history(text: String) -> void:
|
||||
if (!console_history.size() || text != console_history.back()): # Don't add consecutive duplicates
|
||||
console_history.append(text)
|
||||
console_history_index = console_history.size()
|
||||
|
||||
|
||||
func set_enable_on_release_build(enable : bool):
|
||||
func set_enable_on_release_build(enable: bool):
|
||||
enable_on_release_build = enable
|
||||
if (!enable_on_release_build):
|
||||
if (!OS.is_debug_build()):
|
||||
@@ -487,12 +512,14 @@ func set_enable_on_release_build(enable : bool):
|
||||
|
||||
func pause() -> void:
|
||||
get_tree().paused = true
|
||||
|
||||
|
||||
|
||||
func unpause() -> void:
|
||||
get_tree().paused = false
|
||||
|
||||
func exec(filename : String) -> void:
|
||||
var path := "user://%s.txt" % [filename]
|
||||
|
||||
|
||||
func exec(filename: String) -> void:
|
||||
var path := "user://%s.txt" % [filename]
|
||||
var script := FileAccess.open(path, FileAccess.READ)
|
||||
if (script):
|
||||
while (!script.eof_reached()):
|
||||
|
Reference in New Issue
Block a user