75 lines
2.3 KiB
Rust
75 lines
2.3 KiB
Rust
use oc2r_core::{DEFAULT_DEVICE_PATH, DeviceBus, EventLoop, JsonValueExt, Result};
|
|
use opencomputers::RedstoneInterface;
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
use std::time::Duration;
|
|
|
|
static RUNNING: AtomicBool = AtomicBool::new(true);
|
|
|
|
fn main() -> Result<()> {
|
|
install_ctrl_c_handler()?;
|
|
|
|
let mut bus = DeviceBus::connect(DEFAULT_DEVICE_PATH)?;
|
|
let mut redstone = RedstoneInterface::attach(&mut bus)?.expect("no redstone interface");
|
|
|
|
while redstone.try_event()?.is_some() {}
|
|
|
|
redstone.subscribe()?;
|
|
drop(redstone);
|
|
|
|
let mut events = EventLoop::new(&mut bus);
|
|
|
|
println!("Listening for redstone events. Press Ctrl+C to exit.");
|
|
while RUNNING.load(Ordering::SeqCst) {
|
|
let Some(signal) = events.pull_filtered(Some(Duration::from_millis(250)), |signal| {
|
|
signal.name() == "redstone"
|
|
})?
|
|
else {
|
|
continue;
|
|
};
|
|
|
|
let args = signal.args();
|
|
let device_id = args
|
|
.first()
|
|
.cloned()
|
|
.and_then(|value| value.into_string("redstone device").ok())
|
|
.unwrap_or_else(|| "<unknown>".into());
|
|
let side = args
|
|
.get(1)
|
|
.cloned()
|
|
.and_then(|value| value.into_string("redstone side").ok())
|
|
.unwrap_or_else(|| "?".into());
|
|
let level = args
|
|
.get(2)
|
|
.cloned()
|
|
.and_then(|value| value.into_i64("redstone level").ok())
|
|
.unwrap_or(-1);
|
|
println!("{device_id} {side} -> {level}");
|
|
}
|
|
|
|
while events.pull_timeout(Duration::from_millis(0))?.is_some() {}
|
|
|
|
let mut redstone = RedstoneInterface::attach(&mut bus)?.expect("redstone interface detached");
|
|
while redstone.try_event()?.is_some() {}
|
|
redstone.unsubscribe()?;
|
|
|
|
println!("Exited cleanly.");
|
|
Ok(())
|
|
}
|
|
|
|
fn install_ctrl_c_handler() -> Result<()> {
|
|
unsafe {
|
|
let mut action: libc::sigaction = std::mem::zeroed();
|
|
action.sa_flags = libc::SA_RESTART;
|
|
action.sa_sigaction = handle_sigint as usize;
|
|
libc::sigemptyset(&raw mut action.sa_mask);
|
|
if libc::sigaction(libc::SIGINT, &raw const action, std::ptr::null_mut()) != 0 {
|
|
return Err(std::io::Error::last_os_error().into());
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
extern "C" fn handle_sigint(_: libc::c_int) {
|
|
RUNNING.store(false, Ordering::SeqCst);
|
|
}
|