From bfa561357e50dedc66dc20273a25c45f1a35d75b Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Sat, 3 Jul 2021 00:04:34 +0700 Subject: [PATCH] Yield for "frame_pre_draw" signal before writing to terminal Fixes #41. But creates another issue where sometimes the yield will resume after the terminal node has already been freed logging an error to the console. Also a few changes to where update is called it the gdnative terminal code. Also changed gdnative terminal to only accept strings. --- addons/godot_xterm/native/src/terminal.cpp | 32 ++++--------------- addons/godot_xterm/native/src/terminal.h | 4 ++- addons/godot_xterm/nodes/terminal/terminal.gd | 30 ++++++++++++++--- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/addons/godot_xterm/native/src/terminal.cpp b/addons/godot_xterm/native/src/terminal.cpp index b7b50f1..e2da0a0 100644 --- a/addons/godot_xterm/native/src/terminal.cpp +++ b/addons/godot_xterm/native/src/terminal.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2021, Leroy Hopson (MIT License). + #include "terminal.h" #include #include @@ -543,36 +545,14 @@ void Terminal::update_size() { rows = std::max(2, (int)floor(get_rect().size.y / cell_size.y)); cols = std::max(1, (int)floor(get_rect().size.x / cell_size.x)); - emit_signal("size_changed", Vector2(cols, rows)); - tsm_screen_resize(screen, cols, rows); - update(); + emit_signal("size_changed", Vector2(cols, rows)); } -void Terminal::write(Variant data) { - const char *u8; - size_t len; - - switch (data.get_type()) { - case Variant::Type::POOL_BYTE_ARRAY: { - PoolByteArray bytes = data; - u8 = (char *)bytes.read().ptr(); - len = bytes.size(); - break; - } - case Variant::Type::STRING: { - String string = data; - u8 = string.alloc_c_string(); - len = strlen(u8); - break; - } - default: - WARN_PRINT("Method expected a String or PoolByteArray"); - return; - } +void Terminal::write(String data) { + const char *u8 = data.alloc_c_string(); + size_t len = strlen(u8); tsm_vte_input(vte, u8, len); - - update(); } diff --git a/addons/godot_xterm/native/src/terminal.h b/addons/godot_xterm/native/src/terminal.h index 1c8aaee..3df9c35 100644 --- a/addons/godot_xterm/native/src/terminal.h +++ b/addons/godot_xterm/native/src/terminal.h @@ -1,3 +1,5 @@ +// Copyright (c) 2021, Leroy Hopson (MIT License). + #ifndef TERMINAL_H #define TERMINAL_H @@ -52,7 +54,7 @@ public: void _gui_input(Variant event); void _draw(); - void write(Variant data); + void write(String data); enum UpdateMode { DISABLED, diff --git a/addons/godot_xterm/nodes/terminal/terminal.gd b/addons/godot_xterm/nodes/terminal/terminal.gd index f370658..8d0dee0 100644 --- a/addons/godot_xterm/nodes/terminal/terminal.gd +++ b/addons/godot_xterm/nodes/terminal/terminal.gd @@ -16,13 +16,18 @@ enum UpdateMode { export (UpdateMode) var update_mode = UpdateMode.AUTO setget set_update_mode -var rows: int setget , get_rows # TODO: Show in inspector. -var cols: int setget , get_cols # TODO: Show in inspector. +var cols = 2 +var rows = 2 var _viewport: Viewport = preload("./viewport.tscn").instance() var _native_terminal: Control = _viewport.get_node("Terminal") var _screen := TextureRect.new() var _visibility_notifier := VisibilityNotifier2D.new() +var _dirty := false + +var buffer := StreamPeerBuffer.new() + +var times = 0 func set_update_mode(value): @@ -31,16 +36,22 @@ func set_update_mode(value): func get_rows() -> int: - return _native_terminal.rows + return 0 func get_cols() -> int: - return _native_terminal.cols + return 0 func write(data) -> void: assert(data is String or data is PoolByteArray) - _native_terminal.write(data) + + # FIXME: This will occasionally cause a "Resumed function after yield, but class instance is gone" error after freeing the Terminal instance. + # However, this yield is necessary to ensure the terminal state machines framebuffer is up to date when we make all the draw_* calls. + yield(VisualServer, "frame_pre_draw") + + _native_terminal.write(data if data is String else data.get_string_from_utf8()) + _native_terminal.update() func _ready(): @@ -96,4 +107,13 @@ func _on_key_pressed(data: String, event: InputEventKey): func _on_size_changed(new_size: Vector2): + cols = new_size.x + rows = new_size.y emit_signal("size_changed", new_size) + + +func _set_size_warning(value): + if value: + push_warning( + "Terminal cols and rows are read only and determined by the font and rect sizes." + )