agent_tk/definitions/agent/
capabilities.rs1use std::any::TypeId;
7use std::ops::{Deref, DerefMut};
8
9use crate::{Error, Result};
10
11pub trait CapabilityTrait
15{
16 const IS_UNIQUE: bool;
18 fn to_capability(self) -> Capability;
20}
21
22#[derive(Clone)]
24#[allow(missing_docs)]
25pub enum Capability
26{
27 Move(Move),
28 Acquire(Acquire),
29 Grasp(Grasp),
30}
31
32macro_rules! define_capability {
33 ($type:ident, unique) => {
34 impl CapabilityTrait for $type
35 {
36 const IS_UNIQUE: bool = true;
37 fn to_capability(self) -> Capability
38 {
39 return Capability::$type(self);
40 }
41 }
42 };
43 ($type:ident) => {
44 impl CapabilityTrait for $type
45 {
46 const IS_UNIQUE: bool = false;
47 fn to_capability(self) -> Capability
48 {
49 return Capability::$type(self);
50 }
51 }
52 };
53}
54
55#[derive(Copy, Clone)]
57pub struct Move
58{
59 max_velocity: f32,
60}
61
62impl Move
63{
64 pub fn new(max_velocity: f32) -> Move
66 {
67 Move { max_velocity }
68 }
69 pub fn get_max_velocity(&self) -> f32
71 {
72 self.max_velocity
73 }
74}
75
76define_capability!(Move, unique);
77
78#[derive(Clone)]
81pub struct Acquire {}
82
83impl Default for Acquire
84{
85 fn default() -> Self
86 {
87 Self::new()
88 }
89}
90
91impl Acquire
92{
93 pub fn new() -> Acquire
95 {
96 Acquire {}
97 }
98}
99
100define_capability!(Acquire);
101
102#[derive(Clone)]
104pub struct Grasp {}
105
106define_capability!(Grasp);
107
108#[derive(Default, Clone)]
110pub struct Capabilities(Vec<Capability>);
111
112impl Deref for Capabilities
113{
114 type Target = Vec<Capability>;
115 fn deref(&self) -> &Self::Target
116 {
117 &self.0
118 }
119}
120
121impl DerefMut for Capabilities
122{
123 fn deref_mut(&mut self) -> &mut Self::Target
124 {
125 &mut self.0
126 }
127}
128
129macro_rules! build_capability_getter {
130 ($name:tt, $type:tt) => {
131 pub fn $name(&self) -> Result<$type>
133 {
134 let res = self.0.iter().find_map(|x| match x
135 {
136 Capability::$type(p) => Some(p),
137 _ => None,
138 });
139 if res.is_none()
140 {
141 Err(Error::UnknownCapability(std::any::type_name::<$type>()))
142 }
143 else
144 {
145 Ok(*res.unwrap())
146 }
147 }
148 };
149}
150
151macro_rules! build_capabilities_getter {
152 ($name:tt, $type:tt) => {
153 pub fn $name(&self) -> Result<Vec<$type>>
155 {
156 let res = self
157 .0
158 .iter()
159 .filter_map(|x| match x
160 {
161 Capability::$type(p) => Some(p),
162 _ => None,
163 })
164 .map(|x| x.clone())
165 .collect::<Vec<$type>>();
166 if res.is_empty()
167 {
168 Err(Error::UnknownCapability(std::any::type_name::<$type>()))
169 }
170 else
171 {
172 Ok(res)
173 }
174 }
175 };
176}
177
178impl Capabilities
179{
180 build_capability_getter!(get_move, Move);
181 build_capabilities_getter!(get_acquire, Acquire);
182 pub fn add_capability<T: CapabilityTrait + 'static>(
184 &mut self,
185 t: T,
186 ) -> crate::Result<&mut Capabilities>
187 {
188 if T::IS_UNIQUE
190 {
191 let it = self.0.iter().find(|x| match x
192 {
193 Capability::Move(_) => TypeId::of::<Move>() == TypeId::of::<T>(),
194 Capability::Acquire(_) => TypeId::of::<Acquire>() == TypeId::of::<T>(),
195 Capability::Grasp(_) => TypeId::of::<Grasp>() == TypeId::of::<T>(),
196 });
197 if it.is_none()
198 {
199 self.push(t.to_capability());
200 Ok(self)
201 }
202 else
203 {
204 Err(Error::DuplicateCapability(std::any::type_name::<T>()))
205 }
206 }
207 else
208 {
209 self.push(t.to_capability());
210 Ok(self)
211 }
212 }
213}