При использовании стандартных методов ввода (gets
,) время обработки предоставляется другим волокнам. Таким образом, следующее работает правильно:
spawn do
puts "Hello!"
end
gets
# This will output Hello! unless input was already buffered
Но при использовании библиотек C для чтения ввода / событий время обработки не передается оптоволокну. Самым простым примером для показа может быть SDL, поскольку в примерах есть привязок .
# Adapted from samples/sdl/fire.cr
require "./sdl/sdl"
SDL.init
SDL.set_video_mode 100, 100, 32, LibSDL::DOUBLEBUF
spawn do
puts "Hello!" # This will never run unless sleep or something built-in is used
end
loop do
SDL.poll_events do |event|
case event.type
when LibSDL::QUIT
SDL.quit
exit
when LibSDL::KEYDOWN
case event.key.key_sym.sym
when LibSDL::Key::ESCAPE, LibSDL::Key::Q
end
end
end
end
Это показывает проблему, но проблема, которую я хочу решить, на самом деле с моим NCurses и Termbox привязок.
# NCurses non-working example
require "ncurses"
NCurses.start
spawn do
NCurses.add_char 110_u8, 0, 0
NCurses.refresh
end
NCurses.get_char # This blocks, but does not allow fibers to be processed
NCurses.end
# Termbox non-working example
require "lib_termbox"
LibTermbox.init
spawn do
LibTermbox.change_cell 0, 0, 110_u32, 0_u16, 0_u16
LibTermbox.present
end
LibTermbox.poll_event(out event) # Again this is blocking but the fiber does not run
LibTermbox.shutdown
Я пытался прочитать исходный код, как работает четный ввод-вывод, но я не совсем понимаю, как это сделать -произвести его.
Лучший обходной путь, который я видел до сих пор, это просто переписать входные функции (например, 2048 sample )
# Example input
spawn do
puts "Hello!" # this works unless input is buffered already
end
STDIN.raw do |io|
buffer = Bytes.new(4)
bytes_read = io.read(buffer)
pp String.new(buffer[0, bytes_read]) # Display some sort of grapheme cluster?
end