diff --git a/cidre/pomace/av/av.h b/cidre/pomace/av/av.h index e95ef885..f01b9530 100644 --- a/cidre/pomace/av/av.h +++ b/cidre/pomace/av/av.h @@ -40,6 +40,8 @@ Class AV_AUDIO_PCM_BUFFER; Class AV_AUDIO_COMPRESSED_BUFFER; Class AV_AUDIO_FORMAT; +Class AV_PLAYER; + __attribute__((constructor)) static void mtl_initializer(void) { @@ -76,6 +78,8 @@ static void mtl_initializer(void) AV_AUDIO_PCM_BUFFER = [AVAudioPCMBuffer class]; AV_AUDIO_COMPRESSED_BUFFER = [AVAudioCompressedBuffer class]; + AV_PLAYER = [AVPlayer class]; + initialized = 1; } } diff --git a/cidre/src/av/player.rs b/cidre/src/av/player.rs index 41940e0a..0e5e8633 100644 --- a/cidre/src/av/player.rs +++ b/cidre/src/av/player.rs @@ -1,4 +1,4 @@ -use crate::{define_obj_type, ns}; +use crate::{arc, define_cls, define_obj_type, ns, objc}; pub mod item; pub use item::Item as PlayerItem; @@ -45,4 +45,57 @@ pub enum AudiovisualBackgroundPlaybackPolicy { } define_obj_type!(Player(ns::Id)); + +impl arc::A { + #[objc::msg_send(initWithURL:)] + pub fn init_with_url(self, url: &ns::URL) -> arc::R; + #[objc::msg_send(initWithPlayerItem:)] + pub fn init_with_player_item_throws(self, item: Option<&PlayerItem>) -> arc::R; +} + +impl Player { + define_cls!(AV_PLAYER); + + pub fn with_url(url: &ns::URL) -> arc::R { + Self::alloc().init_with_url(url) + } + + pub fn with_player_item_throws(item: Option<&PlayerItem>) -> arc::R { + Self::alloc().init_with_player_item_throws(item) + } + + pub fn with_player_item<'ar>( + item: Option<&PlayerItem>, + ) -> Result, &'ar ns::Exception> { + ns::try_catch(|| Self::with_player_item_throws(item)) + } + + #[objc::msg_send(status)] + pub fn status(&self) -> Status; + + /// If the receiver's status is Status::Failed, this describes the error that caused the failure. + /// + /// The value of this property is an ns::Error that describes what caused the receiver to no longer be able to play items. + /// If the receiver's status is not Status::Failed, the value of this property is nil. + #[objc::msg_send(error)] + pub fn error(&self) -> Option<&ns::Error>; +} + define_obj_type!(QueuePlayer(Player)); + +#[link(name = "av", kind = "static")] +extern "C" { + static AV_PLAYER: &'static objc::Class; +} + +#[cfg(test)] +mod tests { + use crate::{av, ns}; + + #[test] + fn basics() { + let url = ns::URL::with_str("file:///tmp/file.mp4").expect("Url is not valid"); + let player = av::Player::with_url(&url); + assert_eq!(player.status(), av::PlayerStatus::Unknown); + } +} diff --git a/cidre/src/dispatch/queue.rs b/cidre/src/dispatch/queue.rs index f20f58d7..77dadabf 100644 --- a/cidre/src/dispatch/queue.rs +++ b/cidre/src/dispatch/queue.rs @@ -58,6 +58,7 @@ impl Priority { pub const BACKGROUND: Self = Self(-1 << 15); } +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)] #[repr(usize)] pub enum AutoreleaseFrequency { Inherit = 0, @@ -93,7 +94,7 @@ impl Queue { } #[inline] - pub fn main() -> &'static Queue { + pub fn main() -> &'static Main { Main::default() } @@ -124,11 +125,13 @@ impl Queue { unsafe { Self::global_with_flags(identifier, 0) } } + #[doc(alias = "dispatch_get_global_queue")] #[inline] pub unsafe fn global_with_flags<'a>(identifier: isize, flags: usize) -> Option<&'a Global> { dispatch_get_global_queue(identifier, flags) } + #[doc(alias = "dispatch_sync")] #[inline] pub fn sync_b(&self, block: &mut B) where @@ -139,6 +142,7 @@ impl Queue { } } + #[doc(alias = "dispatch_async")] #[inline] pub fn async_b + Sync>(&self, block: &'static mut B) { unsafe { @@ -178,41 +182,49 @@ impl Queue { self.async_b(block.escape()); } + #[doc(alias = "dispatch_async_f")] #[inline] pub fn async_f(&self, context: *mut T, work: Function) { unsafe { dispatch_async_f(self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_sync_f")] #[inline] pub fn sync_f(&self, context: *mut T, work: Function) { unsafe { dispatch_sync_f(self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_async_and_wait_f")] #[inline] pub fn async_and_wait_f(&self, context: *mut T, work: Function) { unsafe { dispatch_async_and_wait_f(self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_after_f")] #[inline] pub fn after_f(&self, when: super::Time, context: *mut T, work: Function) { unsafe { dispatch_after_f(when, self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_barrier_async_f")] #[inline] pub fn barrier_async_f(&self, context: *mut T, work: Function) { unsafe { dispatch_barrier_async_f(self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_barrier_sync_f")] #[inline] pub fn barrier_sync_f(&self, context: *mut T, work: Function) { unsafe { dispatch_barrier_sync_f(self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_barrier_async_and_wait_f")] #[inline] pub fn barrier_async_and_wait_f(&self, context: *mut T, work: Function) { unsafe { dispatch_barrier_async_and_wait_f(self, context as _, transmute(work)) } } + #[doc(alias = "dispatch_group_async_f")] #[inline] pub fn group_async_f(&self, group: &super::Group, context: *mut T, work: Function) { unsafe { dispatch_group_async_f(group, self, context as _, transmute(work)) }