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