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