Skip to content

Commit

Permalink
Improve ESC prompt F2
Browse files Browse the repository at this point in the history
- scroll down the terminal when a command is entered
- new: navigate through commands history (20 last commands max) using up and left arrow keys
- fix: do not crash when the entered command returned an error (either because the command doesn't exist or because its parameters validation failed) and show the error instead
  • Loading branch information
StraToN committed Aug 13, 2024
1 parent d87d985 commit 011ce71
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ func validate(command: String, arguments: Array) -> bool:
"Arguments didn't match minimum size {num}: Only {args} {verb} found." \
.format({"num":self.min_args,"args":required_args_count,"verb":verb})
)
return false

if arguments.size() > self.max_args and not has_varargs:
escoria.logger.error(
Expand All @@ -113,6 +114,7 @@ func validate(command: String, arguments: Array) -> bool:
{"num":self.max_args,"args":arguments}
)
)
return false

for index in range(arguments.size()):
if arguments[index] == null:
Expand Down Expand Up @@ -150,6 +152,7 @@ func validate(command: String, arguments: Array) -> bool:
allowed_types
]
)
return false
return true


Expand Down
2 changes: 1 addition & 1 deletion addons/escoria-core/game/esc_inputs_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ func _on_mouse_exited_item(item: ESCItem) -> void:

if object and not object.interactive:
return
if object and object.node is ESCPlayer and not (object.node as ESCPlayer).selectable:
if object and is_instance_valid(object.node) and object.node is ESCPlayer and not (object.node as ESCPlayer).selectable:
hotspot_focused = ""
return

Expand Down
23 changes: 18 additions & 5 deletions addons/escoria-core/game/esc_logger.gd
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
class ESCLoggerBase:
# Perform emergency savegame
signal perform_emergency_savegame

# Sends the error or warning message in the signal
signal error_message(message)

# Valid log levels
enum { LOG_ERROR, LOG_WARNING, LOG_INFO, LOG_DEBUG, LOG_TRACE }
Expand All @@ -20,12 +23,17 @@ class ESCLoggerBase:
# Configured log level
var _log_level: int

# If true, assert() functions will not be called, thus the program won't exit or error.
# Resets to false after an assert() call was ignored once.
var dont_assert: bool = false


# Constructor
func _init():
_log_level = _level_map[ESCProjectSettingsManager.get_setting(
ESCProjectSettingsManager.LOG_LEVEL
).to_upper()]



func formatted_message(context: String, msg: String, letter: String) -> String:
Expand Down Expand Up @@ -72,8 +80,11 @@ class ESCLoggerBase:
if ESCProjectSettingsManager.get_setting(
ESCProjectSettingsManager.TERMINATE_ON_WARNINGS
):
assert(false)
escoria.get_tree().quit()
if not dont_assert:
assert(false)
escoria.get_tree().quit()
dont_assert = false
emit_signal("error_message", msg)


# Error log
Expand All @@ -88,9 +99,11 @@ class ESCLoggerBase:
if ESCProjectSettingsManager.get_setting(
ESCProjectSettingsManager.TERMINATE_ON_ERRORS
):
assert(false)
escoria.get_tree().quit()

if not dont_assert:
assert(false)
escoria.get_tree().quit()
dont_assert = false
emit_signal("error_message", msg)

func get_log_level() -> int:
return _log_level
Expand Down
54 changes: 50 additions & 4 deletions addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,31 @@ onready var command = $VBoxContainer/command
# ESC commands kept around for references to their command names.
var _print: PrintCommand

# History of typed commands
var commands_history: PoolStringArray
var commands_history_current_id: int
const COMMANDS_HISTORY_LENGTH: int = 20


func _ready() -> void:
_print = PrintCommand.new()
escoria.logger.connect("error_message", self, "_on_error_message")


func _input(event: InputEvent):
if event.is_pressed() and event is InputEventKey:
if (event as InputEventKey).scancode == KEY_UP and not commands_history.empty():
commands_history_current_id -= 1
if commands_history_current_id < 0:
commands_history_current_id = 0
command.text = commands_history[commands_history_current_id]
command.call_deferred("grab_focus")
if (event as InputEventKey).scancode == KEY_DOWN and not commands_history.empty():
commands_history_current_id += 1
if commands_history_current_id > commands_history.size() - 1:
commands_history_current_id = commands_history.size() - 1
command.text = commands_history[commands_history_current_id]
command.call_deferred("grab_focus")


# Run a command
Expand All @@ -29,23 +51,47 @@ func _on_command_text_entered(p_command_str : String):
past_actions.text += "\n"
past_actions.text += "# " + p_command_str
past_actions.text += "\n"

_historize_command(p_command_str)

if p_command_str in ["history", "hist"]:
for ch in commands_history:
past_actions.text += ch + "\n"
return

var errors = []
escoria.logger.dont_assert = true
var script = escoria.esc_compiler.compile([
"%s%s" % [ESCEvent.PREFIX, _print.get_command_name()],
p_command_str
],
get_class()
"%s%s" % [ESCEvent.PREFIX, _print.get_command_name()],
p_command_str
],
get_class()
)

if script:
escoria.logger.dont_assert = true
escoria.event_manager.queue_event(script.events[escoria.event_manager.EVENT_PRINT])
var ret = yield(escoria.event_manager, "event_finished")
while ret[1] != _print.get_command_name():
ret = yield(escoria.event_manager, "event_finished")
past_actions.text += "Returned code: %d" % ret[0]

past_actions.scroll_vertical = past_actions.get_line_count()


# Set the focus to the command
func _on_esc_prompt_popup_about_to_show():
command.grab_focus()

func _on_error_message(message) -> void:
past_actions.text += message + "\n"
past_actions.scroll_vertical = past_actions.get_line_count()


func _historize_command(p_command: String) -> void:
commands_history_current_id += 1
commands_history.append(p_command)
if commands_history.size() + 1 > COMMANDS_HISTORY_LENGTH:
commands_history.remove(0)
commands_history_current_id = COMMANDS_HISTORY_LENGTH - 1

11 changes: 6 additions & 5 deletions addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@ __meta__ = {

[node name="past_actions" type="TextEdit" parent="VBoxContainer"]
margin_right = 599.0
margin_bottom = 240.0
margin_bottom = 340.0
size_flags_vertical = 3
wrap_enabled = true

[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
margin_top = 244.0
margin_top = 344.0
margin_right = 599.0
margin_bottom = 248.0
margin_bottom = 348.0

[node name="command" type="LineEdit" parent="VBoxContainer"]
margin_top = 252.0
margin_top = 352.0
margin_right = 599.0
margin_bottom = 276.0
margin_bottom = 376.0
caret_blink = true

[connection signal="about_to_show" from="." to="." method="_on_esc_prompt_popup_about_to_show"]
Expand Down

0 comments on commit 011ce71

Please sign in to comment.