#![allow(unsafe_code)]
use alloc::sync::Arc;
use bevy_ecs::prelude::Component;
use core::{any::Any, marker::PhantomData, ops::Deref};
use raw_window_handle::{
DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle,
RawWindowHandle, WindowHandle,
};
use std::sync::Mutex;
#[derive(Debug)]
pub struct WindowWrapper<W> {
reference: Arc<dyn Any + Send + Sync>,
ty: PhantomData<W>,
}
impl<W: Send + Sync + 'static> WindowWrapper<W> {
pub fn new(window: W) -> WindowWrapper<W> {
WindowWrapper {
reference: Arc::new(window),
ty: PhantomData,
}
}
}
impl<W: 'static> Deref for WindowWrapper<W> {
type Target = W;
fn deref(&self) -> &Self::Target {
self.reference.downcast_ref::<W>().unwrap()
}
}
#[derive(Debug, Clone, Component)]
pub struct RawHandleWrapper {
_window: Arc<dyn Any + Send + Sync>,
pub window_handle: RawWindowHandle,
pub display_handle: RawDisplayHandle,
}
impl RawHandleWrapper {
pub fn new<W: HasWindowHandle + HasDisplayHandle + 'static>(
window: &WindowWrapper<W>,
) -> Result<RawHandleWrapper, HandleError> {
Ok(RawHandleWrapper {
_window: window.reference.clone(),
window_handle: window.window_handle()?.as_raw(),
display_handle: window.display_handle()?.as_raw(),
})
}
pub unsafe fn get_handle(&self) -> ThreadLockedRawWindowHandleWrapper {
ThreadLockedRawWindowHandleWrapper(self.clone())
}
}
unsafe impl Send for RawHandleWrapper {}
unsafe impl Sync for RawHandleWrapper {}
pub struct ThreadLockedRawWindowHandleWrapper(RawHandleWrapper);
impl HasWindowHandle for ThreadLockedRawWindowHandleWrapper {
fn window_handle(&self) -> Result<WindowHandle, HandleError> {
Ok(unsafe { WindowHandle::borrow_raw(self.0.window_handle) })
}
}
impl HasDisplayHandle for ThreadLockedRawWindowHandleWrapper {
fn display_handle(&self) -> Result<DisplayHandle, HandleError> {
Ok(unsafe { DisplayHandle::borrow_raw(self.0.display_handle) })
}
}
#[derive(Debug, Clone, Component)]
pub struct RawHandleWrapperHolder(pub Arc<Mutex<Option<RawHandleWrapper>>>);