When trying to process OSDP events, I would like access to additional context like the PD address and vendor code. Right now that's inconvenient, because there's no direct way to access the CP handle from inside the callback. In C/C++, you have to pass the pointer using the callback data, or statically store it in memory. Rust's borrow checking forbids both entirely, requiring events to be stored so the context can be retrieved after the callback.
int event_handler(void *data, int pd, struct osdp_event *event) {
auto cp = reinterpret_cast<ControlPanel*>(data); // This works
struct osdp_pd_id pd_info;
int error = cp.get_pd_id(pd, &pd_info);
return 0;
}
cp.setup(&cp_channel, 1, pd_info);
cp.set_event_callback(event_handler, &cp); // ... but now we cannot move cp anymore
let pd_info = vec! [ PdInfo::new(...), ... ];
let mut cp = ControlPanel::new(pd_info)?;
let events = vec![];
cp.set_event_callback(|pd, event| {
// No way to access cp, it's borrowed. A Refcell does not solve this.
events.push(event); // Only solution is to process events outside callback.
});
loop {
cp.refresh();
cp.send_command(0, OsdpCommand::new(...));
}
I think this problem can be solved by passing const osdp_t *ctx to CP callbacks, and exposing it as &ControlPanel in the Rust crate. This would break existing code, but make the API a lot more convenient. My problem would also be solved by passing additional PD info in the callback, but I think the former is more futureproof and convenient.
If this sounds good, I can get started on a PR. This might be a nice addition for v4.
When trying to process OSDP events, I would like access to additional context like the PD address and vendor code. Right now that's inconvenient, because there's no direct way to access the CP handle from inside the callback. In C/C++, you have to pass the pointer using the callback data, or statically store it in memory. Rust's borrow checking forbids both entirely, requiring events to be stored so the context can be retrieved after the callback.
I think this problem can be solved by passing
const osdp_t *ctxto CP callbacks, and exposing it as&ControlPanelin the Rust crate. This would break existing code, but make the API a lot more convenient. My problem would also be solved by passing additional PD info in the callback, but I think the former is more futureproof and convenient.If this sounds good, I can get started on a PR. This might be a nice addition for v4.