ofx/
handle.rs

1use enums::*;
2use image::*;
3use ofx_sys::*;
4use property::*;
5use result::*;
6use std::borrow::Borrow;
7use std::cell::RefCell;
8use std::ffi::{CStr, CString};
9use std::fmt;
10use std::marker::PhantomData;
11use std::rc::Rc;
12use types::*;
13
14#[derive(Debug, Clone)]
15pub struct PropertySetHandle {
16	inner: OfxPropertySetHandle,
17	property: Rc<OfxPropertySuiteV1>,
18}
19
20impl PropertySetHandle {
21	pub(crate) fn new(inner: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
22		PropertySetHandle { inner, property }
23	}
24
25	pub(crate) fn empty() -> Self {
26		panic!("Do not use, only for type validation testing");
27		PropertySetHandle {
28			inner: std::ptr::null::<OfxPropertySetStruct>() as *mut _,
29			property: unsafe { Rc::new(*std::ptr::null()) },
30		}
31	}
32}
33
34#[derive(Clone)]
35pub struct GenericPluginHandle {
36	inner: VoidPtr,
37	property: &'static OfxPropertySuiteV1,
38}
39
40#[derive(Clone)]
41pub struct HostHandle {
42	inner: OfxPropertySetHandle,
43	property: Rc<OfxPropertySuiteV1>,
44}
45
46impl HostHandle {
47	pub fn new(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
48		HostHandle {
49			inner: host,
50			property,
51		}
52	}
53}
54
55#[derive(Clone)]
56pub struct ImageEffectHandle {
57	inner: OfxImageEffectHandle,
58	property: Rc<OfxPropertySuiteV1>,
59	image_effect: Rc<OfxImageEffectSuiteV1>,
60	parameter: Rc<OfxParameterSuiteV1>,
61}
62
63#[derive(Clone)]
64pub struct ImageClipHandle {
65	inner: OfxImageClipHandle,
66	inner_properties: OfxPropertySetHandle,
67	property: Rc<OfxPropertySuiteV1>,
68	image_effect: Rc<OfxImageEffectSuiteV1>,
69}
70
71#[derive(Clone)]
72pub struct ImageHandle {
73	inner: OfxPropertySetHandle,
74	property: Rc<OfxPropertySuiteV1>,
75	image_effect: Rc<OfxImageEffectSuiteV1>,
76}
77
78pub trait ParamHandleValue: Default + Clone {}
79impl ParamHandleValue for Int {}
80impl ParamHandleValue for Bool {}
81impl ParamHandleValue for Double {}
82
83pub trait ParamHandleValueDefault: ParamHandleValue + Default {}
84impl ParamHandleValueDefault for Int {}
85impl ParamHandleValueDefault for Double {}
86
87#[derive(Clone)]
88pub struct ParamHandle<T>
89where
90	T: ParamHandleValue,
91{
92	inner: OfxParamHandle,
93	inner_properties: OfxPropertySetHandle,
94	property: Rc<OfxPropertySuiteV1>,
95	parameter: Rc<OfxParameterSuiteV1>,
96	_type: PhantomData<T>,
97}
98
99#[derive(Clone)]
100pub struct ParamSetHandle {
101	inner: OfxParamSetHandle,
102	property: Rc<OfxPropertySuiteV1>,
103	parameter: Rc<OfxParameterSuiteV1>,
104}
105
106// TODO: custom_derive?
107macro_rules! trivial_debug {
108	($($struct:ty),*) => {
109		$(impl fmt::Debug for $struct {
110			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111				write!(f, "{} {{...}}", stringify!($struct))
112			}
113		})
114		*
115	}
116}
117
118trivial_debug!(
119	ImageClipHandle,
120	ImageEffectHandle,
121	GenericPluginHandle,
122	HostHandle
123);
124
125impl ImageEffectHandle {
126	pub fn new(
127		inner: OfxImageEffectHandle,
128		property: Rc<OfxPropertySuiteV1>,
129		image_effect: Rc<OfxImageEffectSuiteV1>,
130		parameter: Rc<OfxParameterSuiteV1>,
131	) -> Self {
132		ImageEffectHandle {
133			inner,
134			property,
135			image_effect,
136			parameter,
137		}
138	}
139}
140
141impl<T> ParamHandle<T>
142where
143	T: ParamHandleValue + Default,
144{
145	pub fn new(
146		inner: OfxParamHandle,
147		inner_properties: OfxPropertySetHandle,
148		property: Rc<OfxPropertySuiteV1>,
149		parameter: Rc<OfxParameterSuiteV1>,
150	) -> Self {
151		ParamHandle {
152			inner,
153			inner_properties,
154			property,
155			parameter,
156			_type: PhantomData,
157		}
158	}
159}
160
161impl<T> ParamHandle<T>
162where
163	T: ParamHandleValueDefault,
164{
165	pub fn get_value(&self) -> Result<T> {
166		let mut value: T = T::default();
167		suite_fn!(paramGetValue in self.parameter; self.inner, &mut value as *mut T)?;
168		Ok(value)
169	}
170
171	pub fn get_value_at_time(&self, time: Time) -> Result<T> {
172		let mut value: T = T::default();
173		suite_fn!(paramGetValueAtTime in self.parameter; self.inner, time, &mut value as *mut T)?;
174		Ok(value)
175	}
176}
177
178impl ParamHandle<Bool> {
179	pub fn get_value(&self) -> Result<Bool> {
180		let mut value: Int = 0;
181		suite_fn!(paramGetValue in self.parameter; self.inner, &mut value as *mut Int)?;
182		Ok(value != 0)
183	}
184
185	pub fn get_value_at_time(&self, time: Time) -> Result<Bool> {
186		let mut value: Int = 0;
187		suite_fn!(paramGetValueAtTime in self.parameter; self.inner, time, &mut value as *mut Int)?;
188		Ok(value != 0)
189	}
190}
191
192impl ImageClipHandle {
193	pub fn new(
194		inner: OfxImageClipHandle,
195		inner_properties: OfxPropertySetHandle,
196		property: Rc<OfxPropertySuiteV1>,
197		image_effect: Rc<OfxImageEffectSuiteV1>,
198	) -> Self {
199		ImageClipHandle {
200			inner,
201			inner_properties,
202			property,
203			image_effect,
204		}
205	}
206
207	pub fn get_region_of_definition(&self, time: Time) -> Result<RectD> {
208		let mut value = RectD {
209			x1: 0.0,
210			y1: 0.0,
211			x2: 0.0,
212			y2: 0.0,
213		};
214		suite_fn!(clipGetRegionOfDefinition in self.image_effect; self.inner, time, &mut value as *mut RectD)?;
215		Ok(value)
216	}
217
218	pub fn get_image_mut(&mut self, time: Time) -> Result<Rc<RefCell<ImageHandle>>> {
219		self.get_image_rect_mut(time, None)
220	}
221
222	pub fn get_image(&self, time: Time) -> Result<Rc<ImageHandle>> {
223		self.get_image_rect(time, None)
224	}
225
226	pub fn get_image_rect(&self, time: Time, region: Option<RectD>) -> Result<Rc<ImageHandle>> {
227		let mut image: OfxPropertySetHandle = std::ptr::null_mut();
228		let region_ptr = region
229			.as_ref()
230			.map(|m| m as *const RectD)
231			.unwrap_or(std::ptr::null());
232		suite_fn!(clipGetImage in self.image_effect; self.inner, time, region_ptr, &mut image as *mut OfxPropertySetHandle)?;
233		Ok(Rc::new(ImageHandle::new(
234			image,
235			self.property.clone(),
236			self.image_effect.clone(),
237		)))
238	}
239
240	pub fn get_image_rect_mut(
241		&mut self,
242		time: Time,
243		region: Option<RectD>,
244	) -> Result<Rc<RefCell<ImageHandle>>> {
245		let mut image: OfxPropertySetHandle = std::ptr::null_mut();
246		let region_ptr = region
247			.as_ref()
248			.map(|m| m as *const RectD)
249			.unwrap_or(std::ptr::null());
250		suite_fn!(clipGetImage in self.image_effect; self.inner, time, region_ptr, &mut image as *mut OfxPropertySetHandle)?;
251		Ok(Rc::new(RefCell::new(ImageHandle::new(
252			image,
253			self.property.clone(),
254			self.image_effect.clone(),
255		))))
256	}
257}
258
259impl Drop for ImageHandle {
260	fn drop(&mut self) {
261		self.drop_image()
262			.expect("Unable to drop image handle. This is likely a bug");
263	}
264}
265
266impl ImageHandle {
267	pub fn new(
268		inner: OfxPropertySetHandle,
269		property: Rc<OfxPropertySuiteV1>,
270		image_effect: Rc<OfxImageEffectSuiteV1>,
271	) -> Self {
272		ImageHandle {
273			inner,
274			property,
275			image_effect,
276		}
277	}
278
279	pub fn get_descriptor<T>(&self) -> Result<ImageDescriptor<T>>
280	where
281		T: PixelFormat,
282	{
283		let bounds = self.get_bounds()?;
284		let row_bytes = self.get_row_bytes()?;
285		let ptr = self.get_data()?;
286
287		Ok(ImageDescriptor::new(bounds, row_bytes, ptr))
288	}
289
290	fn get_descriptor_mut<T>(&mut self) -> Result<ImageDescriptorMut<T>>
291	where
292		T: PixelFormat,
293	{
294		let bounds = self.get_bounds()?;
295		let row_bytes = self.get_row_bytes()?;
296		let mut ptr = self.get_data()?;
297
298		Ok(ImageDescriptorMut::new(bounds, row_bytes, ptr))
299	}
300
301	pub fn get_tiles_mut<T>(&mut self, count: usize) -> Result<Vec<ImageTileMut<T>>>
302	where
303		T: PixelFormat,
304	{
305		let bounds = self.get_bounds()?;
306		let row_bytes = self.get_row_bytes()?;
307		let mut ptr = self.get_data()?;
308
309		Ok(ImageDescriptorMut::new(bounds, row_bytes, ptr).into_tiles(count))
310	}
311
312	fn drop_image(&mut self) -> Result<()> {
313		debug!("Releasing data for ImageHandle {:?}", self.inner);
314		suite_fn!(clipReleaseImage in self.image_effect; self.inner)
315	}
316}
317
318impl HasProperties<ClipProperties> for ImageClipHandle {
319	fn properties(&self) -> Result<ClipProperties> {
320		Ok(ClipProperties::new(
321			self.inner_properties,
322			self.property.clone(),
323		))
324	}
325}
326
327trait IsPropertiesNewType {
328	fn wrap(inner: PropertySetHandle) -> Self;
329}
330
331pub trait PropertiesNewTypeConstructor {
332	fn build(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self;
333}
334
335#[inline]
336pub fn build_typed<T>(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> T
337where
338	T: PropertiesNewTypeConstructor,
339{
340	T::build(host, property)
341}
342
343macro_rules! properties_newtype {
344	($name:ident) => {
345		#[derive(Clone)]
346		pub struct $name(PropertySetHandle);
347
348		impl IsPropertiesNewType for $name {
349			fn wrap(inner: PropertySetHandle) -> Self {
350				$name(inner)
351			}
352		}
353
354		impl PropertiesNewTypeConstructor for $name {
355			fn build(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
356				$name::new(host, property)
357			}
358		}
359
360		impl $name {
361			pub fn new(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
362				$name(PropertySetHandle::new(host, property))
363			}
364		}
365
366		impl<'a> AsProperties for $name {
367			fn handle(&self) -> OfxPropertySetHandle {
368				self.0.inner
369			}
370			fn suite(&self) -> *const OfxPropertySuiteV1 {
371				self.0.property.borrow() as *const _
372			}
373		}
374
375		trivial_debug!($name);
376	};
377}
378
379properties_newtype!(HostProperties);
380properties_newtype!(EffectDescriptorProperties);
381properties_newtype!(ImageEffectProperties);
382properties_newtype!(ClipProperties);
383
384properties_newtype!(DescribeInContextInArgs);
385
386properties_newtype!(GetRegionOfDefinitionInArgs);
387properties_newtype!(GetRegionOfDefinitionOutArgs);
388
389properties_newtype!(GetRegionsOfInterestInArgs);
390properties_newtype!(GetRegionsOfInterestOutArgs);
391
392properties_newtype!(GetClipPreferencesOutArgs);
393
394properties_newtype!(IsIdentityInArgs);
395properties_newtype!(IsIdentityOutArgs);
396
397properties_newtype!(BeginInstanceChangedInArgs);
398
399properties_newtype!(InstanceChangedInArgs);
400properties_newtype!(InstanceChangedOutArgs);
401
402properties_newtype!(EndInstanceChangedInArgs);
403properties_newtype!(EndInstanceChangedOutArgs);
404
405properties_newtype!(GetTimeDomainOutArgs);
406
407properties_newtype!(BeginSequenceRenderInArgs);
408properties_newtype!(RenderInArgs);
409properties_newtype!(EndSequenceRenderInArgs);
410
411properties_newtype!(ParamDoubleProperties);
412properties_newtype!(ParamIntProperties);
413properties_newtype!(ParamBooleanProperties);
414properties_newtype!(ParamPageProperties);
415properties_newtype!(ParamGroupProperties);
416
417impl DescribeInContextInArgs {}
418
419impl HasProperties<ImageEffectProperties> for ImageEffectHandle {
420	fn properties(&self) -> Result<ImageEffectProperties> {
421		let property_set_handle = {
422			let mut property_set_handle = std::ptr::null_mut();
423
424			suite_fn!(getPropertySet in self.image_effect; self.inner, &mut property_set_handle as *mut _)?;
425
426			property_set_handle
427		};
428		Ok(ImageEffectProperties(PropertySetHandle::new(
429			property_set_handle,
430			self.property.clone(),
431		)))
432	}
433}
434
435impl HasProperties<EffectDescriptorProperties> for ImageEffectHandle {
436	fn properties(&self) -> Result<EffectDescriptorProperties> {
437		let property_set_handle = {
438			let mut property_set_handle = std::ptr::null_mut();
439
440			suite_fn!(getPropertySet in self.image_effect; self.inner, &mut property_set_handle as *mut _)?;
441
442			property_set_handle
443		};
444		Ok(EffectDescriptorProperties(PropertySetHandle::new(
445			property_set_handle,
446			self.property.clone(),
447		)))
448	}
449}
450
451
452impl ImageEffectHandle {
453	fn clip_define(&self, clip_name: &[u8]) -> Result<ClipProperties> {
454		let property_set_handle = {
455			let mut property_set_handle = std::ptr::null_mut();
456			suite_fn!(clipDefine in self.image_effect;
457				self.inner, clip_name.as_ptr() as *const i8, &mut property_set_handle as *mut _)?;
458			property_set_handle
459		};
460		Ok(ClipProperties(PropertySetHandle::new(
461			property_set_handle,
462			self.property.clone(),
463		)))
464	}
465
466	fn clip_get_handle(&self, clip_name: &[u8]) -> Result<ImageClipHandle> {
467		let (clip_handle, clip_properties) = {
468			let mut clip_handle = std::ptr::null_mut();
469			let mut clip_properties = std::ptr::null_mut();
470			suite_fn!(clipGetHandle in self.image_effect;
471				self.inner, clip_name.as_ptr() as *const i8, &mut clip_handle as *mut _, &mut clip_properties as *mut _)?;
472			(clip_handle, clip_properties)
473		};
474		Ok(ImageClipHandle::new(
475			clip_handle,
476			clip_properties,
477			self.property.clone(),
478			self.image_effect.clone(),
479		))
480	}
481
482	pub fn abort(&self) -> Result<Bool> {
483		Ok(suite_call!(abort in self.image_effect; self.inner) != 0)
484	}
485
486	pub fn parameter_set(&self) -> Result<ParamSetHandle> {
487		let parameters_set_handle = {
488			let mut parameters_set_handle = std::ptr::null_mut();
489			suite_fn!(getParamSet in self.image_effect; self.inner, &mut parameters_set_handle as *mut _)?;
490			parameters_set_handle
491		};
492		Ok(ParamSetHandle::new(
493			parameters_set_handle,
494			self.parameter.clone(),
495			self.property.clone(),
496		))
497	}
498
499	pub fn get_output_clip(&self) -> Result<ImageClipHandle> {
500		self.clip_get_handle(ofx_sys::kOfxImageEffectOutputClipName)
501	}
502
503	pub fn get_simple_input_clip(&self) -> Result<ImageClipHandle> {
504		self.clip_get_handle(ofx_sys::kOfxImageEffectSimpleSourceClipName)
505	}
506
507	pub fn get_clip(&self, name: &str) -> Result<ImageClipHandle> {
508		let str_buf = CString::new(name)?.into_bytes_with_nul();
509		self.clip_get_handle(&str_buf)
510	}
511
512	pub fn new_output_clip(&self) -> Result<ClipProperties> {
513		self.clip_define(ofx_sys::kOfxImageEffectOutputClipName)
514	}
515
516	pub fn new_simple_input_clip(&self) -> Result<ClipProperties> {
517		self.clip_define(ofx_sys::kOfxImageEffectSimpleSourceClipName)
518	}
519
520	pub fn new_clip(&self, name: &str) -> Result<ClipProperties> {
521		let str_buf = CString::new(name)?.into_bytes_with_nul();
522		self.clip_define(&str_buf)
523	}
524
525	unsafe fn get_pointer(&self) -> Result<*mut [u8]> {
526		Err(Error::Unimplemented)
527	}
528
529	pub fn set_instance_data<T>(&mut self, data: T) -> Result<()>
530	where
531		T: Sized,
532	{
533		let mut effect_props: ImageEffectProperties = self.properties()?;
534		let data_box = Box::new(data);
535		let data_ptr = Box::into_raw(data_box);
536		let status = suite_fn!(propSetPointer in self.property;
537			effect_props.0.inner, kOfxPropInstanceData.as_ptr() as *const i8, 0, data_ptr as *mut _);
538		if status.is_err() {
539			unsafe {
540				Box::from_raw(data_ptr);
541			}
542		}
543		status
544	}
545
546	fn get_instance_data_ptr(&self) -> Result<VoidPtrMut> {
547		let mut effect_props: ImageEffectProperties = self.properties()?;
548		let mut data_ptr = std::ptr::null_mut();
549		to_result! { suite_call!(propGetPointer in self.property;
550		   effect_props.0.inner, kOfxPropInstanceData.as_ptr() as *const i8, 0, &mut data_ptr)
551		=> data_ptr }
552	}
553
554	// TODO: this is not safe enough
555	pub fn get_instance_data<T>(&self) -> Result<&mut T>
556	where
557		T: Sized,
558	{
559		unsafe {
560			let mut ptr = self.get_instance_data_ptr()?;
561			let mut reference = ptr as *mut T;
562			Ok(&mut *reference)
563		}
564	}
565
566	pub fn drop_instance_data(&mut self) -> Result<()> {
567		unsafe {
568			let mut ptr = self.get_instance_data_ptr()?;
569			if !ptr.is_null() {
570				Box::from_raw(ptr);
571			}
572		}
573		Ok(())
574	}
575}
576
577impl ParamSetHandle {
578	pub fn new(
579		inner: OfxParamSetHandle,
580		parameter: Rc<OfxParameterSuiteV1>,
581		property: Rc<OfxPropertySuiteV1>,
582	) -> Self {
583		ParamSetHandle {
584			inner,
585			parameter,
586			property,
587		}
588	}
589
590	fn param_define<T>(&mut self, param_type: ParamType, name: &str) -> Result<T>
591	where
592		T: IsPropertiesNewType,
593	{
594		let name_buf = CString::new(name)?.into_bytes_with_nul();
595		let property_set_handle = {
596			let mut property_set_handle = std::ptr::null_mut();
597			suite_fn!(paramDefine in self.parameter;
598				self.inner, param_type.as_ptr() as *const _, name_buf.as_ptr() as *const _, &mut property_set_handle as *mut _)?;
599
600			property_set_handle
601		};
602		Ok(T::wrap(PropertySetHandle::new(
603			property_set_handle,
604			self.property.clone(),
605		)))
606	}
607
608	pub fn parameter<T>(&self, name: &str) -> Result<ParamHandle<T>>
609	where
610		T: ParamHandleValue,
611	{
612		let name_buf = CString::new(name)?.into_bytes_with_nul();
613		let (param_handle, param_properties) = {
614			let mut param_handle = std::ptr::null_mut();
615			let mut param_properties = std::ptr::null_mut();
616			suite_fn!(paramGetHandle in self.parameter;
617				self.inner, name_buf.as_ptr() as *const _, &mut param_handle as *mut _, &mut param_properties as *mut _)?;
618			(param_handle, param_properties)
619		};
620		Ok(ParamHandle::new(
621			param_handle,
622			param_properties,
623			self.property.clone(),
624			self.parameter.clone(),
625		))
626	}
627
628	pub fn param_define_double(&mut self, name: &str) -> Result<ParamDoubleProperties> {
629		self.param_define(ParamType::Double, name)
630	}
631
632	pub fn param_define_int(&mut self, name: &str) -> Result<ParamIntProperties> {
633		self.param_define(ParamType::Integer, name)
634	}
635
636	pub fn param_define_boolean(&mut self, name: &str) -> Result<ParamBooleanProperties> {
637		self.param_define(ParamType::Boolean, name)
638	}
639
640	pub fn param_define_group(&mut self, name: &str) -> Result<ParamGroupProperties> {
641		self.param_define(ParamType::Group, name)
642	}
643
644	pub fn param_define_page(&mut self, name: &str) -> Result<ParamPageProperties> {
645		self.param_define(ParamType::Page, name)
646	}
647}
648
649impl AsProperties for HostHandle {
650	fn handle(&self) -> OfxPropertySetHandle {
651		self.inner
652	}
653	fn suite(&self) -> *const OfxPropertySuiteV1 {
654		self.property.borrow() as *const _
655	}
656}
657
658impl AsProperties for ImageClipHandle {
659	fn handle(&self) -> OfxPropertySetHandle {
660		self.inner_properties
661	}
662	fn suite(&self) -> *const OfxPropertySuiteV1 {
663		self.property.borrow() as *const _
664	}
665}
666
667impl AsProperties for ImageHandle {
668	fn handle(&self) -> OfxPropertySetHandle {
669		self.inner
670	}
671	fn suite(&self) -> *const OfxPropertySuiteV1 {
672		self.property.borrow() as *const _
673	}
674}
675
676impl<T> AsProperties for ParamHandle<T>
677where
678	T: ParamHandleValue,
679{
680	fn handle(&self) -> OfxPropertySetHandle {
681		self.inner_properties
682	}
683	fn suite(&self) -> *const OfxPropertySuiteV1 {
684		self.property.borrow() as *const _
685	}
686}
687
688mod tests {
689	use super::*;
690	use property;
691	use property::*;
692
693	// do not run, just compile!
694	fn prop_host() {
695		let mut handle = ImageEffectProperties(PropertySetHandle::empty());
696
697		handle.get::<property::Type::Property>();
698		handle.get::<property::IsBackground::Property>();
699	}
700}