Skip to content

Commit

Permalink
wip leak fix
Browse files Browse the repository at this point in the history
  • Loading branch information
1313 committed Oct 24, 2024
1 parent f920764 commit 79da597
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 64 deletions.
33 changes: 0 additions & 33 deletions src/stream/internal/ffi_utils.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/stream/internal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub mod ffi_utils;
pub mod output_handler;
pub mod sc_stream;
pub mod stream_delegate;
31 changes: 20 additions & 11 deletions src/stream/internal/output_handler.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,63 @@
use std::{ffi::c_void, sync::Once};

use objc::{
rc,
class,
declare::ClassDecl,
runtime::{self, Object, Sel},
sel, sel_impl,
};

use crate::{
declare_trait_wrapper,
stream::{
sc_stream_output_trait::SCStreamOutputTrait, sc_stream_output_type::SCStreamOutputType,
},
utils::objc::get_concrete_from_void,
};

declare_trait_wrapper!(OutputTraitWrapper, SCStreamOutputTrait);
#[repr(transparent)]
pub struct OutputTraitWrapper<T: SCStreamOutputTrait>(T);

unsafe impl<T: SCStreamOutputTrait> objc::Encode for OutputTraitWrapper<T> {
fn encode() -> objc::Encoding {
unsafe { objc::Encoding::from_str("@") }
}
}

