73 lines
2.8 KiB
Markdown
73 lines
2.8 KiB
Markdown
|
# ncurses-poll
|
||
|
|
||
|
## 1. Introduction
|
||
|
|
||
|
This repository contains a simple header, [ncurses-poll.hpp](src/ncurses-poll.hpp). With it, you can perform non-blocking I/O in your ncurses application.
|
||
|
|
||
|
## 2. Features
|
||
|
|
||
|
### 2.1 Multiple instances
|
||
|
|
||
|
Each instance of `ncurses_poll` wraps an ncurses `SCREEN*`. Multiple instances can be handled simultaneously in one thread.
|
||
|
|
||
|
Note that there's no need to call `set_term()` because this is done by the header before callbacks are invoked.
|
||
|
|
||
|
### 2.2 Boost.Asio and coroutines
|
||
|
|
||
|
Asynchronous I/O is achieved using Boost.Asio. Thus, other libraries(e.g. [Beast](https://github.com/boostorg/beast)) which uses Boost.Asio can be easily integrated into your ncurses applications.
|
||
|
|
||
|
Boost.Asio's stackless coroutine is also supported for cleaner and human-friendlier code.
|
||
|
|
||
|
## 3. Documentation
|
||
|
|
||
|
### 3.1 Event loop
|
||
|
|
||
|
An `ncurses_poll` instance must run within a Boost.Asio event loop (aka `io_context`). A const reference to an `io_context` instance should be passed to the constructor.
|
||
|
|
||
|
### 3.2 Session
|
||
|
|
||
|
The `ncurses_poll` class template requires a parameter `Session`, which is the type of session. The session may contain username, permission, or other data concerning a specific connection.
|
||
|
|
||
|
`Session` must be a class with a constructor which accepts a pointer to this `ncurses_poll<session>` class.
|
||
|
|
||
|
To get pointer to current session instance of an `ncurses_poll` instance, call `session()` method.
|
||
|
|
||
|
### 3.2 Async read/write
|
||
|
|
||
|
A read/write operation may block, so we need to determine whether the stream is readable/writable before performing I/O.
|
||
|
|
||
|
The `on_readable` and `on_writable` methods accept a single parameter, the const reference to a callback function. Once the stream is readable/writable, the given callback will be invoked.
|
||
|
|
||
|
The callback function should be of the following type:
|
||
|
|
||
|
```C++
|
||
|
using callback =
|
||
|
std::function<void(const boost::system::error_code&, ncurses_poll*)>;
|
||
|
```
|
||
|
|
||
|
* The first argument of callback is the error code, upon success it yields zero, otherwise it is set to the corresponding errno. You should always handle `error_code` before performing I/O.
|
||
|
* The second argument is the pointer to the `ncurses_poll` instance.
|
||
|
|
||
|
### 3.3 Using coroutines
|
||
|
|
||
|
Boost.Asio's stackless coroutine requires a `boost::asio::coroutine` instance. You can simply use the `coro` property of `ncurses_poll`. For example, in a callback function:
|
||
|
|
||
|
```C++
|
||
|
if (!ec) reenter(poll->coro) for (;;) {
|
||
|
yield poll->on_writable(cb);
|
||
|
// ...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 3.4 Other operations
|
||
|
|
||
|
To get corresponding `io_context` instance, call `get_io_context()` method.
|
||
|
|
||
|
To get `SCREEN` pointer to current ncurses instance, call `screen()` method.
|
||
|
|
||
|
### 3.5 See also
|
||
|
|
||
|
* [Examples](/examples) for using `ncurses_poll`.
|
||
|
* [Ncurses Programming Guide](http://www.cs.ukzn.ac.za/~hughm/os/notes/ncurses.html).
|
||
|
* Boost.Asio [documentation](https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio.html).
|