oc_wasm_opencomputers/lib.rs
1//! This crate provides high-level APIs for accessing components provided by
2//! [OpenComputers](https://oc.cil.li) in a vanilla Minecraft environment (e.g. redstone blocks,
3//! GPUs, screens, etc.).
4//!
5//! As a general rule, APIs in this crate accept an `Invoker` and a `Buffer` scratch buffer, the
6//! latter being used for encoding parameters and decoding return values. This buffer can be reused
7//! between API calls to reduce heap allocations. In some cases the return value of an API may
8//! borrow from the scratch buffer.
9//!
10//! # Important
11//! You *must* depend on [`oc-wasm-futures`](https://gitlab.com/Hawk777/oc-wasm-futures) with the
12//! `proper-waker` feature in your own application if your chosen executor requires the
13//! `proper-waker` feature.
14//!
15//! # Example
16//! ```
17//! extern crate alloc;
18//! use alloc::vec::Vec;
19//! use oc_wasm_futures::sleep;
20//! use oc_wasm_opencomputers::prelude::*;
21//! use oc_wasm_opencomputers::{gpu, screen};
22//! use oc_wasm_opencomputers::common::{Dimension, Point};
23//! use oc_wasm_safe::{component, computer};
24//! use core::panic::PanicInfo;
25//!
26//! #[global_allocator]
27//! static ALLOC: lol_alloc::AssumeSingleThreaded<lol_alloc::LeakingAllocator> =
28//! unsafe { lol_alloc::AssumeSingleThreaded::new(lol_alloc::LeakingAllocator::new()) };
29//!
30//! #[panic_handler]
31//! fn panic_hook(_: &PanicInfo<'_>) -> ! {
32//! computer::error("panic occurred");
33//! }
34//!
35//! async fn main_impl() -> Result<(), oc_wasm_opencomputers::error::Error> {
36//! // Grab the one-and-only resources.
37//! let mut invoker = component::Invoker::take().unwrap();
38//! let mut lister = component::Lister::take().unwrap();
39//!
40//! // Find the GPU.
41//! let mut listing = lister.start(Some("gpu"));
42//! let gpu = *listing.next().expect("no GPU").address();
43//! let gpu = gpu::Gpu::new(gpu);
44//!
45//! // Find the screen.
46//! listing = lister.start(Some("screen"));
47//! let screen = *listing.next().expect("no screen").address();
48//! let screen = screen::Screen::new(screen);
49//!
50//! // Allocate a scratch buffer to use for method calls.
51//! let mut buffer = Vec::<u8>::new();
52//!
53//! // Lock the GPU so method calls can be made on it. For gpu_locked’s lifetime, methods can only
54//! // be called on the GPU, not on anything else. To make method calls on another component, drop
55//! // this value and recreate it later.
56//! let mut gpu_locked = gpu.lock(&mut invoker, &mut buffer);
57//!
58//! // Bind the GPU to the screen.
59//! gpu_locked.bind(*screen.address(), true).await?;
60//!
61//! // Clear the screen.
62//! gpu_locked.set_foreground(gpu::Colour::Rgb(gpu::Rgb(0x00_FF_FF_FF))).await?;
63//! gpu_locked.set_background(gpu::Colour::Rgb(gpu::Rgb(0))).await?;
64//! gpu_locked.fill(Point{x: 1, y: 1}, Dimension{width: 160, height: 80}, ' ').await?;
65//!
66//! // Say hello.
67//! gpu_locked.set(Point{x: 1, y: 1}, "Hello World!", gpu::TextDirection::Horizontal).await?;
68//!
69//! // Stop running forever.
70//! loop {
71//! sleep::for_uptime(core::time::Duration::from_secs(3600)).await;
72//! }
73//! }
74//!
75//! async fn main() -> core::convert::Infallible {
76//! match main_impl().await {
77//! Ok(()) => computer::error("main task terminated"),
78//! Err(e) => computer::error(e.as_str()),
79//! }
80//! }
81//!
82//! #[no_mangle]
83//! pub extern "C" fn run(arg: i32) -> i32 {
84//! oc_wasm_cassette::run(arg, async_main)
85//! }
86//! ```
87
88#![cfg_attr(not(feature = "std"), no_std)]
89#![warn(
90 // Turn on extra language lints.
91 future_incompatible,
92 missing_abi,
93 nonstandard_style,
94 rust_2018_idioms,
95 // Disabled due to <https://github.com/rust-lang/rust/issues/69952>.
96 // single_use_lifetimes,
97 trivial_casts,
98 trivial_numeric_casts,
99 unused,
100 unused_crate_dependencies,
101 unused_import_braces,
102 unused_lifetimes,
103 unused_qualifications,
104
105 // Turn on extra Rustdoc lints.
106 rustdoc::all,
107
108 // Turn on extra Clippy lints.
109 clippy::cargo,
110 clippy::pedantic,
111)]
112// I’m not a big fan of this style, and it sometimes generates larger code.
113#![allow(clippy::option_if_let_else)]
114// Nope, tabs thanks.
115#![allow(clippy::tabs_in_doc_comments)]
116
117extern crate alloc;
118
119pub mod common;
120pub mod eeprom;
121pub mod error;
122pub mod filesystem;
123pub mod gpu;
124pub mod inventory;
125pub mod keyboard;
126pub mod modem;
127pub mod prelude;
128pub mod redstone;
129pub mod robot;
130pub mod screen;
131
132mod helpers;