use serde::{Deserialize, Serialize};
use spring_ai_sys::COMMAND_TO_ID_ENGINE;
use crate::ai_interface::{
callback::{
command::{
command_data::{
path::{
FreePathCommandData, GetApproximateLengthPathCommandData,
GetNextWaypointPathCommandData, InitPathCommandData,
},
CommandData,
},
command_topic::CommandTopic,
},
engine::handle_command,
},
AIInterface,
};
#[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct Path {
ai_id: i32,
path_id: i32,
}
impl AIInterface {
pub fn new_path(
&self,
start_pos: [f32; 3],
end_pos: [f32; 3],
path_type: i32,
goal_radius: f32,
) -> Result<Path, &'static str> {
Path::new(self, start_pos, end_pos, path_type, goal_radius)
}
pub fn path_length(
&self,
start_pos: [f32; 3],
end_pos: [f32; 3],
path_type: i32,
goal_radius: f32,
) -> Result<f32, &'static str> {
let mut command_c_data = GetApproximateLengthPathCommandData {
start_pos,
end_pos,
path_type,
goal_radius,
}
.c_data();
handle_command(
self.ai_id,
COMMAND_TO_ID_ENGINE,
-1,
CommandTopic::PathGetApproximateLength.into(),
&mut command_c_data,
)?;
Ok(command_c_data.ret_approximatePathLength)
}
}
impl Path {
fn new(
ai_interface: &AIInterface,
start_pos: [f32; 3],
end_pos: [f32; 3],
path_type: i32,
goal_radius: f32,
) -> Result<Self, &'static str> {
let mut command_c_data = InitPathCommandData {
start_pos,
end_pos,
path_type,
goal_radius,
}
.c_data();
handle_command(
ai_interface.ai_id,
COMMAND_TO_ID_ENGINE,
-1,
CommandTopic::PathInit.into(),
&mut command_c_data,
)?;
Ok(Self {
ai_id: ai_interface.ai_id,
path_id: command_c_data.ret_pathId,
})
}
pub fn next_waypoint(&self) -> Result<[f32; 3], &'static str> {
let mut command_data = GetNextWaypointPathCommandData {
path_id: self.path_id,
next_waypoint_position: [0.0; 3],
};
handle_command(
self.ai_id,
COMMAND_TO_ID_ENGINE,
-1,
CommandTopic::PathGetNextWaypoint.into(),
&mut command_data.c_data(),
)?;
Ok(command_data.next_waypoint_position)
}
pub fn free_path(self) -> Result<(), &'static str> {
let mut command_data = FreePathCommandData {
path_id: self.path_id,
};
handle_command(
self.ai_id,
COMMAND_TO_ID_ENGINE,
-1,
CommandTopic::PathFree.into(),
&mut command_data.c_data(),
)
}
}