Skip to content

Commit 1ffd181

Browse files
committed
wip
1 parent 285c6ea commit 1ffd181

7 files changed

Lines changed: 110 additions & 14 deletions

File tree

examples/plugin_clack/src/audio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clack_plugin::prelude::*;
33

44
pub struct ExamplePluginAudioProcessor;
55

6-
impl<'a> PluginAudioProcessor<'a, (), ExamplePluginMainThread> for ExamplePluginAudioProcessor {
6+
impl<'a> PluginAudioProcessor<'a, (), ExamplePluginMainThread<'a>> for ExamplePluginAudioProcessor {
77
fn activate(
88
_host: HostAudioProcessorHandle<'a>, _main_thread: &mut ExamplePluginMainThread,
99
_shared: &'a (), _audio_config: PluginAudioConfiguration,

examples/plugin_clack/src/gui.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@ use crate::window_handler::OpenWindowExample;
22
use crate::ExamplePluginMainThread;
33
use baseview::dpi::*;
44
use baseview::gl::GlConfig;
5-
use baseview::{WindowHandle, WindowOpenOptions, WindowSize};
5+
use baseview::host::{Host, HostCallbacks, HostMainThreadCaller};
6+
use baseview::{HandlerError, WindowHandle, WindowOpenOptions, WindowSize};
67
use clack_extensions::gui::{
7-
AspectRatioStrategy, GuiApiType, GuiConfiguration, GuiResizeHints, GuiSize, PluginGuiImpl,
8-
Window as ClapWindow,
8+
AspectRatioStrategy, GuiApiType, GuiConfiguration, GuiResizeHints, GuiSize, HostGui,
9+
PluginGuiImpl, Window as ClapWindow,
910
};
1011
use clack_plugin::plugin::PluginError;
11-
12+
use clack_plugin::prelude::{HostMainThreadHandle, HostSharedHandle};
1213
#[allow(deprecated)]
1314
use raw_window_handle::HasRawWindowHandle;
1415

1516
pub struct ExamplePluginGui {
1617
handle: WindowHandle,
1718
}
1819

19-
impl PluginGuiImpl for ExamplePluginMainThread {
20+
impl PluginGuiImpl for ExamplePluginMainThread<'_> {
2021
fn is_api_supported(&mut self, configuration: GuiConfiguration) -> bool {
2122
!configuration.is_floating
2223
&& Some(configuration.api_type) == GuiApiType::default_for_current_platform()
@@ -97,7 +98,17 @@ impl PluginGuiImpl for ExamplePluginMainThread {
9798
.with_gl_config(GlConfig::default())
9899
.with_parent(&parent);
99100

100-
let window = baseview::create_window(options, OpenWindowExample::new)?;
101+
let mut host = Host::new().with_main_thread(unsafe {
102+
MainThreadHandler { host: self.host.shared().with_arbitrary_lifetime() }
103+
});
104+
105+
if let Some(gui) = self.host_gui {
106+
host = host.with_callbacks(unsafe {
107+
HostGuiCallbacks { ext: gui, host: self.host.with_arbitrary_lifetime() }
108+
});
109+
}
110+
111+
let window = baseview::create_window_with_host(options, OpenWindowExample::new, host)?;
101112

102113
self.gui = Some(ExamplePluginGui { handle: window });
103114

@@ -145,3 +156,30 @@ fn gui_size_to_window_size(size: GuiSize) -> Size {
145156
Size::Physical(PhysicalSize::new(size.width, size.height))
146157
}
147158
}
159+
160+
struct MainThreadHandler {
161+
host: HostSharedHandle<'static>,
162+
}
163+
164+
impl HostMainThreadCaller for MainThreadHandler {
165+
fn call_main_thread(&mut self) {
166+
self.host.request_callback();
167+
}
168+
}
169+
170+
struct HostGuiCallbacks {
171+
ext: HostGui,
172+
host: HostMainThreadHandle<'static>,
173+
}
174+
175+
impl HostCallbacks for HostGuiCallbacks {
176+
fn resized(&mut self, new_size: WindowSize) -> Result<(), HandlerError> {
177+
let size = window_size_to_gui_size(new_size);
178+
self.ext.request_resize(&self.host, size.width, size.height)?;
179+
Ok(())
180+
}
181+
182+
fn destroyed(&mut self) {
183+
self.ext.closed(&self.host, true);
184+
}
185+
}

examples/plugin_clack/src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::audio::ExamplePluginAudioProcessor;
22
use crate::gui::ExamplePluginGui;
3-
use clack_extensions::gui::PluginGui;
3+
use clack_extensions::gui::{HostGui, PluginGui};
44
use clack_plugin::prelude::*;
55

66
mod audio;
@@ -15,7 +15,7 @@ pub struct ExamplePlugin;
1515
impl Plugin for ExamplePlugin {
1616
type AudioProcessor<'a> = ExamplePluginAudioProcessor;
1717
type Shared<'a> = ();
18-
type MainThread<'a> = ExamplePluginMainThread;
18+
type MainThread<'a> = ExamplePluginMainThread<'a>;
1919

2020
fn declare_extensions(builder: &mut PluginExtensions<Self>, _shared: Option<&()>) {
2121
builder.register::<PluginGui>();
@@ -35,19 +35,23 @@ impl DefaultPluginFactory for ExamplePlugin {
3535
}
3636

3737
fn new_main_thread<'a>(
38-
_host: HostMainThreadHandle<'a>, _shared: &'a Self::Shared<'a>,
38+
host: HostMainThreadHandle<'a>, _shared: &'a Self::Shared<'a>,
3939
) -> Result<Self::MainThread<'a>, PluginError> {
40-
Ok(Self::MainThread { gui: None })
40+
Ok(Self::MainThread { gui: None, host_gui: host.get_extension(), host })
4141
}
4242
}
4343

4444
/// The data that belongs to the main thread of our plugin.
45-
pub struct ExamplePluginMainThread {
45+
pub struct ExamplePluginMainThread<'a> {
46+
/// The host handle
47+
host: HostMainThreadHandle<'a>,
48+
// The host GUI extension handle
49+
host_gui: Option<HostGui>,
4650
/// The plugin's GUI state and context
4751
gui: Option<ExamplePluginGui>,
4852
}
4953

50-
impl<'a> PluginMainThread<'a, ()> for ExamplePluginMainThread {
54+
impl<'a> PluginMainThread<'a, ()> for ExamplePluginMainThread<'a> {
5155
fn on_main_thread(&mut self) {}
5256
}
5357

src/host.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::{HandlerError, WindowSize};
2+
3+
pub trait HostMainThreadCaller: Send + 'static {
4+
fn call_main_thread(&mut self);
5+
}
6+
7+
pub trait HostCallbacks: 'static {
8+
fn resized(&mut self, new_size: WindowSize) -> Result<(), HandlerError>;
9+
fn destroyed(&mut self);
10+
}
11+
12+
pub struct Host {
13+
pub(crate) main_thread: Option<Box<dyn HostMainThreadCaller>>,
14+
pub(crate) callbacks: Option<Box<dyn HostCallbacks>>,
15+
}
16+
17+
impl Default for Host {
18+
fn default() -> Self {
19+
Self::new()
20+
}
21+
}
22+
23+
impl Host {
24+
pub fn new() -> Self {
25+
Self { main_thread: None, callbacks: None }
26+
}
27+
28+
pub fn with_main_thread(mut self, main_thread: impl HostMainThreadCaller) -> Self {
29+
self.main_thread = Some(Box::new(main_thread));
30+
self
31+
}
32+
33+
pub fn with_callbacks(mut self, callbacks: impl HostCallbacks) -> Self {
34+
self.callbacks = Some(Box::new(callbacks));
35+
self
36+
}
37+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod context;
33
mod error;
44
mod event;
55
mod handler;
6+
pub mod host;
67
mod keyboard;
78
mod mouse_cursor;
89
mod tracing;

src/platform/x11/window_thread.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::*;
22
use crate::handler::WindowHandlerBuilder;
3+
use crate::host::Host;
34
use crate::platform::x11::event_loop::EventLoop;
45
use crate::platform::x11::window_shared::WindowInner;
56
use crate::{WindowContext, WindowOpenOptions, WindowSize};
@@ -75,7 +76,7 @@ pub struct WindowThreadHandle {
7576

7677
impl WindowThreadHandle {
7778
pub fn create_window(
78-
options: WindowOpenOptions, handler: WindowHandlerBuilder,
79+
options: WindowOpenOptions, handler: WindowHandlerBuilder, host: Host,
7980
) -> Result<Self> {
8081
let (tx, rx) = result_channel();
8182
let shared = Arc::new(WindowThreadShared::new());
@@ -84,6 +85,7 @@ impl WindowThreadHandle {
8485

8586
let join_handle = {
8687
let shared = shared.clone();
88+
let main_thread_caller = host.main_thread;
8789

8890
thread::spawn(move || {
8991
let thread = match WindowThread::create(

src/window.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::handler::WindowHandlerBuilder;
2+
use crate::host::Host;
23
use crate::platform;
34
use crate::*;
45
use dpi::{LogicalSize, PhysicalSize, Pixel, Size};
@@ -69,15 +70,28 @@ impl WindowHandle {
6970
pub fn is_open(&self) -> bool {
7071
self.window_handle.is_open()
7172
}
73+
74+
pub fn host_main_thread_callback(&mut self) {
75+
todo!()
76+
}
7277
}
7378

7479
pub fn create_window<H: WindowHandler>(
7580
builder: WindowOpenOptions,
7681
handler: impl FnOnce(WindowContext) -> Result<H, HandlerError> + Send + 'static,
82+
) -> Result<WindowHandle, Error> {
83+
create_window_with_host(builder, handler, None)
84+
}
85+
86+
pub fn create_window_with_host<H: WindowHandler>(
87+
builder: WindowOpenOptions,
88+
handler: impl FnOnce(WindowContext) -> Result<H, HandlerError> + Send + 'static,
89+
host: impl Into<Option<Host>>,
7790
) -> Result<WindowHandle, Error> {
7891
Ok(WindowHandle::new(platform::WindowHandle::create_window(
7992
builder,
8093
WindowHandlerBuilder::new(handler),
94+
host.into().unwrap_or_else(Host::default),
8195
)?))
8296
}
8397

0 commit comments

Comments
 (0)