1
Fork 0

slight auto interface api changes

I'm not liking the ControlPacket architecture anymore, I'd like to
switch to a state-based controller from message-based to accommodate
reliably getting side changes to work
This commit is contained in:
Andy Killorin 2025-03-26 22:29:09 -04:00
parent b63986711d
commit 9f4b2e57a2
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
4 changed files with 110 additions and 37 deletions

85
interface/Cargo.lock generated
View file

@ -38,7 +38,7 @@ dependencies = [
"accesskit_consumer",
"atspi-common",
"serde",
"thiserror",
"thiserror 1.0.69",
"zvariant",
]
@ -198,7 +198,7 @@ dependencies = [
"ndk-context",
"ndk-sys 0.6.0+11769913",
"num_enum",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@ -739,7 +739,7 @@ dependencies = [
"polling",
"rustix",
"slab",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@ -1111,6 +1111,27 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "directories"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.59.0",
]
[[package]]
name = "dispatch"
version = "0.2.0"
@ -1247,7 +1268,7 @@ dependencies = [
"epaint",
"log",
"profiling",
"thiserror",
"thiserror 1.0.69",
"type-map",
"web-time",
"wgpu",
@ -2149,6 +2170,7 @@ dependencies = [
"common",
"cpal",
"dashmap",
"directories",
"eframe",
"egui-toast",
"egui_extras",
@ -2204,7 +2226,7 @@ dependencies = [
"combine",
"jni-sys",
"log",
"thiserror",
"thiserror 1.0.69",
"walkdir",
"windows-sys 0.45.0",
]
@ -2476,7 +2498,7 @@ dependencies = [
"rustc-hash",
"spirv",
"termcolor",
"thiserror",
"thiserror 1.0.69",
"unicode-xid",
]
@ -2506,7 +2528,7 @@ dependencies = [
"log",
"ndk-sys 0.5.0+25.2.9519653",
"num_enum",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@ -2521,7 +2543,7 @@ dependencies = [
"ndk-sys 0.6.0+11769913",
"num_enum",
"raw-window-handle",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@ -2920,6 +2942,12 @@ version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "orbclient"
version = "0.3.48"
@ -3246,7 +3274,7 @@ dependencies = [
"rand_chacha",
"simd_helpers",
"system-deps",
"thiserror",
"thiserror 1.0.69",
"v_frame",
"wasm-bindgen",
]
@ -3310,6 +3338,17 @@ dependencies = [
"bitflags 2.8.0",
]
[[package]]
name = "redox_users"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
"getrandom 0.2.15",
"libredox",
"thiserror 2.0.12",
]
[[package]]
name = "regex"
version = "1.11.1"
@ -3601,7 +3640,7 @@ dependencies = [
"log",
"memmap2",
"rustix",
"thiserror",
"thiserror 1.0.69",
"wayland-backend",
"wayland-client",
"wayland-csd-frame",
@ -3798,7 +3837,16 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl 2.0.12",
]
[[package]]
@ -3812,6 +3860,17 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]]
name = "tiff"
version = "0.9.1"
@ -4369,7 +4428,7 @@ dependencies = [
"raw-window-handle",
"rustc-hash",
"smallvec",
"thiserror",
"thiserror 1.0.69",
"wgpu-hal",
"wgpu-types",
]
@ -4407,7 +4466,7 @@ dependencies = [
"renderdoc-sys",
"rustc-hash",
"smallvec",
"thiserror",
"thiserror 1.0.69",
"wasm-bindgen",
"web-sys",
"wgpu-types",

View file

@ -24,3 +24,4 @@ image = "0.25.5"
libloading = "0.8.6"
emath = "0.31.1"
dashmap = { version = "6.1.0", features = ["serde"] }
directories = "6.0.0"

View file

@ -1,30 +1,38 @@
use std::{collections::VecDeque, future::Future, ops::{Deref, Div, Index, Range, Sub}, pin::Pin, sync::Arc};
use std::{future::Future, ops::{Deref, Range}, pin::Pin, sync::{atomic::{AtomicBool, Ordering}, Arc}};
use common::{CamState, ControlPacket, SensorData, TelemetryPacket};
use anyhow::{Context, Ok, Result};
use eframe::Storage;
use anyhow::{anyhow, Ok, Result};
use libloading::{Library, Symbol};
use tokio::{sync::{self, broadcast, mpsc, watch}, task::JoinHandle};
use tokio::{sync::watch, task::JoinHandle};
use crate::storage::StorageManager;
pub struct AutoConfig {
turn_gain: f32,
auto_fire_distance: f32,
}
#[derive(Clone)]
pub struct AutoInterface {
command_sender: Option<mpsc::Sender<ControlPacket>>,
command_sender: watch::Sender<ControlPacket>,
data_receiver: watch::Receiver<TelemetryPacket>,
config: StorageManager,
enabled: bool,
enabled: Arc<AtomicBool>,
enable_permission: Arc<AtomicBool>,
}
impl AutoInterface {
pub(crate) fn new(data: watch::Receiver<TelemetryPacket>, config: StorageManager, enable_permission: Arc<AtomicBool>) -> (Self, watch::Receiver<ControlPacket>) {
let (commands, receiver) = watch::channel(ControlPacket::Fire);
let interface = Self {
command_sender: commands,
data_receiver: data,
config,
enabled: Arc::new(AtomicBool::new(false)),
enable_permission,
};
(interface, receiver)
}
/// change active command, fails if not in control
pub async fn run_command(&self, command: ControlPacket) -> Result<()> {
self.command_sender.as_ref().context("no sender")?.send(command).await?;
pub fn run_command(&self, command: ControlPacket) -> Result<()> {
self.command_sender.send(command)?;
Ok(())
}
pub fn sensor_data(&mut self) -> SensorData {
@ -39,17 +47,22 @@ impl AutoInterface {
}
/// disable auto
pub fn disable(&self) {unimplemented!()}
pub fn disable(&mut self) {
self.enabled.store(false, Ordering::Release);
}
/// request auto enable, fails if the driver does not grant it
pub fn enable(&mut self) -> Result<()> {
self.enabled = self.command_sender.is_some();
if self.enable_permission.load(Ordering::Acquire) {
self.enabled.store(true, Ordering::Release);
Ok(())
} else {
Err(anyhow!("no enable"))?
}
pub fn enabled(&self) -> bool { self.enabled}
}
pub fn enabled(&self) -> bool { self.enabled.load(Ordering::Acquire) }
pub fn conf(&self, key: &'static Configurable) -> f32 {
self.config.load(key)
}
fn send_message(&self, message: String) {unimplemented!()}
}
pub struct Configurable {
@ -118,7 +131,7 @@ impl Auto {
}
/// entrypoint
pub async fn run(&self, interface: &AutoInterface) -> Result<JoinHandle<()>> {
pub async fn run(&self, interface: AutoInterface) -> Result<JoinHandle<()>> {
let func: Symbol<unsafe extern "C" fn(AutoInterface) -> Pin<Box<dyn Future<Output = ()> + Send>>> = unsafe {self.library.get(b"entry")?};
let fut = unsafe { func(interface.clone()) };
@ -150,4 +163,3 @@ pub fn get_confs() -> Result<()> {
Ok(())
}

View file

@ -2,7 +2,8 @@ use std::{fmt::format, ops::ControlFlow, result, sync::{atomic::Ordering, Arc},
use anyhow::{Context, Ok, Result};
use atomic_float::AtomicF32;
use interface::{auto::{get_confs, Auto}, combatlog::{combat_logger, CombatData}, POWER_THRESHOLD};
use directories::ProjectDirs;
use interface::{auto::{get_confs, Auto}, combatlog::{combat_logger, CombatData}, storage::StorageManager, POWER_THRESHOLD};
use common::{ControlPacket, TelemetryPacket};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use egui_toast::{Toast, ToastKind};
@ -13,8 +14,11 @@ use tokio::{io::{AsyncReadExt, AsyncWriteExt, BufWriter, WriteHalf}, net::{tcp::
fn main() -> Result<()> {
let directories = ProjectDirs::from("dev", "ank", "Cruise Control").context("no home")?;
let auto = Auto::new("../auto/target/release/libauto.so")?;
let storage = StorageManager::new(directories.config_dir().with_file_name("conf.dat"))?;
println!("name: {}", auto.name());
for config in auto.configs().iter() {
@ -22,9 +26,6 @@ fn main() -> Result<()> {
println!("co {:?}", config.description);
}
let (logging_sender, combatlog) = mpsc::channel(64);
// assumes pulseaudio system with f32 samples and 2204 sample packets