diff options
| author | Julian Hurst <ark@mansus.space> | 2024-09-12 12:00:51 +0200 |
|---|---|---|
| committer | Julian Hurst <ark@mansus.space> | 2024-09-12 12:00:51 +0200 |
| commit | 7f4f36b214b23bee44b80574ec08f54c3723982d (patch) | |
| tree | 4348548c6f4a024bf52e04f5bd7f57117da43045 | |
| parent | b3ddfa2345dcb4def08fd6c35e23e43db414415f (diff) | |
| download | ilhare-7f4f36b214b23bee44b80574ec08f54c3723982d.tar.gz | |
Use hare-ev to handle the event loop
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | main.ha | 142 |
2 files changed, 74 insertions, 70 deletions
@@ -1,6 +1,6 @@ # Building -To build il(hare) you must first install [hare](https://harelang.org) and [hare-libtui](https://git.sr.ht/~ark/hare-libtui) then run: +To build il(hare) you must first install [hare](https://harelang.org), [hare-libtui](https://git.sr.ht/~ark/hare-libtui) and [hare-ev](https://git.sr.ht/~sircmpwn/hare-ev) then run: ``` hare build -o il . @@ -12,6 +12,7 @@ use unix::signal; use unix::poll; use errors; use getopt; +use ev; let searchterm: str = ""; let searchforward: bool = true; @@ -42,6 +43,60 @@ fn resize(list: *list::listwidget) void = { list::resize(list, oldsz); }; +fn handle_signal(file: *ev::file, sig: signal::sig) void = { + if (sig == signal::sig::WINCH) { + let l = ev::getuser(file): *list::listwidget; + resize(l); + }; +}; + +type state = struct { + ui: *libtui::ttyui, + l: *list::listwidget, + layout: libtui::layout::layout, +}; + +fn handle_ui(file: *ev::file) void = { + let st = ev::getuser(file): *state; + let r = match (libtui::scan(*st.ui)) { + case let r: rune => + yield r; + case utf8::invalid => + fmt::fprintln(os::stderr, "Invalid utf8 sequence")!; + ev::stop(ev::getloop(file)); + return; + case io::EOF => + fmt::fprintln(os::stderr, "EOF")!; + ev::stop(ev::getloop(file)); + return; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + ev::stop(ev::getloop(file)); + return; + }; + if (libtui::notify(st.ui, r)) { + ev::stop(ev::getloop(file)); + }; + if (list::notify(st.l, r)) { + ev::stop(ev::getloop(file)); + }; +}; + +fn handle_print(loop: *ev::loop, user: nullable *opaque) void = { + let st = user: *state; + libtui::doclear(&st.l.widget.ui); + match (layout::print(st.layout)) { + case void => + yield; + case let e: io::error => + fmt::fprintln(os::stderr, io::strerror(e))!; + ev::stop(loop); + case let e: tty::error => + fmt::fprintln(os::stderr, tty::strerror(e))!; + ev::stop(loop); + }; +}; + export fn main() void = { const cmd = getopt::parse(os::args, "interactive list", @@ -103,79 +158,28 @@ export fn main() void = { //defer free(searchterm); //libtui::clear(l.widget.ui); - signal::block(signal::sig::WINCH); - let sfd = match (signal::signalfd(signal::sig::WINCH)) { - case let sfd: io::file => - yield sfd; - case let e: errors::error => - fmt::fatal(errors::strerror(e)); + let loop = ev::newloop()!; + defer ev::finish(&loop); + const signal = ev::signal(&loop, &handle_signal, signal::sig::WINCH)!; + defer ev::close(signal); + ev::setuser(signal, &l); + + let st = state { + ui = &ui, + l = &l, + layout = layout, }; - defer io::close(sfd)!; - - const pollfds: [2]poll::pollfd = [poll::pollfd { - fd = ui.f, - events = poll::event::POLLIN, - ... - }, poll::pollfd { - fd = sfd, - events = poll::event::POLLIN, - ... - }]; - - for (true) { - libtui::doclear(&l.widget.ui); - match (layout::print(layout)) { - case void => - yield; - case let e: io::error => - fmt::fatal(io::strerror(e)); - case let e: tty::error => - fmt::fprintln(os::stderr, tty::strerror(e))!; - break; - }; - let nb = match (poll::poll(pollfds, poll::INDEF)) { - case let nb: uint => - yield nb; - case let e: poll::error => - fmt::fprintln(os::stderr, poll::strerror(e))!; - break; - }; - let readin = false; - if (nb == 0) { - continue; - } else { - if (pollfds[0].revents & poll::event::POLLIN != 0) { - readin = true; - }; - if (pollfds[1].revents & poll::event::POLLIN != 0) { - signal::read(pollfds[1].fd)!; - resize(&l); - }; - }; - if (readin) { - let r = match (libtui::scan(ui)) { - case let r: rune => - yield r; - case utf8::invalid => - fmt::fprintln(os::stderr, "Invalid utf8 sequence")!; - break; - case io::EOF => - fmt::fprintln(os::stderr, "EOF")!; - break; - case let e: io::error => - fmt::fprintln(os::stderr, io::strerror(e))!; - break; - }; - if (libtui::notify(&ui, r)) { - break; - }; - if (list::notify(&l, r)) { - break; - }; - }; + let mainf = ev::register(&loop, ui.f, &st)!; + ev::readable(mainf, &handle_ui); + ev::do(&loop, &handle_print, &st); + + for (ev::dispatch(&loop, -1)!) { + ev::do(&loop, &handle_print, &st); + ev::readable(mainf, &handle_ui); }; }; + @fini fn finish() void = { free(searchterm); }; |
