1mod base;
21mod access;
22
23use crate::Result;
24pub use crate::ffi::enums::ParmType;
25pub use crate::ffi::structs::{KeyFrame, ParmInfo};
26use crate::node::{HoudiniNode, NodeHandle, Session};
27pub use base::*;
28use std::fmt::Debug;
29
30#[repr(transparent)]
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub struct ParmHandle(pub crate::ffi::raw::HAPI_ParmId);
34
35#[derive(Debug)]
36pub enum Parameter {
38 Float(FloatParameter),
40 Int(IntParameter),
42 String(StringParameter),
44 Button(IntParameter),
46 Other(BaseParameter),
48}
49
50impl Parameter {
51 pub(crate) fn new(node: NodeHandle, info: ParmInfo) -> Parameter {
52 let wrap = ParmInfoWrap { info, node };
53 match wrap.info.parm_type() {
54 ParmType::Int | ParmType::Toggle | ParmType::Multiparmlist => {
55 Parameter::Int(IntParameter(wrap))
56 }
57 ParmType::Button => Parameter::Button(IntParameter(wrap)),
58 ParmType::Float | ParmType::Color => Parameter::Float(FloatParameter(wrap)),
59 ParmType::String
60 | ParmType::Node
61 | ParmType::PathFile
62 | ParmType::PathFileDir
63 | ParmType::PathFileGeo
64 | ParmType::PathFileImage => Parameter::String(StringParameter(wrap)),
65 _ => Parameter::Other(BaseParameter(wrap)),
66 }
67 }
68
69 pub fn value_as_debug(&self) -> Result<Box<dyn Debug>> {
71 match self {
72 Parameter::Float(parm) => Ok(Box::new(parm.get_array()?)),
73 Parameter::Int(parm) | Parameter::Button(parm) => Ok(Box::new(parm.get_array()?)),
74 Parameter::String(parm) => Ok(Box::new(parm.get_array()?)),
75 Parameter::Other(parm) => Ok(Box::new(parm.0.info.parm_type())),
76 }
77 }
78 #[inline]
80 pub fn info(&self) -> &ParmInfo {
81 &self.base().info
82 }
83
84 #[inline]
86 pub fn name(&self) -> Result<String> {
87 self.info().name()
88 }
89
90 #[inline]
92 pub fn label(&self) -> Result<String> {
93 self.info().label()
94 }
95
96 #[inline]
98 pub fn size(&self) -> i32 {
99 self.info().size()
100 }
101
102 pub fn parent(&self) -> Result<Option<ParmInfo>> {
104 let wrap = self.base();
105 debug_assert!(wrap.info.1.is_valid());
106 match wrap.info.parent_id() {
107 ParmHandle(-1) => Ok(None),
108 handle => {
109 let session = wrap.info.1.clone();
110 let info = crate::ffi::get_parm_info(wrap.node, &session, handle)?;
111 Ok(Some(ParmInfo(info, session, None)))
112 }
113 }
114 }
115
116 pub(crate) fn base(&self) -> &ParmInfoWrap {
117 match self {
118 Parameter::Float(p) => &p.0,
119 Parameter::Int(p) => &p.0,
120 Parameter::Button(p) => &p.0,
121 Parameter::String(p) => &p.0,
122 Parameter::Other(p) => &p.0,
123 }
124 }
125}
126
127impl ParmBaseTrait for Parameter {
128 fn inner(&self) -> &ParmInfoWrap {
129 self.base()
130 }
131
132 fn inner_mut(&mut self) -> &mut ParmInfoWrap {
133 match self {
134 Parameter::Float(p) => &mut p.0,
135 Parameter::Int(p) => &mut p.0,
136 Parameter::Button(p) => &mut p.0,
137 Parameter::String(p) => &mut p.0,
138 Parameter::Other(p) => &mut p.0,
139 }
140 }
141}
142
143impl ParmHandle {
144 pub fn from_name(name: &str, node: &HoudiniNode) -> Result<Self> {
146 debug_assert!(node.is_valid()?);
147 let name = std::ffi::CString::new(name)?;
148 let id = crate::ffi::get_parm_id_from_name(&name, node.handle, &node.session)?;
149 Ok(ParmHandle(id))
150 }
151 pub fn info(&self, node: &HoudiniNode) -> Result<ParmInfo> {
153 debug_assert!(node.is_valid()?);
154 let info = crate::ffi::get_parm_info(node.handle, &node.session, *self)?;
155 Ok(ParmInfo::new(info, node.session.clone(), None))
156 }
157}
158
159impl ParmInfo {
160 pub(crate) fn from_parm_name(name: &str, node: &HoudiniNode) -> Result<Self> {
161 debug_assert!(node.is_valid()?);
162 let name = std::ffi::CString::new(name)?;
163 let info = crate::ffi::get_parm_info_from_name(node.handle, &node.session, &name);
164 info.map(|info| ParmInfo::new(info, node.session.clone(), Some(name)))
165 }
166
167 pub(crate) fn from_parm_handle(
168 parm: ParmHandle,
169 node: NodeHandle,
170 session: &Session,
171 ) -> Result<Self> {
172 let parm_info = crate::ffi::get_parm_info(node, session, parm)?;
173 Ok(ParmInfo::new(parm_info, session.clone(), None))
174 }
175}