Fix resume after yield error

Fixes error that would sometimes occur when closing the Terminal after
calling write() but before the VisualServer had finished drawing the
current frame.
This commit is contained in:
Leroy Hopson 2022-06-26 21:01:11 +07:00
parent 0ae1d80abb
commit cf613708c4
No known key found for this signature in database
GPG key ID: D2747312A6DB51AA
2 changed files with 19 additions and 5 deletions

View file

@ -33,6 +33,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
closing terminals in the Terminal panel of the editor plugin.
- Fixed leaked instances that would occur when PTY exited but child process was still
running.
- Fixed "Resumed function after yield, but class instance is gone" error that would
sometimes occur when closing a Terminal after calling write() but before VisualServer
had finished drawing the current frame.
## [v2.0.0](https://github.com/lihop/godot-xterm/compare/v1.2.1...v2.0.0) - 2021-07-25

View file

@ -61,6 +61,8 @@ var buffer := StreamPeerBuffer.new()
var times = 0
var _buffer := []
func set_update_mode(value):
update_mode = value
@ -78,12 +80,15 @@ func get_cols() -> int:
func write(data) -> void:
assert(data is String or data is PoolByteArray)
# 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")
# Will be cleared when _flush() is called after VisualServer emits the "frame_pre_draw" signal.
_buffer.push_back(data)
_native_terminal.write(data if data is String else data.get_string_from_utf8())
_native_terminal.update()
func _flush():
for data in _buffer:
_native_terminal.write(data if data is String else data.get_string_from_utf8())
_native_terminal.update()
_buffer.clear()
func clear() -> void:
@ -128,6 +133,12 @@ func _ready():
_refresh()
# Ensure the terminal state machine's framebuffer is up to date before
# we make all the draw_* calls caused by writing. We need to use signals
# here rather than yield otherwise we will sometimes get a "Resumed
# function after yield but class instance is gone" error.
VisualServer.connect("frame_pre_draw", self, "_flush")
func _update_theme():
# Themes are not propagated through the Viewport, so in order for theme