type StreamOutputMethod =
extern "C" fn(&Object, Sel, *mut Object, *const c_void, SCStreamOutputType);
extern "C" fn stream_output(
extern "C" fn stream_output<T: SCStreamOutputTrait>(
this: &Object,
_cmd: Sel,
_stream_ref: *mut Object,
sample_buffer_ref: *const c_void,
of_type: SCStreamOutputType,
) {
let stream_output: &OutputTraitWrapper = unsafe { this.get_ivar("output_handler_wrapper") };
let stream_output: &OutputTraitWrapper<T> = unsafe { this.get_ivar("output_handler_wrapper") };
let sample_buffer = unsafe { get_concrete_from_void(sample_buffer_ref) };
stream_output.did_output_sample_buffer(sample_buffer, of_type);
stream_output
.0
.did_output_sample_buffer(sample_buffer, of_type);
}

fn register() {
fn register<T: SCStreamOutputTrait>() {
let mut decl =
ClassDecl::new("StreamOutput", class!(NSObject)).expect("Could not register class");
unsafe {
let output_handler: StreamOutputMethod = stream_output;
decl.add_ivar::<OutputTraitWrapper>("output_handler_wrapper");
let output_handler: StreamOutputMethod = stream_output::<T>;
decl.add_ivar::<OutputTraitWrapper<T>>("output_handler_wrapper");
decl.add_method(sel!(stream:didOutputSampleBuffer:ofType:), output_handler);
decl.register();
}
}
pub type SCStreamOutput = *mut Object;
pub fn get_handler<'a>(handler: impl SCStreamOutputTrait + 'a) -> SCStreamOutput {
pub fn get_handler<T: SCStreamOutputTrait>(handler: T) -> SCStreamOutput {
static REGISTER_ONCE: Once = Once::new();
REGISTER_ONCE.call_once(register);
REGISTER_ONCE.call_once(register::<T>);

unsafe {
let sc_handler = runtime::class_createInstance(class!(StreamOutput), 0);
let wrapper = OutputTraitWrapper::new(handler);
let wrapper = OutputTraitWrapper(handler);
(*sc_handler).set_ivar("output_handler_wrapper", wrapper);
sc_handler
}
Expand Down
48 changes: 29 additions & 19 deletions src/stream/internal/stream_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,76 +9,86 @@ use objc::{
};

use crate::{
declare_trait_wrapper, stream::sc_stream_delegate_trait::SCStreamDelegateTrait,
stream::sc_stream_delegate_trait::SCStreamDelegateTrait,
utils::objc::get_concrete_from_void,
};

use super::sc_stream::SCStream;

declare_trait_wrapper!(StreamDelegateTraitWrapper, SCStreamDelegateTrait);
#[repr(transparent)]
pub struct SCStreamDelegateTraitWrapper<T: SCStreamDelegateTrait>(T);

unsafe impl<T: SCStreamDelegateTrait> objc::Encode for SCStreamDelegateTraitWrapper<T> {
fn encode() -> objc::Encoding {
unsafe { objc::Encoding::from_str("@") }
}
}
type DidStopWithErrorMethod = extern "C" fn(&Object, Sel, *const c_void, *const c_void);
extern "C" fn did_stop_with_error(
extern "C" fn did_stop_with_error<T: SCStreamDelegateTrait>(
this: &Object,
_cmd: Sel,
stream_ref: *const c_void,
error: *const c_void,
) {
let handler = unsafe { this.get_ivar::<StreamDelegateTraitWrapper>("stream_delegate_wrapper") };
let handler: &SCStreamDelegateTraitWrapper<T> =
unsafe { this.get_ivar("stream_delegate_wrapper") };
let stream = unsafe { get_concrete_from_void::<SCStream>(stream_ref) };
let error: CFError = unsafe { get_concrete_from_void(error) };
handler.did_stop_with_error(stream, error);
handler.0.did_stop_with_error(stream, error);
}

type OutputVideoEffectDidStartForStreamMethod = extern "C" fn(&Object, Sel, *const c_void);
extern "C" fn output_video_effect_did_start_for_stream(
extern "C" fn output_video_effect_did_start_for_stream<T: SCStreamDelegateTrait>(
this: &Object,
_cmd: Sel,
stream_ref: *const c_void,
) {
let handler = unsafe { this.get_ivar::<StreamDelegateTraitWrapper>("stream_delegate_wrapper") };
let handler: &SCStreamDelegateTraitWrapper<T> =
unsafe { this.get_ivar("stream_delegate_wrapper") };
let stream = unsafe { get_concrete_from_void::<SCStream>(stream_ref) };
handler.output_video_effect_did_start_for_stream(stream);
handler.0.output_video_effect_did_start_for_stream(stream);
}
type OutputVideoEffectDidStopForStreamMethod = extern "C" fn(&Object, Sel, *const c_void);
extern "C" fn output_video_effect_did_stop_for_stream(
extern "C" fn output_video_effect_did_stop_for_stream<T: SCStreamDelegateTrait>(
this: &Object,
_cmd: Sel,
stream_ref: *const c_void,
) {
let handler = unsafe { this.get_ivar::<StreamDelegateTraitWrapper>("stream_delegate_wrapper") };
let handler: &SCStreamDelegateTraitWrapper<T> =
unsafe { this.get_ivar("stream_delegate_wrapper") };
let stream = unsafe { get_concrete_from_void::<SCStream>(stream_ref) };
handler.output_video_effect_did_stop_for_stream(stream);
handler.0.output_video_effect_did_stop_for_stream(stream);
}

fn register() {
fn register<T: SCStreamDelegateTrait>() {
let mut decl =
ClassDecl::new("StreamDelegate", class!(NSObject)).expect("Could not register class");
unsafe {
decl.add_ivar::<StreamDelegateTraitWrapper>("stream_delegate_wrapper");
decl.add_ivar::<SCStreamDelegateTraitWrapper<T>>("stream_delegate_wrapper");
decl.add_method(
sel!(stream:didStopWithError:),
did_stop_with_error as DidStopWithErrorMethod,
did_stop_with_error::<T> as DidStopWithErrorMethod,
);
decl.add_method(
sel!(outputVideoEffectDidStartForStream:),
output_video_effect_did_start_for_stream as OutputVideoEffectDidStartForStreamMethod,
output_video_effect_did_start_for_stream::<T>
as OutputVideoEffectDidStartForStreamMethod,
);
decl.add_method(
sel!(outputVideoEffectDidStopForStream:),
output_video_effect_did_stop_for_stream as OutputVideoEffectDidStopForStreamMethod,
output_video_effect_did_stop_for_stream::<T> as OutputVideoEffectDidStopForStreamMethod,
);
decl.register();
}
}

pub fn get_handler<'a>(handler: impl SCStreamDelegateTrait + 'a) -> *mut Object {
pub fn get_handler<T: SCStreamDelegateTrait>(handler: T) -> *mut Object {
static REGISTER_ONCE: Once = Once::new();
REGISTER_ONCE.call_once(register);
REGISTER_ONCE.call_once(register::<T>);

unsafe {
let error_delegate = runtime::class_createInstance(class!(StreamDelegate), 0);
let wrapper = StreamDelegateTraitWrapper::new(handler);
let wrapper = SCStreamDelegateTraitWrapper(handler);
(*error_delegate).set_ivar("stream_delegate_wrapper", wrapper);
error_delegate
}
Expand Down

0 comments on commit 79da597

Please sign in to comment.