use crate::ffi::error_codes::ErrorCode;
use crate::ffi::project::{Project, get_simulation, get_simulation_mut};
use crate::model::network::modify::{CurveData, CurveUpdate};
use std::ffi::{CStr, CString};
use std::os::raw::{c_char, c_double, c_int};
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_addcurve(ph: *mut Project, id: *const c_char) -> ErrorCode {
let simulation = get_simulation_mut!(ph);
let c_str = unsafe { CStr::from_ptr(id) };
let curve_id = match c_str.to_str() {
Ok(s) => s,
Err(_) => return ErrorCode::InvalidIdName,
};
let result = simulation.network.add_curve(
curve_id,
&CurveData {
x: vec![1.0],
y: vec![1.0],
},
);
if result.is_err() {
return ErrorCode::DuplicateId;
}
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_getcurveindex(
ph: *mut Project,
id: *const c_char,
out_index: *mut c_int,
) -> ErrorCode {
let simulation = get_simulation!(ph);
let c_str = unsafe { CStr::from_ptr(id) };
let curve_id = match c_str.to_str() {
Ok(s) => s,
Err(_) => return ErrorCode::InvalidIdName,
};
let curve_index = match simulation.network.curve_map.get(curve_id) {
Some(&index) => index,
None => return ErrorCode::UndefinedCurve,
};
unsafe { *out_index = (curve_index + 1) as c_int };
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_getcurveid(
ph: *mut Project,
index: c_int,
out_id: *mut c_char,
) -> ErrorCode {
let simulation = get_simulation!(ph);
let index = index - 1;
let curve_id = match simulation.network.curves.get(index as usize) {
Some(curve) => curve.id.as_ref(),
None => return ErrorCode::UndefinedCurve,
};
let c_str = CString::new(curve_id).unwrap();
unsafe {
std::ptr::copy_nonoverlapping(c_str.as_ptr(), out_id, c_str.as_bytes_with_nul().len());
}
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_setcurveid(
ph: *mut Project,
index: c_int,
id: *const c_char,
) -> ErrorCode {
let simulation = get_simulation_mut!(ph);
let c_str = unsafe { CStr::from_ptr(id) };
let new_curve_id = match c_str.to_str() {
Ok(s) => s,
Err(_) => return ErrorCode::InvalidIdName,
};
let index = index - 1;
let curve = match simulation.network.curves.get_mut(index as usize) {
Some(curve) => curve,
None => return ErrorCode::UndefinedCurve,
};
if simulation.network.curve_map.contains_key(new_curve_id) {
return ErrorCode::DuplicateId;
}
simulation.network.curve_map.remove(&curve.id);
curve.id = new_curve_id.into();
simulation
.network
.curve_map
.insert(new_curve_id.into(), index as usize);
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_getcurvelen(
ph: *mut Project,
index: c_int,
out_count: *mut c_int,
) -> ErrorCode {
let simulation = get_simulation!(ph);
let index = index - 1;
let curve = match simulation.network.curves.get(index as usize) {
Some(curve) => curve,
None => return ErrorCode::UndefinedCurve,
};
let count = curve.x.len();
unsafe { *out_count = count as c_int };
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_getcurvevalue(
ph: *mut Project,
index: c_int,
point_index: c_int,
out_x: *mut c_double,
out_y: *mut c_double,
) -> ErrorCode {
let simulation = get_simulation!(ph);
let index = index - 1;
let curve = match simulation.network.curves.get(index as usize) {
Some(curve) => curve,
None => return ErrorCode::UndefinedCurve,
};
let point_index = (point_index - 1) as usize;
if point_index >= curve.x.len() || curve.x.is_empty() {
return ErrorCode::UndefinedCurve;
}
let x = curve.x[point_index];
let y = curve.y[point_index];
unsafe { *out_x = x as c_double };
unsafe { *out_y = y as c_double };
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_getcurve(
ph: *mut Project,
index: c_int,
out_n_points: *mut c_int,
out_x: *mut *mut c_double,
out_y: *mut *mut c_double,
) -> ErrorCode {
let simulation = get_simulation!(ph);
let index = index - 1;
let curve = match simulation.network.curves.get(index as usize) {
Some(curve) => curve,
None => return ErrorCode::UndefinedCurve,
};
let n_points = curve.x.len();
unsafe { *out_n_points = n_points as c_int };
unsafe { *out_x = curve.x.as_ptr() as *mut c_double };
unsafe { *out_y = curve.y.as_ptr() as *mut c_double };
ErrorCode::Ok
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn EN_setcurve(
ph: *mut Project,
index: c_int,
x: *const c_double,
y: *const c_double,
count: c_int,
) -> ErrorCode {
let simulation = get_simulation_mut!(ph);
let index = index - 1;
let curve_id = match simulation.network.curves.get_mut(index as usize) {
Some(curve) => curve.id.clone(),
None => return ErrorCode::UndefinedCurve,
};
let x = unsafe { std::slice::from_raw_parts(x, count as usize).to_vec() };
let y = unsafe { std::slice::from_raw_parts(y, count as usize).to_vec() };
let result = simulation.network.update_curve(
&curve_id,
&CurveUpdate {
x: Some(x),
y: Some(y),
},
);
if result.is_err() {
return ErrorCode::InvalidParameterCode;
}
ErrorCode::Ok
}