use std::ptr;
use crate::c_error;
use crate::ode::OdeWrapper;
use crate::ode_c::parse_ode_new_common_args;
use crate::ode_callbacks::{
CallbackScalar, DiffsolOdeCallbacksF32, DiffsolOdeCallbacksF64, OdeCallbacksDesc,
};
unsafe fn new_callbacks<T: CallbackScalar>(
callbacks: *const OdeCallbacksDesc<T>,
matrix_type: i32,
linear_solver: i32,
ode_solver: i32,
nbatch: usize,
) -> *mut OdeWrapper {
if callbacks.is_null() {
crate::c_invalid_arg!("callbacks is null");
return ptr::null_mut();
}
let callbacks = unsafe { *callbacks };
let Some((matrix_type, linear_solver, ode_solver)) =
parse_ode_new_common_args(matrix_type, linear_solver, ode_solver)
else {
unsafe { callbacks.free_user_data() };
return ptr::null_mut();
};
if let Err(message) = callbacks.check_nbatch(nbatch) {
crate::c_invalid_arg!(&message);
unsafe { callbacks.free_user_data() };
return ptr::null_mut();
}
let ode = unsafe {
OdeWrapper::new_callbacks(callbacks, matrix_type, linear_solver, ode_solver, nbatch)
};
match ode {
Ok(ode) => Box::into_raw(Box::new(ode)),
Err(err) => {
c_error!(&format!("{}", err));
ptr::null_mut()
}
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn diffsol_ode_new_callbacks_f64(
callbacks: *const DiffsolOdeCallbacksF64,
matrix_type: i32,
linear_solver: i32,
ode_solver: i32,
nbatch: usize,
) -> *mut OdeWrapper {
unsafe { new_callbacks(callbacks, matrix_type, linear_solver, ode_solver, nbatch) }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn diffsol_ode_new_callbacks_f32(
callbacks: *const DiffsolOdeCallbacksF32,
matrix_type: i32,
linear_solver: i32,
ode_solver: i32,
nbatch: usize,
) -> *mut OdeWrapper {
unsafe { new_callbacks(callbacks, matrix_type, linear_solver, ode_solver, nbatch) }
}