Crystal lang 如何为C库实现事件IO(特别是NCurses)

Crystal lang 如何为C库实现事件IO(特别是NCurses),crystal-lang,Crystal Lang,使用标准输入法时,(获取),处理时间将分配给其他光纤。因此,以下方法是正确的: spawn do puts "Hello!" end gets # This will output Hello! unless input was already buffered 但是,当使用C库读取输入/事件时,处理时间不会分配给光纤。最简单的示例可能是SDL,因为示例中有SDL # Adapted from samples/sdl/fire.cr require "./sdl/sdl" SDL.i

使用标准输入法时,(
获取
),处理时间将分配给其他光纤。因此,以下方法是正确的:

spawn do
  puts "Hello!"
end

gets

# This will output Hello! unless input was already buffered
但是,当使用C库读取输入/事件时,处理时间不会分配给光纤。最简单的示例可能是SDL,因为示例中有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 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
我试着通读源代码,了解evented IO是如何工作的,但我并不真正理解它,也不知道如何重新实现它

到目前为止,我所看到的最好的解决方法就是重写输入函数(例如


如果你用-Dpreview_mt编译它会发生什么?我应该加上这个!我以为现在默认启用了多线程,但我想不是。这绝对是一个很好的解决方法。如果用-Dpreview_mt编译它会发生什么?我应该加上它!我以为现在默认启用了多线程,但我想不是。这绝对是一个很好的解决办法。
# 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
# 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