hapi_rs/parameter/
base.rs1use crate::Result;
2use crate::ffi::enums::ChoiceListType;
3use crate::ffi::{KeyFrame, ParmChoiceInfo, ParmInfo};
4use crate::node::{NodeHandle, ParmType};
5use crate::session::Session;
6use std::borrow::Cow;
7use std::ffi::{CStr, CString};
8
9use super::Parameter;
10
11pub trait ParmBaseTrait {
13 #[inline]
14 fn name(&self) -> Result<Cow<'_, str>> {
15 let inner = self.inner();
16 match inner.info.2.as_ref() {
17 None => inner.info.name().map(Cow::Owned),
18 Some(c_name) => Ok(c_name.to_string_lossy()),
19 }
20 }
21
22 #[inline]
23 fn session(&self) -> &Session {
24 &self.info().1
25 }
26
27 #[inline]
28 fn node(&self) -> NodeHandle {
29 self.inner().node
30 }
31
32 #[inline]
33 fn size(&self) -> i32 {
34 self.info().size()
35 }
36
37 #[inline]
38 fn info(&self) -> &ParmInfo {
39 &self.inner().info
40 }
41
42 fn update(&mut self) -> Result<()> {
45 let inner = self.inner_mut();
46 let name = inner.info.2.take();
47 let mut info = ParmInfo::from_parm_handle(inner.info.id(), inner.node, &inner.info.1)?;
48 info.2 = name;
49 inner.info = info;
50 Ok(())
51 }
52
53 #[inline]
55 fn is_menu(&self) -> bool {
56 !matches!(self.info().choice_list_type(), ChoiceListType::None)
57 }
58 fn menu_items(&self) -> Result<Option<Vec<ParmChoiceInfo>>> {
60 if !self.is_menu() {
61 return Ok(None);
62 }
63 let inner = self.inner();
64 debug_assert!(inner.info.1.is_valid());
65 if inner.info.choice_count() == 0 {
66 return Ok(Some(Vec::new()));
67 }
68 let parms = crate::ffi::get_parm_choice_list(
69 inner.node,
70 &inner.info.1,
71 inner.info.choice_index(),
72 inner.info.choice_count(),
73 );
74 let parms = parms.map(|v| {
75 use std::ops::Deref;
76
77 v.into_iter()
78 .map(|p| ParmChoiceInfo(p, inner.info.1.deref().clone()))
79 .collect::<Vec<ParmChoiceInfo>>()
80 })?;
81 Ok(Some(parms))
82 }
83
84 fn multiparm_children(&self) -> Result<Option<Vec<Parameter>>> {
88 let inner = self.inner();
89 if inner.info.parm_type() != ParmType::Multiparmlist {
90 return Ok(None);
91 }
92 let node = inner.node.to_node(&inner.info.1)?;
93 let mut all_parameters = node.parameters()?;
94 all_parameters.retain(|parm| {
95 parm.info().is_child_of_multi_parm() && parm.info().parent_id() == inner.info.id()
96 });
97
98 Ok(Some(all_parameters))
99 }
100
101 fn insert_multiparm_instance(&self, position: i32) -> Result<()> {
102 let ParmInfoWrap { info, node } = self.inner();
103 crate::ffi::insert_multiparm_instance(&info.1, *node, info.id(), position)
104 }
105
106 fn remove_multiparm_instance(&self, position: i32) -> Result<()> {
107 let ParmInfoWrap { info, node } = self.inner();
108 crate::ffi::remove_multiparm_instance(&info.1, *node, info.id(), position)
109 }
110
111 fn expression(&self, index: i32) -> Result<Option<String>> {
113 let inner = self.inner();
114 debug_assert!(inner.info.1.is_valid());
115 let name = self.c_name()?;
116 let expr_string = crate::ffi::get_parm_expression(inner.node, &inner.info.1, &name, index)?;
117 Ok(if expr_string.is_empty() {
118 None
119 } else {
120 Some(expr_string)
121 })
122 }
123
124 fn has_expression(&self, index: i32) -> Result<bool> {
126 let inner = self.inner();
127 debug_assert!(inner.info.1.is_valid());
128 let name = self.c_name()?;
129 crate::ffi::parm_has_expression(inner.node, &inner.info.1, &name, index)
130 }
131
132 fn set_expression(&self, value: &str, index: i32) -> Result<()> {
134 let inner = self.inner();
135 debug_assert!(inner.info.1.is_valid());
136 let value = CString::new(value)?;
137 crate::ffi::set_parm_expression(inner.node, &inner.info.1, inner.info.id(), &value, index)
138 }
139
140 fn remove_expression(&self, index: i32) -> Result<()> {
142 let inner = self.inner();
143 debug_assert!(inner.info.1.is_valid());
144 crate::ffi::remove_parm_expression(inner.node, &inner.info.1, inner.info.id(), index)
145 }
146
147 fn revert_to_default(&self, index: Option<i32>) -> Result<()> {
149 let inner = self.inner();
150 crate::ffi::revert_parameter_to_default(inner.node, &inner.info.1, &self.c_name()?, index)
151 }
152
153 fn set_anim_curve(&self, index: i32, keys: &[KeyFrame]) -> Result<()> {
155 let inner = self.inner();
156 debug_assert!(inner.info.1.is_valid());
157 let keys = unsafe {
159 &*(std::ptr::from_ref::<[crate::ffi::structs::KeyFrame]>(keys)
160 as *const [crate::ffi::raw::HAPI_Keyframe])
161 };
162 crate::ffi::set_parm_anim_curve(&inner.info.1, inner.node, inner.info.id(), index, keys)
163 }
164
165 fn has_tag(&self, tag: &str) -> Result<bool> {
166 let inner = self.inner();
167 let tag = CString::new(tag)?;
168 crate::ffi::parm_has_tag(&inner.info.1, inner.node, inner.info.id(), &tag)
169 }
170
171 fn get_tag_name(&self, tag_index: i32) -> Result<String> {
173 let inner = self.inner();
174 crate::ffi::get_parm_tag_name(&inner.info.1, inner.node, inner.info.id(), tag_index)
175 }
176
177 fn get_tag_value(&self, tag_name: &str) -> Result<String> {
178 let inner = self.inner();
179 let tag = CString::new(tag_name)?;
180 crate::ffi::get_parm_tag_value(&inner.info.1, inner.node, inner.info.id(), &tag)
181 }
182
183 #[doc(hidden)]
184 fn c_name(&self) -> Result<Cow<'_, CStr>> {
187 let inner = self.inner();
188 match inner.info.2.as_deref() {
189 None => inner.info.name_cstr().map(Cow::Owned),
190 Some(name) => Ok(Cow::Borrowed(name)),
191 }
192 }
193 #[doc(hidden)]
194 fn inner(&self) -> &ParmInfoWrap;
195
196 #[doc(hidden)]
197 fn inner_mut(&mut self) -> &mut ParmInfoWrap;
198}
199
200#[derive(Debug)]
201#[doc(hidden)]
202pub struct ParmInfoWrap {
203 pub(crate) info: ParmInfo,
204 pub(crate) node: NodeHandle,
205}
206
207#[derive(Debug)]
208#[doc(hidden)]
209pub struct BaseParameter(pub(crate) ParmInfoWrap);
210
211#[derive(Debug)]
213pub struct FloatParameter(pub(crate) ParmInfoWrap);
214
215#[derive(Debug)]
217pub struct IntParameter(pub(crate) ParmInfoWrap);
218
219#[derive(Debug)]
221pub struct StringParameter(pub(crate) ParmInfoWrap);
222
223impl ParmBaseTrait for FloatParameter {
224 #[inline]
225 #[doc(hidden)]
226 fn inner(&self) -> &ParmInfoWrap {
227 &self.0
228 }
229
230 #[inline]
231 #[doc(hidden)]
232 fn inner_mut(&mut self) -> &mut ParmInfoWrap {
233 &mut self.0
234 }
235}
236
237impl ParmBaseTrait for IntParameter {
238 #[inline]
239 #[doc(hidden)]
240 fn inner(&self) -> &ParmInfoWrap {
241 &self.0
242 }
243
244 #[inline]
245 #[doc(hidden)]
246 fn inner_mut(&mut self) -> &mut ParmInfoWrap {
247 &mut self.0
248 }
249}
250
251impl ParmBaseTrait for StringParameter {
252 #[inline]
253 #[doc(hidden)]
254 fn inner(&self) -> &ParmInfoWrap {
255 &self.0
256 }
257
258 #[inline]
259 #[doc(hidden)]
260 fn inner_mut(&mut self) -> &mut ParmInfoWrap {
261 &mut self.0
262 }
263}