From 2fd02c7e68fa14de9796bd14e4c61e96673a9412 Mon Sep 17 00:00:00 2001 From: Jasper Hugo Date: Tue, 17 Aug 2021 08:55:17 +0700 Subject: [PATCH] provide a ctx argument for the C API callbacks --- lib-gst-meet-c/include/gstmeet.h | 3 ++- lib-gst-meet-c/src/lib.rs | 46 ++++++++++++++++++-------------- lib-gst-meet/src/conference.rs | 29 +++++--------------- shell.nix | 3 +++ 4 files changed, 38 insertions(+), 43 deletions(-) diff --git a/lib-gst-meet-c/include/gstmeet.h b/lib-gst-meet-c/include/gstmeet.h index 8b5654a..bdfc3e8 100644 --- a/lib-gst-meet-c/include/gstmeet.h +++ b/lib-gst-meet-c/include/gstmeet.h @@ -67,6 +67,7 @@ GstElement *gstmeet_conference_video_sink_element(struct Context *context, void gstmeet_conference_on_participant(struct Context *context, JitsiConference *conference, - GstBin *(*f)(struct Participant)); + GstBin *(*f)(struct Participant, void *), + void *callback_context); #endif /* gstmeet_h */ diff --git a/lib-gst-meet-c/src/lib.rs b/lib-gst-meet-c/src/lib.rs index 38f35f9..ac3ca9f 100644 --- a/lib-gst-meet-c/src/lib.rs +++ b/lib-gst-meet-c/src/lib.rs @@ -1,7 +1,8 @@ use std::{ - ffi::{CStr, CString}, + ffi::{CStr, CString, c_void}, os::raw::c_char, ptr, + sync::{Arc, atomic::{AtomicPtr, Ordering}}, }; use anyhow::Result; @@ -186,26 +187,31 @@ pub unsafe extern "C" fn gstmeet_conference_video_sink_element(context: *mut Con pub unsafe extern "C" fn gstmeet_conference_on_participant( context: *mut Context, conference: *mut JitsiConference, - f: unsafe extern "C" fn(Participant) -> *mut gstreamer::ffi::GstBin, + f: unsafe extern "C" fn(Participant, *mut c_void) -> *mut gstreamer::ffi::GstBin, + ctx: *mut c_void, ) { + let ctx = Arc::new(AtomicPtr::new(ctx)); (*context) .runtime - .block_on((*conference).on_participant(move |participant| Box::pin(async move { - let participant = Participant { - jid: CString::new(participant.jid.to_string())?.into_raw() as *const _, - muc_jid: CString::new(participant.muc_jid.to_string())?.into_raw() as *const _, - nick: participant - .nick - .map(|nick| Ok::<_, anyhow::Error>(CString::new(nick)?.into_raw() as *const _)) - .transpose()? - .unwrap_or_else(ptr::null), - }; - let maybe_bin = f(participant); - if maybe_bin.is_null() { - Ok(None) - } - else { - Ok(Some(from_glib_full(maybe_bin))) - } - }))); + .block_on((*conference).on_participant(move |participant| { + let ctx = ctx.clone(); + Box::pin(async move { + let participant = Participant { + jid: CString::new(participant.jid.to_string())?.into_raw() as *const _, + muc_jid: CString::new(participant.muc_jid.to_string())?.into_raw() as *const _, + nick: participant + .nick + .map(|nick| Ok::<_, anyhow::Error>(CString::new(nick)?.into_raw() as *const _)) + .transpose()? + .unwrap_or_else(ptr::null), + }; + let maybe_bin = f(participant, ctx.load(Ordering::Relaxed)); + if maybe_bin.is_null() { + Ok(None) + } + else { + Ok(Some(from_glib_full(maybe_bin))) + } + }) + })); } \ No newline at end of file diff --git a/lib-gst-meet/src/conference.rs b/lib-gst-meet/src/conference.rs index 46772b8..450b28f 100644 --- a/lib-gst-meet/src/conference.rs +++ b/lib-gst-meet/src/conference.rs @@ -94,17 +94,14 @@ pub struct Participant { bin: Option, } +type BoxedBinResultFuture = Pin>> + Send>>; +type BoxedResultFuture = Pin> + Send>>; + pub(crate) struct JitsiConferenceInner { pub(crate) jingle_session: Option, participants: HashMap, - on_participant: Option< - Arc< - dyn (Fn(Participant) -> Pin>> + Send>>) - + Send - + Sync, - >, - >, - on_participant_left: Option Pin> + Send>>) + Send + Sync>>, + on_participant: Option BoxedBinResultFuture) + Send + Sync>>, + on_participant_left: Option BoxedResultFuture) + Send + Sync>>, state: JitsiConferenceState, connected_tx: Option>, connected_rx: Option>, @@ -273,13 +270,7 @@ impl JitsiConference { } #[tracing::instrument(level = "trace", skip(f))] - pub async fn on_participant( - &self, - f: impl (Fn(Participant) -> Pin>> + Send>>) - + Send - + Sync - + 'static, - ) { + pub async fn on_participant(&self, f: impl (Fn(Participant) -> BoxedBinResultFuture) + Send + Sync + 'static) { let f = Arc::new(f); let f2 = f.clone(); let existing_participants: Vec<_> = { @@ -320,13 +311,7 @@ impl JitsiConference { } #[tracing::instrument(level = "trace", skip(f))] - pub async fn on_participant_left( - &self, - f: impl (Fn(Participant) -> Pin> + Send>>) - + Send - + Sync - + 'static, - ) { + pub async fn on_participant_left(&self, f: impl (Fn(Participant) -> BoxedResultFuture) + Send + Sync + 'static) { self.inner.lock().await.on_participant_left = Some(Arc::new(f)); } } diff --git a/shell.nix b/shell.nix index 11040dd..d08a169 100644 --- a/shell.nix +++ b/shell.nix @@ -4,6 +4,7 @@ mkShell { buildInputs = [ pkg-config glib + glib-networking gst_all_1.gstreamer gst_all_1.gst-plugins-base gst_all_1.gst-plugins-good @@ -13,4 +14,6 @@ mkShell { darwin.apple_sdk.frameworks.AppKit darwin.apple_sdk.frameworks.Security ] else []); + + GIO_EXTRA_MODULES = ["${pkgs.glib-networking.out}/lib/gio/modules"]; }