#![allow(clippy::missing_safety_doc)]
use super::*;
#[no_mangle]
pub extern "C" fn lmflow_graph_new() -> *mut LMFlowGraph {
guard_val(std::ptr::null_mut(), || {
last_error::set("");
Box::into_raw(Box::new(GraphSlot::default())) as *mut LMFlowGraph
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_free(g: *mut LMFlowGraph) {
guard_val((), || {
if g.is_null() {
return;
}
let slot = Box::from_raw(g as *mut GraphSlot);
if let Some(gr) = &slot.graph {
gr.cancel();
let _ = gr.wait_done();
}
drop(slot);
});
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_init_from_yaml(
g: *mut LMFlowGraph,
yaml: *const c_char,
) -> i32 {
guard(|| {
let Some(slot) = slot_mut(g) else {
return fail(Error::InvalidArg("graph handle is null".into()));
};
if slot.graph.is_some() {
return fail(Error::State("graph already initialized".into()));
}
let Some(text) = cstr(yaml) else {
return fail(Error::InvalidArg("yaml is empty or not UTF-8".into()));
};
match Graph::from_yaml(text) {
Ok(gr) => {
slot.graph = Some(gr);
code::OK
}
Err(e) => fail(e),
}
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_init_from_yaml_file(
g: *mut LMFlowGraph,
path: *const c_char,
) -> i32 {
guard(|| {
let Some(slot) = slot_mut(g) else {
return fail(Error::InvalidArg("graph handle is null".into()));
};
let Some(p) = cstr(path) else {
return fail(Error::InvalidArg("path is null".into()));
};
match Graph::from_yaml_file(p) {
Ok(gr) => {
slot.graph = Some(gr);
code::OK
}
Err(e) => fail(e),
}
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_start(g: *mut LMFlowGraph) -> i32 {
guard(|| with_graph(g, |gr| to_status(gr.start())))
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_reset(g: *mut LMFlowGraph) -> i32 {
guard(|| with_graph(g, |gr| to_status(gr.reset())))
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_set_side_packet(
g: *mut LMFlowGraph,
name: *const c_char,
pkt: LMFlowPacket,
) -> i32 {
guard(|| {
let p = take_packet(pkt);
let Some(n) = cstr(name) else {
return fail(Error::InvalidArg("side packet name is null".into()));
};
with_graph(g, |gr| to_status(gr.set_side_packet(n, p)))
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_cancel(g: *mut LMFlowGraph) {
guard_val((), || {
let _ = with_graph(g, |gr| {
gr.cancel();
code::OK
});
});
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_wait_done(g: *mut LMFlowGraph) -> i32 {
guard(|| with_graph(g, |gr| to_status(gr.wait_done())))
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_wait_done_timeout(g: *mut LMFlowGraph, ms: i64) -> i32 {
guard(|| {
with_graph(g, |gr| {
to_status(gr.wait_done_timeout(std::time::Duration::from_millis(ms.max(0) as u64)))
})
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_wait_until_idle(g: *mut LMFlowGraph) -> i32 {
guard(|| with_graph(g, |gr| to_status(gr.wait_until_idle())))
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_wait_until_idle_timeout(g: *mut LMFlowGraph, ms: i64) -> i32 {
guard(|| {
with_graph(g, |gr| {
to_status(
gr.wait_until_idle_timeout(std::time::Duration::from_millis(ms.max(0) as u64)),
)
})
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_pump_step(g: *mut LMFlowGraph) -> bool {
guard_val(false, || {
let Some(slot) = slot_mut(g) else {
last_error::set("graph handle is null");
return false;
};
let Some(graph) = slot.graph.as_ref() else {
last_error::set("graph not yet initialized");
return false;
};
graph.pump_step()
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_set_wakeup_callback(
g: *mut LMFlowGraph,
cb: Option<unsafe extern "C" fn(*mut c_void)>,
user: *mut c_void,
) -> i32 {
guard(|| {
with_graph(g, |graph| {
if let Some(callback) = cb {
let user = user as usize;
graph.set_wakeup_callback(move || unsafe { callback(user as *mut c_void) });
} else {
graph.clear_wakeup_callback();
}
code::OK
})
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_pause(g: *mut LMFlowGraph) {
guard_val((), || {
if let Some(gr) = graph_of(g) {
gr.pause();
}
});
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_resume(g: *mut LMFlowGraph) {
guard_val((), || {
if let Some(gr) = graph_of(g) {
gr.resume();
}
});
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_last_error(g: *mut LMFlowGraph) -> *const c_char {
guard_val(c"".as_ptr(), || {
match slot_mut(g).and_then(|s| s.graph.as_ref()) {
Some(gr) => gr.inner().shared.error_cstr(),
None => c"".as_ptr(),
}
})
}
#[no_mangle]
pub unsafe extern "C" fn lmflow_graph_state(g: *mut LMFlowGraph) -> i32 {
guard_val(0, || match slot_mut(g).and_then(|s| s.graph.as_ref()) {
Some(gr) => gr.state() as i32,
None => State::Created as i32,
})
}