2 unstable releases
0.2.0 | Nov 4, 2019 |
---|---|
0.1.1 | Oct 15, 2019 |
0.1.0 |
|
#583 in Text processing
280KB
6.5K
SLoC
glk-rs
This crate provides bindings to implement the Glk I/O interface for hosting interactive fiction interpreters. This standard is used by, for example, the glulxe interpreter.
It exports the C functions, rust traits and a dummy implementation. It is up to the user of this crate to provide actual implementations for the Glk functions that the interpreter will invoke.
Note
This crate currently only has the capability to provide a Glk library.
When implementing an interpreter or other Glk application it would be useful to use a Glk library, this is currently not possible with this crate, though it could likely share some of the traits, utility code, or constants at least.
How to use
Implement the trait glk::traits::Api
and Glk traits (at least Base
, which
handles the base functionality; every Glk module is handled by a separate
trait) on a structure with handlers, then call glk::init(…)
to register the
handlers.
/** Dispatch trait for all Glk APIs. Each function returns a
* reference to a trait which will be called for functions on the associated
* Glk module.
*/
pub trait Api {
/** Mandatory Glk API functions. */
fn base(&mut self) -> &mut dyn Base;
/** GLK_MODULE_LINE_ECHO */
fn line_echo(&mut self) -> Option<&mut dyn LineEcho>;
/** GLK_MODULE_LINE_TERMINATORS */
fn line_terminators(&mut self) -> Option<&mut dyn LineTerminators>;
/** GLK_MODULE_UNICODE */
fn unicode(&mut self) -> Option<&mut dyn Unicode>;
/** GLK_MODULE_UNICODE_NORM */
fn unicode_norm(&mut self) -> Option<&mut dyn UnicodeNorm>;
/** GLK_MODULE_IMAGE */
fn image(&mut self) -> Option<&mut dyn Image>;
/** GLK_MODULE_SOUND */
fn sound(&mut self) -> Option<&mut dyn Sound>;
/** GLK_MODULE_SOUND2 */
fn sound2(&mut self) -> Option<&mut dyn Sound2>;
/** GLK_MODULE_HYPERLINKS */
fn hyperlinks(&mut self) -> Option<&mut dyn Hyperlinks>;
/** GLK_MODULE_DATETIME */
fn date_time(&mut self) -> Option<&mut dyn Datetime>;
/** GLK_MODULE_RESOURCE_STREAM */
fn resource_stream(&mut self) -> Option<&mut dyn ResourceStream>;
/** GLK_MODULE_GARGLKTEXT */
fn garglk_text(&mut self) -> Option<&mut dyn garglk::GarGlkText>;
/** GI blorb handler functions */
fn giblorb(&mut self) -> Option<&mut dyn giblorb::Handlers>;
/** GI dispatch handler functions */
fn gidispatch(&mut self) -> Option<&mut dyn gidispatch::Handlers>;
/** Rust Glk extension handler functions */
fn ext(&mut self) -> Option<&mut dyn ext::Handlers>;
}
These functions could return Some(self)
, or delegate to a different object that
implements the given trait. Or return None
if the module is left unimplemented.
Then link your application to whatever needs the glk_
API.
Note that the handlers registered with glk::init
are local to a thread, so
make sure to call the interpreter from the same thread that registers the glk
API handlers. Glk only supports single-threaded interpreters.
Example: Toyglk
A basic demo Glk implementation, using crossterm as terminal backend. It hosts
the Glulxe interpreter using the glulxe
crate.
- Aims to be a complete implementation of the Glk standard, including the Unicode extension.
- Only supports one window: the entire terminal.
- Line and character (also special keycodes) input.
- Saving and restoring works.
- Supports Glk styling and GarGlkText RGB colors.
Several of my favorites stories like Blue Lacuna and Counterfeit Monkey work. e.g.
$ cargo run --release --example toyglk CounterfeitMonkey.gblorb
...
Can you hear me? >> yes
Good, you're conscious. We're conscious. I've heard urban legends about
synthesis going wrong, one half person getting lost.
Glk types
glui32
is directly mapped to u32
, and glsi32
to i32
.
The opaque handle types (frefid_t
, schanid_t
, strid_t
, winid_t
) are
represented as opaque types that can be cast from and to usize
(or a pointer,
if you're living dangerously).
Struct types event_t
, glkdate_t
, glktimeval_t
, stream_result_t
are
provided as C-compatible structs.
Convenience types have been defined for gestalts, event types, keycodes and
such. These are newtypes that wrap a u32
, not enums, to leave room for
extensions (or ad-hoc need) to pass new values.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
(note that the inner crate, glk-sys
is licensed under a MIT license only,
because it is based on files from glk which are licensed such)
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~0–2MB
~40K SLoC