spring_ai_rs/ai_interface/callback/
path.rs

1use serde::{Deserialize, Serialize};
2use spring_ai_sys::COMMAND_TO_ID_ENGINE;
3
4use crate::ai_interface::{
5    callback::{
6        command::{
7            command_data::{
8                path::{
9                    FreePathCommandData, GetApproximateLengthPathCommandData,
10                    GetNextWaypointPathCommandData, InitPathCommandData,
11                },
12                CommandData,
13            },
14            command_topic::CommandTopic,
15        },
16        engine::handle_command,
17    },
18    AIInterface,
19};
20
21#[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
22pub struct Path {
23    ai_id: i32,
24    path_id: i32,
25}
26
27impl AIInterface {
28    pub fn new_path(
29        &self,
30        start_pos: [f32; 3],
31        end_pos: [f32; 3],
32        path_type: i32,
33        goal_radius: f32,
34    ) -> Result<Path, &'static str> {
35        Path::new(self, start_pos, end_pos, path_type, goal_radius)
36    }
37
38    pub fn path_length(
39        &self,
40        start_pos: [f32; 3],
41        end_pos: [f32; 3],
42        path_type: i32,
43        goal_radius: f32,
44    ) -> Result<f32, &'static str> {
45        let mut command_c_data = GetApproximateLengthPathCommandData {
46            start_pos,
47            end_pos,
48            path_type,
49            goal_radius,
50        }
51        .c_data();
52
53        handle_command(
54            self.ai_id,
55            COMMAND_TO_ID_ENGINE,
56            -1,
57            CommandTopic::PathGetApproximateLength.into(),
58            &mut command_c_data,
59        )?;
60
61        Ok(command_c_data.ret_approximatePathLength)
62    }
63}
64
65impl Path {
66    fn new(
67        ai_interface: &AIInterface,
68        start_pos: [f32; 3],
69        end_pos: [f32; 3],
70        path_type: i32,
71        goal_radius: f32,
72    ) -> Result<Self, &'static str> {
73        let mut command_c_data = InitPathCommandData {
74            start_pos,
75            end_pos,
76            path_type,
77            goal_radius,
78        }
79        .c_data();
80
81        handle_command(
82            ai_interface.ai_id,
83            COMMAND_TO_ID_ENGINE,
84            -1,
85            CommandTopic::PathInit.into(),
86            &mut command_c_data,
87        )?;
88
89        Ok(Self {
90            ai_id: ai_interface.ai_id,
91            path_id: command_c_data.ret_pathId,
92        })
93    }
94
95    pub fn next_waypoint(&self) -> Result<[f32; 3], &'static str> {
96        let mut command_data = GetNextWaypointPathCommandData {
97            path_id: self.path_id,
98            next_waypoint_position: [0.0; 3],
99        };
100
101        handle_command(
102            self.ai_id,
103            COMMAND_TO_ID_ENGINE,
104            -1,
105            CommandTopic::PathGetNextWaypoint.into(),
106            &mut command_data.c_data(),
107        )?;
108
109        Ok(command_data.next_waypoint_position)
110    }
111
112    pub fn free_path(self) -> Result<(), &'static str> {
113        let mut command_data = FreePathCommandData {
114            path_id: self.path_id,
115        };
116
117        handle_command(
118            self.ai_id,
119            COMMAND_TO_ID_ENGINE,
120            -1,
121            CommandTopic::PathFree.into(),
122            &mut command_data.c_data(),
123        )
124    }
125}