1use super::*;
2use std::ffi::{ CStr, CString };
3use ae_sys::PF_PathID;
4use serde::{de::DeserializeOwned, Serialize};
5
6define_enum! {
7 ae_sys::PF_ParamType,
8 ParamType {
9 Reserved = ae_sys::PF_Param_RESERVED,
10 Layer = ae_sys::PF_Param_LAYER,
11 Slider = ae_sys::PF_Param_SLIDER,
12 FixSlider = ae_sys::PF_Param_FIX_SLIDER,
13 Angle = ae_sys::PF_Param_ANGLE,
14 CheckBox = ae_sys::PF_Param_CHECKBOX,
15 Color = ae_sys::PF_Param_COLOR,
16 Point = ae_sys::PF_Param_POINT,
17 PopUp = ae_sys::PF_Param_POPUP,
18 Custom = ae_sys::PF_Param_CUSTOM,
19 NoData = ae_sys::PF_Param_NO_DATA,
20 FloatSlider = ae_sys::PF_Param_FLOAT_SLIDER,
21 ArbitraryData = ae_sys::PF_Param_ARBITRARY_DATA,
22 Path = ae_sys::PF_Param_PATH,
23 GroupStart = ae_sys::PF_Param_GROUP_START,
24 GroupEnd = ae_sys::PF_Param_GROUP_END,
25 Button = ae_sys::PF_Param_BUTTON,
26 Reserved2 = ae_sys::PF_Param_RESERVED2,
27 Reserved3 = ae_sys::PF_Param_RESERVED3,
28 Point3D = ae_sys::PF_Param_POINT_3D,
29 }
30}
31
32bitflags! {
33 pub struct ParamUIFlags: ae_sys::A_long {
34 const NONE = ae_sys::PF_PUI_NONE as ae_sys::A_long;
35 const TOPIC = ae_sys::PF_PUI_TOPIC as ae_sys::A_long;
37 const CONTROL = ae_sys::PF_PUI_CONTROL as ae_sys::A_long;
39 const CONTROL_ONLY = ae_sys::PF_PUI_STD_CONTROL_ONLY as ae_sys::A_long;
41 const NO_ECW_UI = ae_sys::PF_PUI_NO_ECW_UI as ae_sys::A_long;
43 const ECW_SEPARATOR = ae_sys::PF_PUI_ECW_SEPARATOR as ae_sys::A_long;
45 const DISABLED = ae_sys::PF_PUI_DISABLED as ae_sys::A_long;
47 const DO_NOT_ERASE_TOPIC = ae_sys::PF_PUI_DONT_ERASE_TOPIC as ae_sys::A_long;
50 const DO_NOT_ERASE_CONTROL = ae_sys::PF_PUI_DONT_ERASE_CONTROL as ae_sys::A_long;
51 const RADIO_BUTTON = ae_sys::PF_PUI_RADIO_BUTTON as ae_sys::A_long;
53 const INVISIBLE = ae_sys::PF_PUI_INVISIBLE as ae_sys::A_long;
57 }
58}
59
60bitflags! {
61 pub struct ParamFlag: ae_sys::A_long {
62 const CANNOT_TIME_VARY = ae_sys::PF_ParamFlag_CANNOT_TIME_VARY as ae_sys::A_long;
64 const CANNOT_INTERP = ae_sys::PF_ParamFlag_CANNOT_INTERP as ae_sys::A_long;
66 const TWIRLY = ae_sys::PF_ParamFlag_COLLAPSE_TWIRLY as ae_sys::A_long;
71 const SUPERVISE = ae_sys::PF_ParamFlag_SUPERVISE as ae_sys::A_long;
73 const START_COLLAPSED = ae_sys::PF_ParamFlag_START_COLLAPSED as ae_sys::A_long;
78 const USE_VALUE_FOR_OLD_PROJECTS = ae_sys::PF_ParamFlag_USE_VALUE_FOR_OLD_PROJECTS as ae_sys::A_long;
85 const LAYER_PARAM_IS_TRACKMATTE = ae_sys::PF_ParamFlag_LAYER_PARAM_IS_TRACKMATTE as ae_sys::A_long;
87 const EXCLUDE_FROM_HAVE_INPUTS_CHANGED = ae_sys::PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED as ae_sys::A_long;
89 const SKIP_REVEAL_WHEN_UNHIDDEN = ae_sys::PF_ParamFlag_SKIP_REVEAL_WHEN_UNHIDDEN as ae_sys::A_long;
91 }
92}
93
94bitflags! {
95 pub struct ChangeFlag: ae_sys::A_long {
96 const NONE = ae_sys::PF_ChangeFlag_NONE as ae_sys::A_long;
97 const CHANGED_VALUE = ae_sys::PF_ChangeFlag_CHANGED_VALUE as ae_sys::A_long;
104 const SET_TO_VARY = ae_sys::PF_ChangeFlag_SET_TO_VARY as ae_sys::A_long;
106 const SET_TO_CONSTANT = ae_sys::PF_ChangeFlag_SET_TO_CONSTANT as ae_sys::A_long;
108 }
109}
110
111bitflags! {
112 pub struct ValueDisplayFlag: u16 {
113 const NONE = ae_sys::PF_ValueDisplayFlag_NONE as u16;
114 const PERCENT = ae_sys::PF_ValueDisplayFlag_PERCENT as u16;
116 const PIXEL = ae_sys::PF_ValueDisplayFlag_PIXEL as u16;
118 const REVERSE = ae_sys::PF_ValueDisplayFlag_REVERSE as u16;
120 }
121}
122
123bitflags! {
124 pub struct FSliderFlag: u16 {
125 const NONE = ae_sys::PF_FSliderFlag_NONE as u16;
126 const WANT_PHASE = ae_sys::PF_FSliderFlag_WANT_PHASE as u16;
128 }
129}
130
131define_param_wrapper! {
133 PF_Param_ANGLE, PF_AngleDef, ad,
134 Param::Angle,
135 AngleDef { },
136 impl value: Fixed,
137}
138impl AngleDef<'_> {
139 pub fn set_default(&mut self, v: f32) -> &mut Self {
140 self.def.dephault = Fixed::from(v).as_fixed();
141 self
142 }
143 pub fn default(&self) -> f32 {
144 Fixed::from_fixed(self.def.dephault).into()
145 }
146 pub fn float_value(&self) -> Result<f64, Error> {
147 if self._in_data.is_null() || self._parent_ptr.is_none() {
148 return Err(Error::InvalidParms);
149 }
150 Ok(pf::suites::AngleParam::new()?
151 .floating_point_value_from_angle_def(unsafe { (*self._in_data).effect_ref }, self._parent_ptr.unwrap())?)
152 }
153}
154define_param_wrapper! {
158 PF_Param_BUTTON, PF_ButtonDef, button_d,
159 Param::Button,
160 ButtonDef {
161 label: CString,
162 },
163 impl label: String,
164}
165define_param_wrapper! {
169 PF_Param_CHECKBOX, PF_CheckBoxDef, bd,
170 Param::CheckBox,
171 CheckBoxDef {
172 label: CString,
173 },
174 impl value: bool,
175 fn init(param) {
176 param.set_label(" ");
177 }
178}
179impl<'a> CheckBoxDef<'_> {
180 pub fn set_default(&mut self, v: bool) -> &mut Self {
181 self.def.dephault = if v { 1 } else { 0 };
182 self
183 }
184 pub fn default(&self) -> bool {
185 self.def.dephault != 0
186 }
187 pub fn set_label(&mut self, v: &str) -> &mut Self {
188 self.label = CString::new(v).unwrap();
189 self.def.u.nameptr = self.label.as_ptr();
190 self
191 }
192 pub fn label(&self) -> &str {
193 unsafe { CStr::from_ptr(self.def.u.nameptr).to_str().unwrap() }
194 }
195}
196define_param_wrapper! {
200 PF_Param_COLOR, PF_ColorDef, cd,
201 Param::Color,
202 ColorDef { },
203 impl value: Pixel8,
204 impl default: Pixel8,
205}
206impl ColorDef<'_> {
207 pub fn float_value(&self) -> Result<PixelF32, Error> {
208 if self._in_data.is_null() || self._parent_ptr.is_none() {
209 return Err(Error::InvalidParms);
210 }
211 Ok(pf::suites::ColorParam::new()?
212 .floating_point_value_from_color_def(unsafe { (*self._in_data).effect_ref }, self._parent_ptr.unwrap())?)
213 }
214}
215define_param_wrapper! {
219 PF_Param_SLIDER, PF_SliderDef, sd,
220 Param::Slider,
221 SliderDef { },
222 impl value: i32,
223 impl default: i32,
224 impl valid_min: i32,
225 impl valid_max: i32,
226 impl slider_min: i32,
227 impl slider_max: i32,
228 impl value_str: ShortString,
229 impl value_desc: ShortString,
230}
231define_param_wrapper! {
238 PF_Param_FLOAT_SLIDER, PF_FloatSliderDef, fs_d,
239 Param::FloatSlider,
240 FloatSliderDef { },
241 impl value: f64,
242 impl phase: f64,
243 impl default: f64,
244 impl precision: i16,
245 impl curve_tolerance: f32,
246 impl valid_min: f32,
247 impl valid_max: f32,
248 impl slider_min: f32,
249 impl slider_max: f32,
250 impl value_desc: ShortString,
251}
252impl FloatSliderDef<'_> {
253 pub fn set_display_flags(&mut self, flags: ValueDisplayFlag) -> &mut Self {
254 self.def.display_flags = flags.bits() as _;
255 self
256 }
257 pub fn display_flags(&self) -> ValueDisplayFlag {
258 ValueDisplayFlag::from_bits_truncate(self.def.display_flags as _)
259 }
260 pub fn set_flags(&mut self, flags: FSliderFlag) -> &mut Self {
261 self.def.fs_flags = flags.bits() as _;
262 self
263 }
264 pub fn flags(&self) -> FSliderFlag {
265 FSliderFlag::from_bits_truncate(self.def.fs_flags as _)
266 }
267 pub fn set_exponent(&mut self, v: f32) -> &mut Self {
268 self.def.exponent = v;
269 self.def.useExponent = 1;
270 self
271 }
272 pub fn exponent(&self) -> Option<f32> {
273 if self.def.useExponent == 1 {
274 Some(self.def.exponent)
275 } else {
276 None
277 }
278 }
279}
280define_param_wrapper! {
284 PF_Param_PATH, PF_PathDef, path_d,
285 Param::Path,
286 PathDef { },
291 impl path_id: PF_PathID,
292 impl default: i32,
293}
294define_param_wrapper! {
298 PF_Param_POINT, PF_PointDef, td,
299 Param::Point,
300 PointDef { },
308 impl restrict_bounds: bool,
309 impl x_value: Fixed,
310 impl y_value: Fixed,
311}
312impl PointDef<'_> {
313 pub fn set_default_x(&mut self, v: f32) -> &mut Self { self.def.x_dephault = Fixed::from(v).as_fixed(); self }
314 pub fn set_default_y(&mut self, v: f32) -> &mut Self { self.def.y_dephault = Fixed::from(v).as_fixed(); self }
315 pub fn default_x(&self) -> f32 { Fixed::from_fixed(self.def.x_dephault).into() }
316 pub fn default_y(&self) -> f32 { Fixed::from_fixed(self.def.y_dephault).into() }
317
318 pub fn set_default(&mut self, v: (f32, f32)) -> &mut Self {
319 self.def.x_dephault = Fixed::from(v.0).as_fixed();
320 self.def.y_dephault = Fixed::from(v.1).as_fixed();
321 self
322 }
323 pub fn default(&self) -> (f32, f32) {
324 (Fixed::from_fixed(self.def.x_dephault).into(), Fixed::from_fixed(self.def.y_dephault).into())
325 }
326
327 pub fn set_value(&mut self, v: (f32, f32)) -> &mut Self {
328 self.def.x_value = Fixed::from(v.0).as_fixed();
329 self.def.y_value = Fixed::from(v.1).as_fixed();
330 self
331 }
332 pub fn value(&self) -> (f32, f32) {
333 (Fixed::from_fixed(self.def.x_value).into(), Fixed::from_fixed(self.def.y_value).into())
334 }
335 pub fn float_value(&self) -> Result<ae_sys::A_FloatPoint, Error> {
336 if self._in_data.is_null() || self._parent_ptr.is_none() {
337 return Err(Error::InvalidParms);
338 }
339 Ok(pf::suites::PointParam::new()?
340 .floating_point_value_from_point_def(unsafe { (*self._in_data).effect_ref }, self._parent_ptr.unwrap())?)
341 }
342}
343
344define_param_wrapper! {
345 PF_Param_POINT_3D, PF_Point3DDef, point3d_d,
346 Param::Point3D,
347 Point3DDef { },
352 impl x_value: f64,
353 impl y_value: f64,
354 impl z_value: f64,
355}
356impl Point3DDef<'_> {
357 pub fn set_default_x(&mut self, v: f64) -> &mut Self { self.def.x_dephault = v; self }
358 pub fn set_default_y(&mut self, v: f64) -> &mut Self { self.def.y_dephault = v; self }
359 pub fn set_default_z(&mut self, v: f64) -> &mut Self { self.def.z_dephault = v; self }
360 pub fn default_x(&self) -> f64 { self.def.x_dephault }
361 pub fn default_y(&self) -> f64 { self.def.y_dephault }
362 pub fn default_z(&self) -> f64 { self.def.z_dephault }
363
364 pub fn set_default(&mut self, v: (f64, f64, f64)) -> &mut Self {
365 self.def.x_dephault = v.0;
366 self.def.y_dephault = v.1;
367 self.def.z_dephault = v.2;
368 self
369 }
370 pub fn default(&self) -> (f64, f64, f64) {
371 (self.def.x_dephault, self.def.y_dephault, self.def.z_dephault)
372 }
373
374 pub fn set_value(&mut self, v: (f64, f64, f64)) -> &mut Self {
375 self.def.x_value = v.0;
376 self.def.y_value = v.1;
377 self.def.z_value = v.2;
378 self
379 }
380 pub fn value(&self) -> (f64, f64, f64) {
381 (self.def.x_value, self.def.y_value, self.def.z_value)
382 }
383}
384define_param_wrapper! {
388 PF_Param_POPUP, PF_PopupDef, pd,
389 Param::Popup,
390 PopupDef {
391 options: CString,
392 },
393 impl value: i32,
394 impl default: i32,
395}
396impl<'a> PopupDef<'a> {
397 pub fn set_options(&mut self, options: &[&str]) {
398 self.options = CString::new(options.join("|")).unwrap();
400 self.def.u.namesptr = self.options.as_ptr();
401 self.def.num_choices = options.len().try_into().unwrap();
402 }
403 pub fn options(&self) -> Vec<&str> {
404 let options = unsafe { CStr::from_ptr(self.def.u.namesptr).to_str().unwrap() };
405 options.split('|').collect()
406 }
407}
408define_param_wrapper! {
412 PF_Param_LAYER, PF_LayerDef, ld,
413 Param::Layer,
414 LayerDef { },
415}
416impl<'a> LayerDef<'a> {
417 pub fn set_default_to_this_layer(&mut self) {
418 self.def.dephault = ae_sys::PF_LayerDefault_MYSELF;
419 }
420 pub fn value(&self) -> Option<Layer> {
421 if self.def.data.is_null() {
422 None
423 } else {
424 Some(Layer::from_raw(&*self.def as *const _ as _, self._in_data, None))
425 }
426 }
427}
428#[allow(dead_code)]
432pub struct NullDef<'a>(&'a ());
433impl<'a> NullDef<'a> {
434 pub fn new() -> Self {
435 Self(&())
436 }
437}
438impl<'p> Into<Param<'p>> for NullDef<'p> {
439 fn into(self) -> Param<'p> {
440 Param::Null(self)
441 }
442}
443define_param_wrapper! {
447 PF_Param_ARBITRARY_DATA, PF_ArbitraryDef, arb_d,
448 Param::Arbitrary,
449 ArbitraryDef { },
450 impl pad: i16,
451}
452impl ArbitraryDef<'_> {
453 pub fn set_default<T>(&mut self, value: T) -> Result<&mut Self, Error> {
454 self.def.dephault = Handle::into_raw(Handle::new(value)?);
455 Ok(self)
456 }
457
458 pub fn set_value<T>(&mut self, value: T) -> Result<&mut Self, Error> {
459 if !self.def.value.is_null() {
460 let _ = Handle::<T>::from_raw(self.def.value, true);
461 }
462 self.def.value = Handle::into_raw(Handle::new(value)?);
463 self.set_value_changed();
464 Ok(self)
465 }
466 pub fn value<T>(&self) -> Result<BorrowedHandleLock<T>, Error> {
467 if self.def.value.is_null() {
468 return Err(Error::InvalidParms);
469 }
470 BorrowedHandleLock::<T>::from_raw(self.def.value)
471 }
472
473 pub fn set_refcon(&mut self, refcon: *mut std::ffi::c_void) -> &mut Self {
474 self.def.refconPV = refcon as _;
475 self
476 }
477}
478pub trait ArbitraryData<T> {
481 fn interpolate(&self, other: &T, value: f64) -> T;
482}
483
484define_struct_wrapper!(ArbParamsExtra, PF_ArbParamsExtra);
485
486impl std::fmt::Debug for ArbParamsExtra {
487 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
488 f.debug_struct("ArbParamsExtra")
489 .field("id", &self.id())
490 .field("refcon", &self.refcon())
491 .field("which_function", &self.which_function())
492 .finish()
493 }
494}
495
496impl ArbParamsExtra {
497 pub fn id(&self) -> i16 {
498 self.as_ref().id as _
499 }
500
501 pub fn refcon(&self) -> *mut std::ffi::c_void {
502 unsafe { self.as_ref().u.new_func_params.refconPV }
503 }
504
505 pub fn which_function(&self) -> u32 {
506 self.as_ref().which_function as _
507 }
508
509 pub fn dispatch<T, P>(&mut self, param: P) -> Result<(), Error>
510 where T: ArbitraryData<T> + Default + DeserializeOwned + Serialize + PartialEq + PartialOrd,
511 P: Eq + PartialEq + Hash + Copy + Debug
512 {
513 let param_id = Parameters::param_id(param) as i16;
514 if self.id() != param_id {
515 return Ok(());
517 }
518 match self.as_ref().which_function as _ {
519 ae_sys::PF_Arbitrary_NEW_FUNC => unsafe {
520 assert!(!self.as_ref().u.new_func_params.arbPH.is_null());
521 self.as_ref()
527 .u
528 .new_func_params
529 .arbPH
530 .write(Handle::into_raw(Handle::<T>::new(T::default())?));
531 },
532
533 ae_sys::PF_Arbitrary_DISPOSE_FUNC => {
534 if unsafe { !self.as_ref().u.dispose_func_params.arbH.is_null() } {
540 Handle::<T>::from_raw(unsafe { self.as_ref().u.dispose_func_params.arbH }, true)?;
541 }
542 }
543
544 ae_sys::PF_Arbitrary_COPY_FUNC => unsafe {
545 if self.as_ref().u.copy_func_params.src_arbH.is_null() {
552 self.as_ref()
554 .u
555 .copy_func_params
556 .dst_arbPH
557 .write(Handle::into_raw(Handle::<T>::new(T::default())?));
558 return Ok(());
559 }
560
561 let mut src_handle = Handle::<T>::from_raw(self.as_ref().u.copy_func_params.src_arbH, false)?;
562 let lock = src_handle.lock()?;
563
564 let serialized = bincode::serialize::<T>(lock.as_ref()?).map_err(|_| Error::InternalStructDamaged)?;
565 let deserialized = bincode::deserialize::<T>(&serialized).map_err(|_| Error::InternalStructDamaged)?;
566 let new_handle = Handle::<T>::new(deserialized)?;
567
568 self.as_ref()
569 .u
570 .copy_func_params
571 .dst_arbPH
572 .write(Handle::into_raw(new_handle));
573 },
574
575 ae_sys::PF_Arbitrary_FLAT_SIZE_FUNC => unsafe {
576 let mut handle = Handle::<T>::from_raw(self.as_ref().u.flat_size_func_params.arbH, false)?;
579 let lock = handle.lock()?;
580
581 let serialized = bincode::serialize::<T>(lock.as_ref()?).map_err(|_| Error::InternalStructDamaged)?;
582
583 self.as_ref()
584 .u
585 .flat_size_func_params
586 .flat_data_sizePLu
587 .write(serialized.len() as _);
588 },
589
590 ae_sys::PF_Arbitrary_FLATTEN_FUNC => unsafe {
591 assert!(!self.as_ref().u.unflatten_func_params.flat_dataPV.is_null());
593
594 let mut handle = Handle::<T>::from_raw(self.as_ref().u.flatten_func_params.arbH, false)?;
595 let lock = handle.lock()?;
596
597 let serialized = bincode::serialize::<T>(lock.as_ref()?).map_err(|_| Error::InternalStructDamaged)?;
598
599 assert!(
600 serialized.len() <= self.as_ref().u.flatten_func_params.buf_sizeLu as _
601 );
602
603 std::ptr::copy_nonoverlapping(
604 serialized.as_ptr(),
605 self.as_ref().u.flatten_func_params.flat_dataPV as _,
606 serialized.len(),
607 );
608 }
609
610 ae_sys::PF_Arbitrary_UNFLATTEN_FUNC => unsafe {
611 assert!(!self.as_ref().u.unflatten_func_params.flat_dataPV.is_null());
613
614 let serialized = std::slice::from_raw_parts(
615 self.as_ref().u.unflatten_func_params.flat_dataPV as *mut u8,
616 self.as_ref().u.unflatten_func_params.buf_sizeLu as _
617 );
618 let t = bincode::deserialize::<T>(serialized).map_err(|_| Error::InternalStructDamaged)?;
619 let handle = Handle::<T>::new(t)?;
620
621 self.as_ref()
622 .u
623 .unflatten_func_params
624 .arbPH
625 .write(Handle::into_raw(handle));
626 },
627
628 ae_sys::PF_Arbitrary_INTERP_FUNC => unsafe {
629 let mut left = Handle::<T>::from_raw(self.as_ref().u.interp_func_params.left_arbH, false)?;
632 let left_lock = left.lock()?;
633
634 let mut right = Handle::<T>::from_raw(self.as_ref().u.interp_func_params.right_arbH, false)?;
635 let right_lock = right.lock()?;
636
637 let interpolated = Handle::<T>::new(
638 left_lock.as_ref()?.interpolate(right_lock.as_ref()?, self.as_ref().u.interp_func_params.tF)
639 )?;
640
641 self.as_ref()
642 .u
643 .interp_func_params
644 .interpPH
645 .write(Handle::into_raw(interpolated));
646 },
647
648 ae_sys::PF_Arbitrary_COMPARE_FUNC => {
649 let mut handle_a = Handle::<T>::from_raw(unsafe { self.as_ref().u.compare_func_params.a_arbH }, false)?;
652 let handle_a_lock = handle_a.lock()?;
653 let a = handle_a_lock.as_ref()?;
654
655 let mut handle_b = Handle::<T>::from_raw(unsafe { self.as_ref().u.compare_func_params.b_arbH }, false)?;
656 let handle_b_lock = handle_b.lock()?;
657 let b = handle_b_lock.as_ref()?;
658
659 if a < b {
660 unsafe {
661 self.as_ref()
662 .u
663 .compare_func_params
664 .compareP
665 .write(ae_sys::PF_ArbCompare_LESS as _);
666 }
667 } else if a > b {
668 unsafe {
669 self.as_ref()
670 .u
671 .compare_func_params
672 .compareP
673 .write(ae_sys::PF_ArbCompare_MORE as _);
674 }
675 } else if a == b {
676 unsafe {
677 self.as_ref()
678 .u
679 .compare_func_params
680 .compareP
681 .write(ae_sys::PF_ArbCompare_EQUAL as _);
682 }
683 } else {
684 unsafe {
685 self.as_ref()
686 .u
687 .compare_func_params
688 .compareP
689 .write(ae_sys::PF_ArbCompare_NOT_EQUAL as _);
690 }
691 }
692 }
693
694 ae_sys::PF_Arbitrary_PRINT_SIZE_FUNC => unsafe {
695 let mut handle = Handle::<T>::from_raw(self.as_ref().u.print_size_func_params.arbH, false)?;
698 let lock = handle.lock()?;
699
700 let serialized = serde_json::to_string::<T>(lock.as_ref()?).map_err(|_| Error::InternalStructDamaged)?;
701 let cstr = std::ffi::CString::new(serialized).unwrap();
702
703 self.as_ref().u.print_size_func_params.print_sizePLu.write(
704 cstr.as_bytes_with_nul().len() as _,
705 );
706 },
707
708 ae_sys::PF_Arbitrary_PRINT_FUNC => unsafe {
711 let mut handle = Handle::<T>::from_raw(self.as_ref().u.print_func_params.arbH, false)?;
714 let lock = handle.lock()?;
715
716 let serialized = serde_json::to_string::<T>(lock.as_ref()?).map_err(|_| Error::InternalStructDamaged)?;
717 let cstr = std::ffi::CString::new(serialized).unwrap();
718 let cstr = cstr.as_bytes_with_nul();
719
720 if cstr.len() <= self.as_ref().u.print_func_params.print_sizeLu as _ && self.as_ref().u.print_func_params.print_flags == 0 {
721 std::ptr::copy_nonoverlapping(
722 cstr.as_ptr(),
723 self.as_ref().u.print_func_params.print_bufferPC as _,
724 cstr.len(),
725 );
726 }
727 }
728 ae_sys::PF_Arbitrary_SCAN_FUNC => unsafe {
729 let cstr = CStr::from_ptr(self.as_ref().u.scan_func_params.bufPC).to_str().map_err(|_| Error::InternalStructDamaged)?;
732
733 let t = serde_json::from_str::<T>(cstr).map_err(|_| Error::InternalStructDamaged)?;
734 let handle = Handle::<T>::new(t)?;
735
736 self.as_ref()
737 .u
738 .scan_func_params
739 .arbPH
740 .write(Handle::into_raw(handle));
741 },
742 _ => {
743 return Err(Error::Generic);
744 }
745 }
746 Ok(())
747 }
748}
749
750macro_rules! define_param_cast {
751 ($name:tt, $enm:ident, $type:ty) => {
752 paste::item! {
753 pub fn [<as_ $name>]<'a>(&'a self) -> Result<$type<'a>, Error> where 'p: 'a {
754 match self.as_param()? {
755 Param::$enm(x) => Ok(x),
756 x => {
757 log::error!("Invalid param type! Requested {:?}, but the param is {:?}", stringify!($name), x);
758 Err(Error::InvalidParms)
759 }
760 }
761 }
762 pub fn [<as_ $name _mut>]<'a>(&'a mut self) -> Result<$type<'a>, Error> where 'p: 'a {
763 match self.as_param_mut()? {
764 Param::$enm(x) => Ok(x),
765 x => {
766 log::error!("Invalid param type! Requested {:?}, but the param is {:?}", stringify!($name), x);
767 Err(Error::InvalidParms)
768 }
769 }
770 }
771 }
772 };
773}
774
775pub enum Param<'p> {
776 Angle(AngleDef<'p>),
777 Arbitrary(ArbitraryDef<'p>),
778 Button(ButtonDef<'p>),
779 CheckBox(CheckBoxDef<'p>),
780 Color(ColorDef<'p>),
781 FloatSlider(FloatSliderDef<'p>),
782 Path(PathDef<'p>),
783 Point(PointDef<'p>),
784 Point3D(Point3DDef<'p>),
785 Popup(PopupDef<'p>),
786 Slider(SliderDef<'p>),
787 Layer(LayerDef<'p>),
788 Null(NullDef<'p>),
789}
790
791impl Debug for Param<'_> {
792 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
793 match self {
794 Param::Angle(_) => write!(f, "Angle"),
795 Param::Arbitrary(_) => write!(f, "Arbitrary"),
796 Param::Button(_) => write!(f, "Button"),
797 Param::CheckBox(_) => write!(f, "CheckBox"),
798 Param::Color(_) => write!(f, "Color"),
799 Param::FloatSlider(_) => write!(f, "FloatSlider"),
800 Param::Path(_) => write!(f, "Path"),
801 Param::Point(_) => write!(f, "Point"),
802 Param::Point3D(_) => write!(f, "Point3D"),
803 Param::Popup(_) => write!(f, "Popup"),
804 Param::Slider(_) => write!(f, "Slider"),
805 Param::Layer(_) => write!(f, "Layer"),
806 Param::Null(_) => write!(f, "Null"),
807 }
808 }
809}
810
811#[derive(Clone)]
812pub struct ParamDef<'p> {
813 param_def: Ownership<'p, ae_sys::PF_ParamDef>,
814 checkin_on_drop: bool,
815 index: Option<i32>,
816 in_data: InData,
817}
818
819impl<'p> ParamDef<'p> {
820 pub fn new(in_data: InData) -> Self {
821 Self {
822 param_def: Ownership::Rust(unsafe { std::mem::zeroed() }),
823 checkin_on_drop: false,
824 in_data,
825 index: None,
826 }
827 }
828
829 pub fn as_ref(&self) -> &ae_sys::PF_ParamDef {
830 &*self.param_def
831 }
832 pub fn as_mut(&mut self) -> &mut ae_sys::PF_ParamDef {
833 &mut *self.param_def
834 }
835
836 pub fn index(&self) -> Option<i32> {
837 self.index
838 }
839
840 pub fn update_param_ui(&self) -> Result<(), Error> {
841 if let Some(index) = self.index {
842 self.in_data.effect().update_param_ui(index, self)
843 } else {
844 Err(Error::InvalidIndex)
845 }
846 }
847 pub fn keyframe_count(&self) -> Result<i32, Error> {
848 if let Some(index) = self.index {
849 pf::suites::ParamUtils::new()?
850 .keyframe_count(self.in_data.effect_ref(), index)
851 } else {
852 Err(Error::InvalidIndex)
853 }
854 }
855
856 pub fn from_raw(in_data: InData, param_def: &'p mut ae_sys::PF_ParamDef, index: Option<i32>) -> Self {
857 Self {
858 param_def: Ownership::AfterEffectsMut(param_def),
859 checkin_on_drop: false,
860 in_data,
861 index,
862 }
863 }
864
865 pub fn add(&mut self, index: i32) -> Result<(), Error> {
866 self.in_data.interact().add_param(index, &*self.param_def)?;
867 if index != -1 {
868 self.index = Some(index);
869 }
870 Ok(())
871 }
872
873 pub fn checkout(in_data: InData, index: i32, what_time: i32, time_step: i32, time_scale: u32, expected_type: Option<ParamType>) -> Result<Self, Error> {
874 let mut param_def = in_data.interact().checkout_param(index, what_time, time_step, time_scale)?;
875 if param_def.param_type == ae_sys::PF_Param_RESERVED {
876 return Err(Error::InvalidIndex);
877 }
878
879 if index > 0 && expected_type.is_some() {
881 param_def.param_type = expected_type.unwrap().into();
882 }
883
884 Ok(Self {
885 param_def: Ownership::Rust(param_def),
886 checkin_on_drop: true,
887 in_data,
888 index: Some(index),
889 })
890 }
891
892 pub fn set_param(&mut self, param: &Param) {
893 match param {
894 Param::Popup(pd) => {
895 self.param_def.u.pd = *pd.def;
896 self.param_def.param_type = ae_sys::PF_Param_POPUP;
897 }
898 Param::Angle(ad) => {
899 self.param_def.u.ad = *ad.def;
900 self.param_def.param_type = ae_sys::PF_Param_ANGLE;
901 }
902 Param::CheckBox(bd) => {
903 self.param_def.u.bd = *bd.def;
904 self.param_def.param_type = ae_sys::PF_Param_CHECKBOX;
905 }
906 Param::Color(cd) => {
907 self.param_def.u.cd = *cd.def;
908 self.param_def.param_type = ae_sys::PF_Param_COLOR;
909 }
910 Param::Slider(sd) => {
911 self.param_def.u.sd = *sd.def;
912 self.param_def.param_type = ae_sys::PF_Param_SLIDER;
913 }
914 Param::FloatSlider(fs_d) => {
915 self.param_def.u.fs_d = *fs_d.def;
916 self.param_def.param_type = ae_sys::PF_Param_FLOAT_SLIDER;
917 }
918 Param::Button(button_d) => {
919 self.param_def.u.button_d = *button_d.def;
920 self.param_def.param_type = ae_sys::PF_Param_BUTTON;
921 }
922 Param::Path(path_d) => {
923 self.param_def.u.path_d = *path_d.def;
924 self.param_def.param_type = ae_sys::PF_Param_PATH;
925 }
926 Param::Point(td) => {
927 self.param_def.u.td = *td.def;
928 self.param_def.param_type = ae_sys::PF_Param_POINT;
929 }
930 Param::Point3D(point3d_d) => {
931 self.param_def.u.point3d_d = *point3d_d.def;
932 self.param_def.param_type = ae_sys::PF_Param_POINT_3D;
933 }
934 Param::Arbitrary(arb_d) => {
935 self.param_def.u.arb_d = *arb_d.def;
936 self.param_def.param_type = ae_sys::PF_Param_ARBITRARY_DATA;
937 }
938 Param::Layer(ld) => {
939 self.param_def.u.ld = *ld.def;
940 self.param_def.param_type = ae_sys::PF_Param_LAYER;
941 }
942 Param::Null(_) => {
943 self.param_def.param_type = ae_sys::PF_Param_NO_DATA;
944 }
945 }
946 }
947
948 define_param_cast!("popup", Popup, PopupDef);
949 define_param_cast!("angle", Angle, AngleDef);
950 define_param_cast!("checkbox", CheckBox, CheckBoxDef);
951 define_param_cast!("color", Color, ColorDef);
952 define_param_cast!("slider", Slider, SliderDef);
953 define_param_cast!("float_slider", FloatSlider, FloatSliderDef);
954 define_param_cast!("button", Button, ButtonDef);
955 define_param_cast!("arbitrary", Arbitrary, ArbitraryDef);
956 define_param_cast!("point", Point, PointDef);
957 define_param_cast!("point3d", Point3D, Point3DDef);
958 define_param_cast!("path", Path, PathDef);
959 define_param_cast!("layer", Layer, LayerDef);
960 define_param_cast!("null", Null, NullDef);
961
962 pub fn as_param<'a>(&'a self) -> Result<Param<'a>, Error> where 'p: 'a {
963 let param_def = &*self.param_def;
964 let parent_ptr = param_def as *const _;
965 unsafe {
966 match param_def.param_type {
967 ae_sys::PF_Param_ANGLE => Ok(Param::Angle (AngleDef ::from_ref(¶m_def.u.ad, self.in_data.as_ptr(), parent_ptr))),
968 ae_sys::PF_Param_ARBITRARY_DATA => Ok(Param::Arbitrary (ArbitraryDef ::from_ref(¶m_def.u.arb_d, self.in_data.as_ptr(), parent_ptr))),
969 ae_sys::PF_Param_BUTTON => Ok(Param::Button (ButtonDef ::from_ref(¶m_def.u.button_d, self.in_data.as_ptr(), parent_ptr))),
970 ae_sys::PF_Param_CHECKBOX => Ok(Param::CheckBox (CheckBoxDef ::from_ref(¶m_def.u.bd, self.in_data.as_ptr(), parent_ptr))),
971 ae_sys::PF_Param_COLOR => Ok(Param::Color (ColorDef ::from_ref(¶m_def.u.cd, self.in_data.as_ptr(), parent_ptr))),
972 ae_sys::PF_Param_FLOAT_SLIDER => Ok(Param::FloatSlider(FloatSliderDef::from_ref(¶m_def.u.fs_d, self.in_data.as_ptr(), parent_ptr))),
973 ae_sys::PF_Param_POPUP => Ok(Param::Popup (PopupDef ::from_ref(¶m_def.u.pd, self.in_data.as_ptr(), parent_ptr))),
974 ae_sys::PF_Param_SLIDER => Ok(Param::Slider (SliderDef ::from_ref(¶m_def.u.sd, self.in_data.as_ptr(), parent_ptr))),
975 ae_sys::PF_Param_POINT => Ok(Param::Point (PointDef ::from_ref(¶m_def.u.td, self.in_data.as_ptr(), parent_ptr))),
976 ae_sys::PF_Param_POINT_3D => Ok(Param::Point3D (Point3DDef ::from_ref(¶m_def.u.point3d_d, self.in_data.as_ptr(), parent_ptr))),
977 ae_sys::PF_Param_PATH => Ok(Param::Path (PathDef ::from_ref(¶m_def.u.path_d, self.in_data.as_ptr(), parent_ptr))),
978 ae_sys::PF_Param_LAYER => Ok(Param::Layer (LayerDef ::from_ref(¶m_def.u.ld, self.in_data.as_ptr(), parent_ptr))),
979 ae_sys::PF_Param_NO_DATA => Ok(Param::Null (NullDef ::new())),
980 _ => {
981 log::error!("Invalid parameter type: {}", param_def.param_type);
982 Err(Error::InvalidParms)
983 }
984 }
985 }
986 }
987
988 pub fn as_param_mut<'a>(&'a mut self) -> Result<Param<'a>, Error> where 'p: 'a {
989 let param_def = &mut *self.param_def;
990 let parent_ptr = param_def as *const _;
991 unsafe {
992 match param_def.param_type {
993 ae_sys::PF_Param_ANGLE => Ok(Param::Angle (AngleDef ::from_mut(&mut param_def.u.ad, self.in_data.as_ptr(), parent_ptr))),
994 ae_sys::PF_Param_ARBITRARY_DATA => Ok(Param::Arbitrary (ArbitraryDef ::from_mut(&mut param_def.u.arb_d, self.in_data.as_ptr(), parent_ptr))),
995 ae_sys::PF_Param_BUTTON => Ok(Param::Button (ButtonDef ::from_mut(&mut param_def.u.button_d, self.in_data.as_ptr(), parent_ptr))),
996 ae_sys::PF_Param_CHECKBOX => Ok(Param::CheckBox (CheckBoxDef ::from_mut(&mut param_def.u.bd, self.in_data.as_ptr(), parent_ptr))),
997 ae_sys::PF_Param_COLOR => Ok(Param::Color (ColorDef ::from_mut(&mut param_def.u.cd, self.in_data.as_ptr(), parent_ptr))),
998 ae_sys::PF_Param_FLOAT_SLIDER => Ok(Param::FloatSlider(FloatSliderDef::from_mut(&mut param_def.u.fs_d, self.in_data.as_ptr(), parent_ptr))),
999 ae_sys::PF_Param_POPUP => Ok(Param::Popup (PopupDef ::from_mut(&mut param_def.u.pd, self.in_data.as_ptr(), parent_ptr))),
1000 ae_sys::PF_Param_SLIDER => Ok(Param::Slider (SliderDef ::from_mut(&mut param_def.u.sd, self.in_data.as_ptr(), parent_ptr))),
1001 ae_sys::PF_Param_POINT => Ok(Param::Point (PointDef ::from_mut(&mut param_def.u.td, self.in_data.as_ptr(), parent_ptr))),
1002 ae_sys::PF_Param_POINT_3D => Ok(Param::Point3D (Point3DDef ::from_mut(&mut param_def.u.point3d_d, self.in_data.as_ptr(), parent_ptr))),
1003 ae_sys::PF_Param_PATH => Ok(Param::Path (PathDef ::from_mut(&mut param_def.u.path_d, self.in_data.as_ptr(), parent_ptr))),
1004 ae_sys::PF_Param_LAYER => Ok(Param::Layer (LayerDef ::from_mut(&mut param_def.u.ld, self.in_data.as_ptr(), parent_ptr))),
1005 ae_sys::PF_Param_NO_DATA => Ok(Param::Null (NullDef ::new())),
1006 _ => {
1007 log::error!("Invalid parameter type: {}", param_def.param_type);
1008 Err(Error::InvalidParms)
1009 }
1010 }
1011 }
1012 }
1013
1014 pub fn is_valid(&self) -> bool {
1015 matches!(
1016 self.param_def.param_type,
1017 ae_sys::PF_Param_ANGLE
1018 | ae_sys::PF_Param_ARBITRARY_DATA
1019 | ae_sys::PF_Param_BUTTON
1020 | ae_sys::PF_Param_CHECKBOX
1021 | ae_sys::PF_Param_COLOR
1022 | ae_sys::PF_Param_FIX_SLIDER
1023 | ae_sys::PF_Param_FLOAT_SLIDER
1024 | ae_sys::PF_Param_GROUP_START
1025 | ae_sys::PF_Param_GROUP_END
1026 | ae_sys::PF_Param_POPUP
1027 | ae_sys::PF_Param_SLIDER
1028 | ae_sys::PF_Param_POINT
1029 | ae_sys::PF_Param_POINT_3D
1030 | ae_sys::PF_Param_PATH
1031 | ae_sys::PF_Param_LAYER
1032 | ae_sys::PF_Param_NO_DATA
1033 )
1034 }
1035 pub fn param_type(&self) -> ParamType {
1036 self.param_def.param_type.into()
1037 }
1038
1039 pub unsafe fn layer_def(&mut self) -> *mut ae_sys::PF_LayerDef {
1040 &mut self.param_def.u.ld
1041 }
1042
1043 pub fn set_name(&mut self, name: &str) {
1044 let name_cstr = CString::new(name).unwrap();
1045 let name_slice = name_cstr.to_bytes_with_nul();
1046 assert!(name_slice.len() <= 32);
1047 self.param_def.name[0..name_slice.len()].copy_from_slice(unsafe { std::mem::transmute(name_slice) });
1048 }
1049
1050 pub fn set_flags (&mut self, f: ParamFlag) { self.param_def.flags = f.bits() as _; }
1051 pub fn set_change_flags(&mut self, f: ChangeFlag) { self.param_def.uu.change_flags = f.bits() as _; }
1052 pub fn set_ui_flags (&mut self, f: ParamUIFlags) { self.param_def.ui_flags = f.bits() as _; }
1053
1054 pub fn set_flag (&mut self, f: ParamFlag, set: bool) { let mut v = self.flags(); v.set(f, set); self.set_flags(v); }
1055 pub fn set_change_flag(&mut self, f: ChangeFlag, set: bool) { let mut v = self.change_flags(); v.set(f, set); self.set_change_flags(v); }
1056 pub fn set_ui_flag (&mut self, f: ParamUIFlags, set: bool) { let mut v = self.ui_flags(); v.set(f, set); self.set_ui_flags(v); }
1057
1058 pub fn flags (&self) -> ParamFlag { ParamFlag::from_bits_truncate(self.param_def.flags) }
1059 pub fn change_flags(&self) -> ChangeFlag { ChangeFlag::from_bits_truncate(unsafe { self.param_def.uu.change_flags }) }
1060 pub fn ui_flags (&self) -> ParamUIFlags { ParamUIFlags::from_bits_truncate(self.param_def.ui_flags) }
1061
1062 pub fn set_ui_width(&mut self, width: u16) {
1063 self.param_def.ui_width = width as _;
1064 }
1065 pub fn set_ui_height(&mut self, height: u16) {
1066 self.param_def.ui_height = height as _;
1067 }
1068
1069 pub fn set_id(&mut self, id: i32) {
1070 self.param_def.uu.id = id;
1071 if self.param_def.param_type == ae_sys::PF_Param_ARBITRARY_DATA {
1072 self.param_def.u.arb_d.id = id as i16; }
1074 }
1075
1076 pub fn set_value_changed(&mut self) {
1077 self.param_def.uu.change_flags = ChangeFlag::CHANGED_VALUE.bits();
1078 }
1079}
1080
1081impl Drop for ParamDef<'_> {
1082 fn drop(&mut self) {
1083 if self.checkin_on_drop {
1084 self.in_data.interact().checkin_param(&*self.param_def).unwrap()
1085 }
1086 }
1087}
1088impl Debug for ParamDef<'_> {
1089 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1090 f.debug_struct("ParamDef")
1091 .field("type", &self.param_type())
1092 .field("checkin_on_drop", &self.checkin_on_drop)
1093 .field("in_data_ptr", &self.in_data.as_ptr())
1094 .finish()
1095 }
1096}
1097
1098use std::collections::HashMap;
1099use std::fmt::Debug;
1100use std::hash::Hash;
1101
1102#[derive(Clone, Debug)]
1103pub struct ParamMapInfo {
1104 pub index: usize,
1105 pub type_: ParamType,
1106}
1107impl ParamMapInfo {
1108 fn new(index: usize, type_: ParamType) -> Self {
1109 Self { index, type_ }
1110 }
1111}
1112
1113#[derive(Clone)]
1114pub struct Parameters<'p, P: Eq + PartialEq + Hash + Copy + Debug> {
1115 num_params: usize,
1116 in_data: *const ae_sys::PF_InData,
1117 pub map: Ownership<'p, HashMap<P, ParamMapInfo>>,
1118 params: Vec<ParamDef<'p>>,
1119}
1120impl<P: Eq + PartialEq + Hash + Copy + Debug> Default for Parameters<'_, P> {
1121 fn default() -> Self {
1122 Self::new()
1123 }
1124}
1125impl<'p, P: Eq + PartialEq + Hash + Copy + Debug> Parameters<'p, P> {
1126 pub fn len(&self) -> usize {
1127 self.map.len()
1128 }
1129 pub fn set_in_data(&mut self, in_data: *const ae_sys::PF_InData) {
1130 self.in_data = in_data;
1131 }
1132 pub fn in_data(&self) -> InData {
1133 InData::from_raw(self.in_data)
1134 }
1135 pub fn new() -> Self {
1136 Self {
1137 in_data: std::ptr::null(),
1138 num_params: 1,
1139 map: Ownership::Rust(Default::default()),
1140 params: Vec::new(),
1141 }
1142 }
1143 pub fn with_params(in_data: *const ae_sys::PF_InData, params: &'p [*mut ae_sys::PF_ParamDef], map: Option<&'p HashMap<P, ParamMapInfo>>, num_params: usize) -> Self {
1144 let in_data_obj = InData::from_raw(in_data);
1145 Self {
1146 in_data,
1147 params: if params.is_empty() || params[0].is_null() {
1148 Vec::new()
1149 } else {
1150 params
1151 .into_iter()
1152 .enumerate()
1153 .map(|(i, p)| { debug_assert!(!p.is_null()); ParamDef::from_raw(in_data_obj, unsafe { &mut **p }, Some(i as i32)) })
1154 .collect::<Vec<_>>()
1155 },
1156 num_params,
1157 map: map.map_or_else(|| Ownership::Rust(HashMap::new()), Ownership::AfterEffects),
1158 }
1159 }
1160
1161 fn param_id(type_: P) -> i32 {
1162 use hash32::Murmur3Hasher;
1163 use std::hash::Hasher;
1164 let mut hasher = Murmur3Hasher::default();
1165 format!("{type_:?}").hash(&mut hasher);
1166 hasher.finish() as i32
1167 }
1168
1169 pub fn add_group<F: FnOnce(&mut Self) -> Result<(), Error>>(&mut self, type_start: P, type_end: P, name: &str, start_collapsed: bool, inner_cb: F) -> Result<(), Error> {
1170 assert!(!self.in_data.is_null());
1171
1172 let mut param_def = ParamDef::new(InData::from_raw(self.in_data));
1173 param_def.set_name(name);
1174 param_def.as_mut().param_type = ParamType::GroupStart.into();
1175 param_def.set_id(Self::param_id(type_start));
1176 if start_collapsed {
1177 param_def.set_flags(ParamFlag::START_COLLAPSED);
1178 }
1179 param_def.add(-1)?;
1180 self.map.insert(type_start, ParamMapInfo::new(self.num_params, ParamType::GroupStart));
1181 self.num_params += 1;
1182
1183 inner_cb(self)?;
1184
1185 let mut param_def = ParamDef::new(InData::from_raw(self.in_data));
1186 param_def.as_mut().param_type = ParamType::GroupEnd.into();
1187 param_def.set_id(Self::param_id(type_end));
1188 param_def.add(-1)?;
1189 self.map.insert(type_end, ParamMapInfo::new(self.num_params, ParamType::GroupEnd));
1190 self.num_params += 1;
1191 Ok(())
1192 }
1193
1194 pub fn add<'a>(&mut self, type_: P, name: &str, def: impl Into<Param<'a>>) -> Result<(), Error> {
1195 assert!(!self.in_data.is_null());
1196
1197 let param = def.into(); let mut param_def = ParamDef::new(InData::from_raw(self.in_data));
1200 param_def.set_name(name);
1201 param_def.set_param(¶m);
1202 let param_type = param_def.param_type();
1203 param_def.set_id(Self::param_id(type_));
1204 if matches!(param, Param::Button(_)) {
1205 param_def.set_flags(ParamFlag::SUPERVISE);
1206 }
1207 param_def.add(-1)?;
1208 self.map.insert(type_, ParamMapInfo::new(self.num_params, param_type));
1209 self.num_params += 1;
1210 Ok(())
1211 }
1212
1213 pub fn add_with_flags<'a>(&mut self, type_: P, name: &str, def: impl Into<Param<'a>>, flags: ParamFlag, ui_flags: ParamUIFlags) -> Result<(), Error> {
1214 assert!(!self.in_data.is_null());
1215
1216 let param = def.into(); let mut param_def = ParamDef::new(InData::from_raw(self.in_data));
1219 param_def.set_name(name);
1220 param_def.set_param(¶m);
1221 let param_type = param_def.param_type();
1222 param_def.set_id(Self::param_id(type_));
1223 param_def.set_flags(flags);
1224 param_def.set_ui_flags(ui_flags);
1225 param_def.add(-1)?;
1226 self.map.insert(type_, ParamMapInfo::new(self.num_params, param_type));
1227 self.num_params += 1;
1228 Ok(())
1229 }
1230
1231 pub fn add_customized<'a, F: FnOnce(&mut ParamDef) -> i32>(&mut self, type_: P, name: &str, def: impl Into<Param<'a>>, cb: F) -> Result<(), Error> {
1232 assert!(!self.in_data.is_null());
1233
1234 let param = def.into(); let mut param_def = ParamDef::new(InData::from_raw(self.in_data));
1237 param_def.set_name(name);
1238 param_def.set_param(¶m);
1239 let param_type = param_def.param_type();
1240 param_def.set_id(Self::param_id(type_));
1241 let mut index = cb(&mut param_def);
1242 param_def.add(index)?;
1243 if index == -1 {
1244 index = self.num_params as i32;
1245 }
1246 self.map.insert(type_, ParamMapInfo::new(index as usize, param_type));
1247 self.num_params += 1;
1248 Ok(())
1249 }
1250
1251 #[inline(always)]
1252 pub fn get(&self, type_: P) -> Result<ReadOnlyOwnership<ParamDef<'p>>, Error> {
1253 self.get_at(type_, None, None, None)
1254 }
1255
1256 #[inline(always)]
1257 pub fn get_mut(&mut self, type_: P) -> Result<Ownership<ParamDef<'p>>, Error> {
1258 self.get_mut_at(type_, None, None, None)
1259 }
1260
1261 #[inline(always)]
1262 pub fn checkout(&self, type_: P) -> Result<Ownership<ParamDef<'p>>, Error> {
1263 self.checkout_at(type_, None, None, None)
1264 }
1265
1266 pub fn get_at(&self, type_: P, time: Option<i32>, time_step: Option<i32>, time_scale: Option<u32>) -> Result<ReadOnlyOwnership<ParamDef<'p>>, Error> {
1267 if self.params.is_empty() || time.is_some() {
1268 match self.checkout_at(type_, time, time_step, time_scale) {
1269 Ok(Ownership::Rust(param)) => Ok(ReadOnlyOwnership::Rust(param)),
1270 Ok(_) => unreachable!(),
1271 Err(e) => Err(e)
1272 }
1273 } else {
1274 let index = self.index(type_).ok_or(Error::InvalidIndex)?;
1275 Ok(ReadOnlyOwnership::AfterEffects(self.params.get(index).ok_or(Error::InvalidIndex)?))
1276 }
1277 }
1278
1279 pub fn get_mut_at(&mut self, type_: P, time: Option<i32>, time_step: Option<i32>, time_scale: Option<u32>) -> Result<Ownership<ParamDef<'p>>, Error> {
1280 if self.params.is_empty() || time.is_some() {
1281 self.checkout_at(type_, time, time_step, time_scale)
1282 } else {
1283 let index = self.index(type_).ok_or(Error::InvalidIndex)?;
1284 Ok(Ownership::AfterEffectsMut(self.params.get_mut(index).ok_or(Error::InvalidIndex)?))
1285 }
1286 }
1287
1288 pub fn checkout_at(&self, type_: P, time: Option<i32>, time_step: Option<i32>, time_scale: Option<u32>) -> Result<Ownership<ParamDef<'p>>, Error> {
1289 let index = self.index(type_).ok_or(Error::InvalidIndex)?;
1290 let type_ = self.raw_param_type(type_).ok_or(Error::InvalidIndex)?;
1291 let in_data = self.in_data();
1292 let param = ParamDef::checkout(
1293 in_data,
1294 index as i32,
1295 time.unwrap_or(in_data.current_time()),
1296 time_step.unwrap_or(in_data.time_step()),
1297 time_scale.unwrap_or(in_data.time_scale()),
1298 Some(type_)
1299 )?;
1300 if !param.is_valid() {
1301 return Err(Error::InvalidParms);
1302 }
1303 Ok(Ownership::Rust(param))
1304 }
1305
1306 pub fn num_params(&self) -> usize {
1307 self.num_params
1308 }
1309
1310 pub fn index(&self, type_: P) -> Option<usize> {
1311 self.map.get(&type_).map(|x| x.index)
1312 }
1313 pub fn type_at(&self, index: usize) -> P {
1314 *self.map.iter().find(|(_, v)| v.index == index).unwrap().0
1315 }
1316
1317 pub fn raw_params(&self) -> &[ParamDef<'p>] {
1318 &self.params
1319 }
1320 pub fn raw_param_type(&self, type_: P) -> Option<ParamType> {
1321 self.map.get(&type_).map(|x| x.type_)
1322 }
1323
1324 pub fn cloned(&self) -> Parameters<'p, P> {
1325 Parameters::<'p, P> {
1326 in_data: self.in_data.clone(),
1327 num_params: self.num_params,
1328 map: self.map.clone(),
1329 params: self.params.iter().cloned().collect(),
1330 }
1331 }
1332}