use core::marker::Sync;
use libc::c_void;
use objc2::{msg_send, runtime::AnyObject};
use objc2_core_foundation::{CGFloat, CGRect};
#[repr(C)]
pub struct IOSViewObj {
pub view: *mut AnyObject,
pub metal_layer: *mut c_void,
pub maximum_frames: i32,
pub callback_to_swift: extern "C" fn(arg: i32),
}
pub struct AppSurface {
pub view: *mut AnyObject,
pub scale_factor: f32,
pub ctx: crate::IASDQContext,
pub maximum_frames: i32,
pub callback_to_app: Option<extern "C" fn(arg: i32)>,
pub temporary_directory: &'static str,
pub library_directory: &'static str,
}
unsafe impl Sync for AppSurface {}
impl AppSurface {
pub fn new(obj: IOSViewObj) -> Self {
_ = env_logger::try_init();
let scale_factor = get_scale_factor(obj.view);
let s: CGRect = unsafe { msg_send![obj.view, frame] };
let physical = (
(s.size.width as f32 * scale_factor) as u32,
(s.size.height as f32 * scale_factor) as u32,
);
let backends = wgpu::Backends::METAL;
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends,
flags: wgpu::InstanceFlags::default(),
backend_options: wgpu::BackendOptions::default(),
..wgpu::InstanceDescriptor::new_without_display_handle()
});
let surface = unsafe {
instance
.create_surface_unsafe(wgpu::SurfaceTargetUnsafe::CoreAnimationLayer(
obj.metal_layer,
))
.expect("Surface creation failed")
};
let ctx = futures_lite::future::block_on(crate::create_iasdq_context(
instance, surface, physical,
));
AppSurface {
view: obj.view,
scale_factor,
ctx,
callback_to_app: Some(obj.callback_to_swift),
maximum_frames: obj.maximum_frames,
temporary_directory: "",
library_directory: "",
}
}
pub fn get_view_size(&self) -> (u32, u32) {
let s: CGRect = unsafe { msg_send![self.view, frame] };
(
(s.size.width as f32 * self.scale_factor) as u32,
(s.size.height as f32 * self.scale_factor) as u32,
)
}
}
fn get_scale_factor(obj: *mut AnyObject) -> f32 {
let mut _scale_factor: CGFloat = 1.0;
_scale_factor = unsafe { msg_send![obj, contentScaleFactor] };
_scale_factor as f32
}