Skip to content

Commit

Permalink
Make Opaque a newtype
Browse files Browse the repository at this point in the history
And add Sync to its bounds

Fixes: xiph#2641
  • Loading branch information
lu-zero committed Jan 15, 2021
1 parent 1b1ebcd commit b72d254
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/api/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@ fn send_frame_kf<T: Pixel>(ctx: &mut Context<T>, keyframe: bool) {
let frame_type_override =
if keyframe { FrameTypeOverride::Key } else { FrameTypeOverride::No };

let opaque = Some(Box::new(keyframe) as Box<dyn std::any::Any + Send>);
let opaque = Some(Opaque::new(keyframe));

let fp = FrameParameters { frame_type_override, opaque };

Expand Down
22 changes: 21 additions & 1 deletion src/api/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,27 @@ use std::sync::Arc;
use thiserror::*;

/// Opaque type to be passed from Frame to Packet
pub type Opaque = Box<dyn Any + Send>;
#[derive(Debug)]
pub struct Opaque(Box<dyn Any + Send + Sync>);

impl Opaque {
/// Wrap a type in the opaque struct
pub fn new<T: Any + Send + Sync>(t: T) -> Self {
Opaque(Box::new(t) as Box<dyn Any + Send + Sync>)
}

/// Attempt to downcast the opaque to a concrete type.
pub fn downcast<T: Any + Send + Sync>(self) -> Result<Box<T>, Opaque> {
if self.0.is::<T>() {
unsafe {
let raw: *mut (dyn Any + Send + Sync) = Box::into_raw(self.0);
Ok(Box::from_raw(raw as *mut T))
}
} else {
Err(self)
}
}
}

// TODO: use the num crate?
/// A rational number.
Expand Down
3 changes: 2 additions & 1 deletion src/capi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct FrameOpaque {
}

unsafe impl Send for FrameOpaque {}
unsafe impl Sync for FrameOpaque {}

impl Default for FrameOpaque {
fn default() -> Self {
Expand Down Expand Up @@ -1062,7 +1063,7 @@ pub unsafe extern fn rav1e_send_frame(
let maybe_opaque = if frame.is_null() {
None
} else {
(*frame).opaque.take().map(|o| Box::new(o) as rav1e::Opaque)
(*frame).opaque.take().map(|o| rav1e::Opaque::new(o))
};

let ret = (*ctx)
Expand Down

0 comments on commit b72d254

Please sign in to comment.