4.7 KiB
4.7 KiB
opencomputers
Typed wrappers for the OC2R high-level API based on oc2r-core.
Each module exposes a safe, idiomatic Rust interface for a specific
device class.
Usage Overview
Every wrapper sits on top of Device::call. Typical imports look like:
use oc2r_core::{DeviceBus, Result, DEFAULT_DEVICE_PATH};
use opencomputers::*;
Attach the device before use:
let mut bus = DeviceBus::connect(DEFAULT_DEVICE_PATH)?;
let mut redstone = RedstoneInterface::attach(&mut bus)?
.expect("no redstone interface attached");
redstone.subscribe()?; // unsubscribe() once you are done
Robot
use opencomputers::{Robot, RobotDirection};
let mut robot = Robot::attach(&mut bus)?.expect("no robot available");
println!("energy {}/{}", robot.energy()?, robot.capacity()?);
let selected = robot.slot(None)?;
println!("selected slot {selected}");
if let Some(stack) = robot.stack(None)? {
println!("holding: {stack:?}");
}
if robot.move_blocking(RobotDirection::Forward)? {
println!("stepped forward");
}
robot.turn(RobotDirection::Left)?;
Redstone Interface
use opencomputers::{RedstoneInterface, RedstoneSignal, Side};
redstone.set_output_state(Side::East, true)?;
let input = redstone.input(Side::East)?;
let output = redstone.output(Side::East)?;
redstone.set_output_level(Side::East, 7)?;
if let Some(signal) = redstone.try_event()? {
println!("{} -> {}", signal.side, signal.level);
}
Side implements FromStr so strings like "north" parse safely. Incoming
events surface as RedstoneSignal { side, level }; see
examples/redstone-events.rs for a full event
loop.
Energy Storage
use opencomputers::EnergyStorage;
let mut energy = EnergyStorage::attach(&mut bus)?.expect("no energy storage");
println!("{}/{}", energy.energy_stored()?, energy.max_energy_stored()?);
println!("can_extract: {}", energy.can_extract()?);
println!("can_receive: {}", energy.can_receive()?);
Fluid Handler
use opencomputers::FluidHandler;
let mut fluids = FluidHandler::attach(&mut bus)?.expect("no fluid handler");
let tanks = fluids.tank_count()? as usize;
for tank in 0..tanks {
let capacity = fluids.tank_capacity(tank)?;
let content = fluids.fluid_in_tank(tank)?;
println!("tank {tank}: {content:?}/{capacity}");
}
Item Handler
use opencomputers::ItemHandler;
let mut items = ItemHandler::attach(&mut bus)?.expect("no item handler");
let slots = items.slot_count()? as usize;
for slot in 0..slots {
let stack = items.stack_in_slot(slot)?;
let limit = items.slot_limit(slot)?;
println!("slot {slot}: {stack:?} (limit {limit})");
}
CPU
use opencomputers::Cpu;
let mut cpu = Cpu::attach(&mut bus)?.expect("no cpu card");
println!("frequency {} MHz", cpu.frequency()?);
Sound Card
use opencomputers::SoundCard;
let mut sound = SoundCard::attach(&mut bus)?.expect("no sound card");
sound.play_with_volume_and_pitch("minecraft:block.note_block.harp", 0.8, 1.2)?;
let matches = sound.find("note_block")?;
println!("found {} sound(s)", matches.len());
Block Operations Module
use opencomputers::{BlockOperations, RobotSide};
let mut ops = BlockOperations::attach(&mut bus)?.expect("no block module");
ops.excavate_on(RobotSide::Front)?;
ops.place_on(RobotSide::Down)?;
println!("durability {}", ops.durability()?);
if ops.repair()? {
println!("tool repaired");
}
Inventory Operations Module
use opencomputers::{InventoryOperations, RobotSide};
let mut inv = InventoryOperations::attach(&mut bus)?.expect("no inventory module");
inv.move_items(0, 1, 32)?;
inv.drop_on(16, RobotSide::Front)?;
let taken = inv.take_from_slot_on(0, 8, RobotSide::Up)?;
println!("taken {taken}");
File Import/Export Card
use opencomputers::FileImportExport;
let mut fie = FileImportExport::attach(&mut bus)?.expect("no file card");
fie.reset()?;
fie.begin_export("test.txt")?;
fie.write_export_chunk(b"hello world")?;
fie.finish_export()?;
if fie.request_import()? {
if let Some(info) = fie.begin_import()? {
println!(
"importing {} ({} bytes)",
info.name.unwrap_or_default(),
info.size
);
while let Some(bytes) = fie.read_import_chunk()? {
// write bytes to disk
println!("chunk {} bytes", bytes.len());
}
}
}
Device-specific events remain accessible through Device::next_event or
DeviceBus::next_event_for when you need raw payloads.
Examples
examples/redstone.rs— control redstone IO from the command line.examples/redstone-events.rs— subscribe to redstone change events.