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

View file

@ -24,3 +24,4 @@ image = "0.25.5"
libloading = "0.8.6" libloading = "0.8.6"
emath = "0.31.1" emath = "0.31.1"
dashmap = { version = "6.1.0", features = ["serde"] } 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 common::{CamState, ControlPacket, SensorData, TelemetryPacket};
use anyhow::{Context, Ok, Result}; use anyhow::{anyhow, Ok, Result};
use eframe::Storage;
use libloading::{Library, Symbol}; use libloading::{Library, Symbol};
use tokio::{sync::{self, broadcast, mpsc, watch}, task::JoinHandle}; use tokio::{sync::watch, task::JoinHandle};
use crate::storage::StorageManager; use crate::storage::StorageManager;
pub struct AutoConfig {
turn_gain: f32,
auto_fire_distance: f32,
}
#[derive(Clone)] #[derive(Clone)]
pub struct AutoInterface { pub struct AutoInterface {
command_sender: Option<mpsc::Sender<ControlPacket>>, command_sender: watch::Sender<ControlPacket>,
data_receiver: watch::Receiver<TelemetryPacket>, data_receiver: watch::Receiver<TelemetryPacket>,
config: StorageManager, config: StorageManager,
enabled: bool, enabled: Arc<AtomicBool>,
enable_permission: Arc<AtomicBool>,
} }
impl AutoInterface { 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 /// change active command, fails if not in control
pub async fn run_command(&self, command: ControlPacket) -> Result<()> { pub fn run_command(&self, command: ControlPacket) -> Result<()> {
self.command_sender.as_ref().context("no sender")?.send(command).await?; self.command_sender.send(command)?;
Ok(()) Ok(())
} }
pub fn sensor_data(&mut self) -> SensorData { pub fn sensor_data(&mut self) -> SensorData {
@ -39,17 +47,22 @@ impl AutoInterface {
} }
/// disable auto /// 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 /// request auto enable, fails if the driver does not grant it
pub fn enable(&mut self) -> Result<()> { pub fn enable(&mut self) -> Result<()> {
self.enabled = self.command_sender.is_some(); if self.enable_permission.load(Ordering::Acquire) {
Ok(()) 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 { pub fn conf(&self, key: &'static Configurable) -> f32 {
self.config.load(key) self.config.load(key)
} }
fn send_message(&self, message: String) {unimplemented!()}
} }
pub struct Configurable { pub struct Configurable {
@ -118,7 +131,7 @@ impl Auto {
} }
/// entrypoint /// 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 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()) }; let fut = unsafe { func(interface.clone()) };
@ -150,4 +163,3 @@ pub fn get_confs() -> Result<()> {
Ok(()) Ok(())
} }

View file

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