Init
This commit is contained in:
87
src/lib.rs
Normal file
87
src/lib.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use std::{slice, thread};
|
||||
|
||||
use async_channel::{Sender, Receiver, unbounded};
|
||||
use async_io::block_on;
|
||||
use async_lock::{OnceCell, RwLock};
|
||||
|
||||
type Callback = extern "C" fn (ByteArray);
|
||||
|
||||
static CHANNEL: OnceCell<(Sender<Vec<u8>>, Receiver<Vec<u8>>)> = OnceCell::new();
|
||||
static CALLBACK: RwLock<Option<Callback>> = RwLock::new(None);
|
||||
|
||||
fn get_channel() -> &'static (Sender<Vec<u8>>, Receiver<Vec<u8>>) {
|
||||
CHANNEL.get_or_init_blocking(|| {
|
||||
println!("Initialized channel");
|
||||
unbounded()
|
||||
})
|
||||
}
|
||||
|
||||
fn get_sender() -> &'static Sender<Vec<u8>> {
|
||||
&get_channel().0
|
||||
}
|
||||
|
||||
fn get_receiver() -> &'static Receiver<Vec<u8>> {
|
||||
&get_channel().1
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ByteArray {
|
||||
data: *const u8,
|
||||
length: usize
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for ByteArray {
|
||||
fn from(value: Vec<u8>) -> Self {
|
||||
ByteArray { data: value.as_ptr(), length: value.len() }
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn register_callback(cb: Callback) {
|
||||
block_on(async {
|
||||
let mut writer = CALLBACK.write().await;
|
||||
*writer = Some(cb);
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn start_listening() {
|
||||
let receiver = get_receiver().clone();
|
||||
thread::spawn(move|| {
|
||||
block_on(async {
|
||||
println!("Start listening for received events");
|
||||
loop {
|
||||
let next = receiver.recv().await;
|
||||
if let Ok(data) = next {
|
||||
println!("Received data: {:?}", data);
|
||||
let reader = CALLBACK.read().await;
|
||||
if reader.is_some() {
|
||||
println!("Calling callback");
|
||||
let cb = reader.unwrap();
|
||||
let bytes = ByteArray::from(data);
|
||||
cb(bytes);
|
||||
} else {
|
||||
println!("No callback");
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn send(data: *const u8, length: usize) {
|
||||
let byte_slice = unsafe {
|
||||
assert!(!data.is_null());
|
||||
slice::from_raw_parts(data, length)
|
||||
};
|
||||
|
||||
get_sender().send_blocking(byte_slice.to_vec()).unwrap();
|
||||
println!("Received {} bytes, array: {:?}", length, byte_slice);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn receive() -> ByteArray {
|
||||
let data = get_receiver().recv_blocking().unwrap();
|
||||
ByteArray::from(data)
|
||||
}
|
||||
Reference in New Issue
Block a user