use crate::{BAD_HANDLE, arg, with};
use kevy_embedded::PubsubFrame;
pub const EVENT_MESSAGE: u8 = 1;
pub const EVENT_PMESSAGE: u8 = 2;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn kevy_subscribe(h: u32, cp: *const u8, cl: u32) -> u32 {
let channel = unsafe { arg(cp, cl) };
with(h, 0, |inst| {
let sub = inst.store.subscribe(&[channel]);
let id = inst.next_sub;
inst.next_sub += 1;
inst.subs.insert(id, sub);
id
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn kevy_psubscribe(h: u32, pp: *const u8, pl: u32) -> u32 {
let pattern = unsafe { arg(pp, pl) };
with(h, 0, |inst| {
let sub = inst.store.psubscribe(&[pattern]);
let id = inst.next_sub;
inst.next_sub += 1;
inst.subs.insert(id, sub);
id
})
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_unsubscribe(h: u32, sub: u32) -> i32 {
with(h, BAD_HANDLE, |inst| match inst.subs.remove(&sub) {
Some(_) => crate::OK,
None => BAD_HANDLE,
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn kevy_publish(
h: u32,
cp: *const u8,
cl: u32,
pp: *const u8,
pl: u32,
) -> i32 {
let (channel, payload) = unsafe { (arg(cp, cl), arg(pp, pl)) };
with(h, BAD_HANDLE, |inst| inst.store.publish(channel, payload) as i32)
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_poll_events(h: u32) -> i32 {
with(h, BAD_HANDLE, |inst| {
inst.out.clear();
let crate::Instance { subs, out, .. } = inst;
let mut count = 0i32;
for (id, sub) in subs.iter() {
while let Ok(Some(frame)) = sub.try_recv() {
match frame {
PubsubFrame::Message { channel, payload } => {
pack_event(out, EVENT_MESSAGE, *id, &[], &channel, &payload);
count += 1;
}
PubsubFrame::Pmessage { pattern, channel, payload } => {
pack_event(out, EVENT_PMESSAGE, *id, &pattern, &channel, &payload);
count += 1;
}
_ => {}
}
}
}
count
})
}
fn pack_event(out: &mut Vec<u8>, kind: u8, sub: u32, a: &[u8], b: &[u8], c: &[u8]) {
out.push(kind);
out.extend_from_slice(&sub.to_le_bytes());
for seg in [a, b, c] {
out.extend_from_slice(&(seg.len() as u32).to_le_bytes());
out.extend_from_slice(seg);
}
}