vapoursynth4_rs/
plugin.rs1pub mod plugin_function;
2pub mod types;
3
4use std::{borrow::Borrow, ffi::CStr, ptr::NonNull};
5
6use crate::{api::Api, core::Core, ffi, map::Map};
7
8pub use plugin_function::*;
9pub use types::*;
10
11#[derive(PartialEq, Eq, Hash, Debug)]
12pub struct Plugin {
13 handle: NonNull<ffi::VSPlugin>,
14 api: Api,
15}
16
17impl Plugin {
18 #[must_use]
19 pub fn new(handle: NonNull<ffi::VSPlugin>, api: Api) -> Self {
20 Self { handle, api }
21 }
22
23 #[must_use]
24 pub fn as_ptr(&self) -> *const ffi::VSPlugin {
25 self.handle.as_ptr()
26 }
27
28 #[must_use]
29 pub fn name(&self) -> &CStr {
30 unsafe {
31 let ptr = (self.api.getPluginName)(self.as_ptr().cast_mut());
32 CStr::from_ptr(ptr)
33 }
34 }
35
36 #[must_use]
37 pub fn id(&self) -> &CStr {
38 unsafe {
39 let ptr = (self.api.getPluginID)(self.as_ptr().cast_mut());
40 CStr::from_ptr(ptr)
41 }
42 }
43
44 #[must_use]
45 pub fn namespace(&self) -> &CStr {
46 unsafe {
47 let ptr = (self.api.getPluginNamespace)(self.as_ptr().cast_mut());
48 CStr::from_ptr(ptr)
49 }
50 }
51
52 #[must_use]
53 pub fn invoke(&self, name: &CStr, args: impl Borrow<Map>) -> Map {
54 unsafe {
55 let ptr = (self.api.invoke)(
56 self.as_ptr().cast_mut(),
57 name.as_ptr(),
58 args.borrow().as_ptr(),
59 );
60 Map::from_ptr(ptr, self.api)
61 }
62 }
63
64 #[must_use]
65 pub fn functions(&self) -> Functions<'_> {
66 Functions::new(self)
67 }
68
69 #[must_use]
70 pub fn get_function_by_name(&self, name: &CStr) -> Option<PluginFunction> {
71 unsafe {
72 NonNull::new((self.api.getPluginFunctionByName)(
73 name.as_ptr(),
74 self.as_ptr().cast_mut(),
75 ))
76 }
77 .map(|handle| PluginFunction::from_ptr(handle, self.api))
78 }
79
80 #[must_use]
81 pub fn path(&self) -> &CStr {
82 unsafe {
83 let ptr = (self.api.getPluginPath)(self.as_ptr().cast_mut());
84 CStr::from_ptr(ptr)
85 }
86 }
87
88 #[must_use]
89 pub fn version(&self) -> i32 {
90 unsafe { (self.api.getPluginVersion)(self.as_ptr().cast_mut()) }
91 }
92}
93
94#[derive(Clone, PartialEq, Eq, Hash, Debug)]
95pub struct Plugins<'c> {
96 cursor: *mut ffi::VSPlugin,
97 core: &'c Core,
98}
99
100impl<'c> Plugins<'c> {
101 pub(crate) fn new(core: &'c Core) -> Plugins<'c> {
102 Self {
103 cursor: std::ptr::null_mut(),
104 core,
105 }
106 }
107}
108
109impl Iterator for Plugins<'_> {
110 type Item = Plugin;
111
112 fn next(&mut self) -> Option<Self::Item> {
113 unsafe {
114 let api = self.core.api();
115 let ptr = (api.getNextPlugin)(self.cursor, self.core.as_ptr());
116 NonNull::new(ptr).map(|p| {
117 self.cursor = ptr;
118 Plugin::new(p, api)
119 })
120 }
121 }
122}
123
124#[macro_export]
125macro_rules! declare_plugin {
126 ($id:literal, $name:literal, $desc:literal,
127 $version:expr,
128 $api_version:expr, $flags:expr
129 $(, ($filter:tt, $data:expr) )*
130 ) => {
131 #[unsafe(no_mangle)]
132 pub unsafe extern "system-unwind" fn VapourSynthPluginInit2(
133 plugin: *mut $crate::ffi::VSPlugin,
134 vspapi: *const $crate::ffi::VSPLUGINAPI,
135 ) {
136 unsafe {
137 ((*vspapi).configPlugin)(
138 $id.as_ptr(),
139 $name.as_ptr(),
140 $desc.as_ptr(),
141 $crate::utils::make_version($version.0, $version.1),
142 $crate::VAPOURSYNTH_API_VERSION,
143 $flags,
144 plugin,
145 );
146
147 $(
148 $crate::node::FilterRegister::<$filter>::new($data).register(plugin, vspapi);
149 )*
150 }
151 }
152 };
153}