Created
November 6, 2025 16:46
-
-
Save marler8997/553f9c70834d9983073f8f95b71a4641 to your computer and use it in GitHub Desktop.
C++ Opaque Concrete Pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/linux/src/Engine.cpp b/linux/src/Engine.cpp | |
| index 41481be07..9a413e412 100644 | |
| --- a/linux/src/Engine.cpp | |
| +++ b/linux/src/Engine.cpp | |
| @@ -117,6 +117,24 @@ namespace | |
| std::vector<std::string> slugs; | |
| } global_personal_call_url; | |
| + | |
| + // defines conversion functions between the "opaque types" used by zig | |
| + // and the concrete types in C++ | |
| + #define DEFINE_OPAQUE_CONCRETE(Opaque, Concrete) \ | |
| + Opaque* opaque(Concrete* c) { return reinterpret_cast<Opaque*>(c); } \ | |
| + const Opaque* opaque(const Concrete* c) { return reinterpret_cast<const Opaque*>(c); } \ | |
| + Concrete& concrete(Opaque* o) { return *reinterpret_cast<Concrete*>(o); } \ | |
| + const Concrete& concrete(const Opaque* o) { return *reinterpret_cast<const Concrete*>(o); } | |
| + | |
| + DEFINE_OPAQUE_CONCRETE(StdString, std::string) | |
| + DEFINE_OPAQUE_CONCRETE(SharedPtrTnCall, std::shared_ptr<tn::Call>) | |
| + DEFINE_OPAQUE_CONCRETE(SharedPtrTnPeer, std::shared_ptr<tn::Peer>) | |
| + DEFINE_OPAQUE_CONCRETE(SharedPtrTnCallNotification, std::shared_ptr<tn::CallNotification>) | |
| + DEFINE_OPAQUE_CONCRETE(ClientAuthSessionOpaque, tn::RestAPI::ClientAuthSession) | |
| + DEFINE_OPAQUE_CONCRETE(TnCurrentUser, tn::RestAPI::CurrentUser) | |
| + DEFINE_OPAQUE_CONCRETE(WebrtcVideoFrameBuffer, webrtc::VideoFrameBuffer) | |
| + DEFINE_OPAQUE_CONCRETE(SharedPtrScreenVideoSink, std::shared_ptr<ScreenVideoSink>) | |
| + | |
| class AppLinux : public tn::SignalerObserver , public tn::CallerObserver { | |
| public: | |
| AppLinux(int event_fd) : m_event_fd(event_fd) { } | |
| @@ -224,7 +242,7 @@ namespace | |
| void OnDeferredCall(std::shared_ptr<tn::Call> call) override { | |
| MediaStatePinned media_state_pinned; | |
| copy_media_state(&media_state_pinned, call->CurrentMediaState()); | |
| - onCall(m_event_fd, (SharedPtrTnCall*)&call, &media_state_pinned); | |
| + onCall(m_event_fd, opaque(&call), &media_state_pinned); | |
| } | |
| void OnTransientCall(std::shared_ptr<tn::Call>) override { | |
| TN_WARN("TODO: OnTransientCall"); | |
| @@ -236,13 +254,13 @@ namespace | |
| // TN_WARN("TODO: OnIncomingCall audio={}", audio_only); | |
| // call->Peers() must be accessed on the thread that called us | |
| auto peer = call->Peers().front(); | |
| - onIncomingCall(m_event_fd, (SharedPtrTnCall*)&call, (SharedPtrTnPeer*)&peer, (int)audio_only); | |
| + onIncomingCall(m_event_fd, opaque(&call), opaque(&peer), (int)audio_only); | |
| } | |
| void OnCallWillEnd(std::shared_ptr<tn::Call>) override { | |
| TN_WARN("TODO: OnCallWillEnd"); | |
| } | |
| void OnCallEnd(std::shared_ptr<tn::Call> call) override { | |
| - onCallEnd(m_event_fd, (SharedPtrTnCall*)&call); | |
| + onCallEnd(m_event_fd, opaque(&call)); | |
| } | |
| void OnAudioError(std::shared_ptr<tn::Call>, std::shared_ptr<tn::AudioDeviceIDs>, const tn::AudioError&) override { | |
| TN_WARN("TODO: OnAudioError"); | |
| @@ -256,6 +274,7 @@ namespace | |
| void OnPeerAdded(std::shared_ptr<tn::Call>, std::shared_ptr<tn::Peer>) override { | |
| TN_WARN("TODO: OnPeerAdded"); | |
| + // onPeerAdded(m_event_fd, opaque(&call), opaque(&peer)); | |
| } | |
| void OnPeerStateChange(std::shared_ptr<tn::Call>, std::shared_ptr<tn::Peer>, const tn::CallPeerState&) override { | |
| TN_WARN("TODO: OnPeerStateChange"); | |
| @@ -266,7 +285,7 @@ namespace | |
| void OnMediaChange(std::shared_ptr<tn::Call> call, const tn::CallMediaState& state) override { | |
| MediaStatePinned media_state_pinned; | |
| copy_media_state(&media_state_pinned, state); | |
| - onMediaChange(m_event_fd, (SharedPtrTnCall*)&call, &media_state_pinned); | |
| + onMediaChange(m_event_fd, opaque(&call), &media_state_pinned); | |
| } | |
| void OnCursorColorsChange(std::shared_ptr<tn::Call>, const tn::CallCursorColors&) override { | |
| TN_WARN("TODO: OnCursorColorsChange"); | |
| @@ -288,10 +307,8 @@ namespace | |
| void OnMouseEvent(std::shared_ptr<tn::Call> call, std::shared_ptr<tn::Peer> peer, std::shared_ptr<tn::Protocol::MouseEvent> e) override { | |
| onMouse( | |
| m_event_fd, | |
| - (SharedPtrTnCall*)&call, | |
| - (SharedPtrTnPeer*)&peer, | |
| - e->x_ratio(), | |
| - e->y_ratio() | |
| + opaque(&call), opaque(&peer), | |
| + e->x_ratio(), e->y_ratio() | |
| ); | |
| } | |
| void OnKeyboardEvent(std::shared_ptr<tn::Call>, std::shared_ptr<tn::Peer>, std::shared_ptr<tn::Protocol::KeyboardEvent>) override { | |
| @@ -309,12 +326,12 @@ namespace | |
| void OnCallNotification(std::shared_ptr<tn::Call> call, std::shared_ptr<tn::CallNotification> call_notification) override { | |
| onCallNotification( | |
| - m_event_fd, (SharedPtrTnCall*)&call, (SharedPtrTnCallNotification*)&call_notification | |
| + m_event_fd, opaque(&call), opaque(&call_notification) | |
| ); | |
| } | |
| void OnCallNotificationDismiss(std::shared_ptr<tn::Call> call, std::shared_ptr<tn::CallNotification> call_notification) override { | |
| onCallNotificationDismiss( | |
| - m_event_fd, (SharedPtrTnCall*)&call, (SharedPtrTnCallNotification*)&call_notification | |
| + m_event_fd, opaque(&call), opaque(&call_notification) | |
| ); | |
| } | |
| @@ -385,90 +402,73 @@ size_t std_string_size(const StdString* s) | |
| void shared_ptr_tn_call_ctor_copy(SharedPtrTnCall* dst, const SharedPtrTnCall* src) | |
| { | |
| - const std::shared_ptr<tn::Call>& src_cpp = *(const std::shared_ptr<tn::Call>*)src; | |
| - new (dst) std::shared_ptr<tn::Call>(src_cpp); | |
| + new (dst) std::shared_ptr<tn::Call>(concrete(src)); | |
| } | |
| void shared_ptr_tn_call_ctor_move(SharedPtrTnCall* dst, SharedPtrTnCall* src) | |
| { | |
| - std::shared_ptr<tn::Call>& src_cpp = *(std::shared_ptr<tn::Call>*)src; | |
| - new (dst) std::shared_ptr<tn::Call>(std::move(src_cpp)); | |
| + new (dst) std::shared_ptr<tn::Call>(std::move(concrete(src))); | |
| } | |
| void shared_ptr_tn_call_dtor(SharedPtrTnCall* call) | |
| { | |
| - ((std::shared_ptr<tn::Call>*)call)->~shared_ptr(); | |
| + concrete(call).~shared_ptr(); | |
| } | |
| int shared_ptr_tn_call_eql(const SharedPtrTnCall* a, const SharedPtrTnCall* b) | |
| { | |
| - std::shared_ptr<tn::Call>& a_cpp = *(std::shared_ptr<tn::Call>*)a; | |
| - std::shared_ptr<tn::Call>& b_cpp = *(std::shared_ptr<tn::Call>*)b; | |
| - return a_cpp.get() == b_cpp.get(); | |
| + return concrete(a).get() == concrete(b).get(); | |
| } | |
| void shared_ptr_tn_peer_ctor_copy(SharedPtrTnPeer* dst, const SharedPtrTnPeer* src) | |
| { | |
| - const std::shared_ptr<tn::Peer>& src_cpp = *(const std::shared_ptr<tn::Peer>*)src; | |
| - new (dst) std::shared_ptr<tn::Peer>(src_cpp); | |
| + new (dst) std::shared_ptr<tn::Peer>(concrete(src)); | |
| } | |
| void shared_ptr_tn_peer_ctor_move(SharedPtrTnPeer* dst, SharedPtrTnPeer* src) | |
| { | |
| - std::shared_ptr<tn::Peer>& src_cpp = *(std::shared_ptr<tn::Peer>*)src; | |
| - new (dst) std::shared_ptr<tn::Peer>(std::move(src_cpp)); | |
| + new (dst) std::shared_ptr<tn::Peer>(std::move(concrete(src))); | |
| } | |
| void shared_ptr_tn_peer_dtor(SharedPtrTnPeer* peer) | |
| { | |
| - ((std::shared_ptr<tn::Peer>*)peer)->~shared_ptr(); | |
| + concrete(peer).~shared_ptr(); | |
| } | |
| int shared_ptr_tn_peer_has_value(const SharedPtrTnPeer* peer) | |
| { | |
| - const std::shared_ptr<tn::Peer>& peer_cpp = *(std::shared_ptr<tn::Peer>*)peer; | |
| - return peer_cpp.get() != 0; | |
| + return concrete(peer).get() != 0; | |
| } | |
| int shared_ptr_tn_peer_eql(const SharedPtrTnPeer* a, const SharedPtrTnPeer* b) | |
| { | |
| - std::shared_ptr<tn::Peer>& a_cpp = *(std::shared_ptr<tn::Peer>*)a; | |
| - std::shared_ptr<tn::Peer>& b_cpp = *(std::shared_ptr<tn::Peer>*)b; | |
| - return a_cpp.get() == b_cpp.get(); | |
| + return concrete(a).get() == concrete(b).get(); | |
| } | |
| const StdString* shared_ptr_tn_peer_full_name_ref(const SharedPtrTnPeer* peer) | |
| { | |
| - const std::shared_ptr<tn::Peer>& peer_cpp = *(std::shared_ptr<tn::Peer>*)peer; | |
| - return (const StdString*)&(peer_cpp->User().full_name); | |
| + return opaque(&concrete(peer)->User().full_name); | |
| } | |
| void call_notification_ctor_copy(SharedPtrTnCallNotification* dst, const SharedPtrTnCallNotification* src) | |
| { | |
| - const std::shared_ptr<tn::CallNotification>& src_cpp = *(const std::shared_ptr<tn::CallNotification>*)src; | |
| - new (dst) std::shared_ptr<tn::CallNotification>(src_cpp); | |
| + new (dst) std::shared_ptr<tn::CallNotification>(concrete(src)); | |
| } | |
| void call_notification_dtor(SharedPtrTnCallNotification* notification) | |
| { | |
| - ((std::shared_ptr<tn::CallNotification>*)notification)->~shared_ptr(); | |
| + concrete(notification).~shared_ptr(); | |
| } | |
| int call_notification_eql(const SharedPtrTnCallNotification* a, const SharedPtrTnCallNotification* b) | |
| { | |
| - std::shared_ptr<tn::CallNotification>& a_cpp = *(std::shared_ptr<tn::CallNotification>*)a; | |
| - std::shared_ptr<tn::CallNotification>& b_cpp = *(std::shared_ptr<tn::CallNotification>*)b; | |
| - return a_cpp.get() == b_cpp.get(); | |
| + return concrete(a).get() == concrete(b).get(); | |
| } | |
| CallNotificationKind call_notification_kind(const SharedPtrTnCallNotification* notification) | |
| { | |
| - const std::shared_ptr<tn::CallNotification>& cpp = *(std::shared_ptr<tn::CallNotification>*)notification; | |
| - return zigEnumFromCpp(cpp->Kind()); | |
| + return zigEnumFromCpp(concrete(notification)->Kind()); | |
| } | |
| void call_notification_reject(const SharedPtrTnCallNotification* notification) | |
| { | |
| - const std::shared_ptr<tn::CallNotification>& cpp = *(std::shared_ptr<tn::CallNotification>*)notification; | |
| - cpp->Reject(); | |
| + concrete(notification)->Reject(); | |
| } | |
| void call_notification_accept(const SharedPtrTnCallNotification* notification) | |
| { | |
| - const std::shared_ptr<tn::CallNotification>& cpp = *(std::shared_ptr<tn::CallNotification>*)notification; | |
| - cpp->Accept(); | |
| + concrete(notification)->Accept(); | |
| } | |
| const StdString* call_notification_sender_short_name(const SharedPtrTnCallNotification* notification) | |
| { | |
| - const std::shared_ptr<tn::CallNotification>& cpp = *(std::shared_ptr<tn::CallNotification>*)notification; | |
| - return (const StdString*)&cpp->Sender()->short_name; | |
| + return opaque(&concrete(notification)->Sender()->short_name); | |
| } | |
| class WebcamCapturerAdapter : public tn::WebcamCapturerAdapter | |
| @@ -518,7 +518,7 @@ const StdString* lock_personal_call_slug() | |
| { | |
| global_personal_call_url.mutex.lock(); | |
| if (global_personal_call_url.slugs.size() == 0) return nullptr; | |
| - return (const StdString*)&global_personal_call_url.slugs.back(); | |
| + return opaque(&global_personal_call_url.slugs.back()); | |
| } | |
| void unlock_personal_call_slug() | |
| { | |
| @@ -532,12 +532,12 @@ ClientAuthSessionOpaque* auth_session_create(const char* code_verifier_ptr, size | |
| std::unique_ptr<tn::RestAPI::ClientAuthSession> session = tn::Signaler::Default()->RestClient()->CreateAuthSession( | |
| std::string(code_verifier) | |
| ); | |
| - return (ClientAuthSessionOpaque*)session.release(); | |
| + return opaque(session.release()); | |
| } | |
| void auth_session_delete(ClientAuthSessionOpaque* session) | |
| { | |
| - delete (tn::RestAPI::ClientAuthSession*)session; | |
| + delete &concrete(session); | |
| } | |
| void format_auth_session_browser_url( | |
| @@ -545,7 +545,7 @@ void format_auth_session_browser_url( | |
| void* context, | |
| void (*callback)(void*, const char* url, size_t len) | |
| ) { | |
| - auto url = ((tn::RestAPI::ClientAuthSession*)session)->BrowserURL().str(); | |
| + auto url = concrete(session).BrowserURL().str(); | |
| callback(context, url.data(), url.size()); | |
| } | |
| @@ -555,7 +555,7 @@ void auth_session_exchange(ClientAuthSessionOpaque* session, int event_fd, const | |
| // NOTE: auth_code is potentially sensitive data we probably don't want to log | |
| // TN_ERROR("auth_session_exchange auth_code='{}'", auth_code); | |
| - ((tn::RestAPI::ClientAuthSession*)session)->Exchange(auth_code, [event_fd]( | |
| + concrete(session).Exchange(auth_code, [event_fd]( | |
| std::unique_ptr<tn::RestAPI::CurrentUser> user, | |
| const tn::HTTP::Error& err | |
| ) { | |
| @@ -593,11 +593,11 @@ void signaler_sign_out() | |
| void tn_current_user_delete(TnCurrentUser* user) | |
| { | |
| - delete (tn::RestAPI::CurrentUser*)user; | |
| + delete &concrete(user); | |
| } | |
| const StdString* tn_current_user_auth_token_ref(const TnCurrentUser* user) | |
| { | |
| - return (const StdString*)&((tn::RestAPI::CurrentUser*)user)->auth_token; | |
| + return opaque(&concrete(user).auth_token); | |
| } | |
| class CallJoiner | |
| @@ -634,14 +634,13 @@ void join_call_slug_std_string(const StdString* slug_opaque) | |
| void reject_call(SharedPtrTnCall* call) | |
| { | |
| - std::shared_ptr<tn::Call>& call_cpp = *(std::shared_ptr<tn::Call>*)call; | |
| - global.caller->Reject(call_cpp); | |
| + global.caller->Reject(concrete(call)); | |
| } | |
| void accept_call(SharedPtrTnCall* call) | |
| { | |
| - std::shared_ptr<tn::Call>& call_cpp = *(std::shared_ptr<tn::Call>*)call; | |
| + std::shared_ptr<tn::Call> call_cpp = concrete(call); | |
| global.caller->Accept(call_cpp, [call_cpp](const tn::Caller::Error& error) { | |
| - onAcceptCallComplete(global.app->get_event_fd(), (SharedPtrTnCall*)&call_cpp, zigEnumFromCpp(error.Type())); | |
| + onAcceptCallComplete(global.app->get_event_fd(), opaque(&call_cpp), zigEnumFromCpp(error.Type())); | |
| }); | |
| } | |
| @@ -652,12 +651,10 @@ void hangup() | |
| void call_set_mic_enabled(const SharedPtrTnCall* call, int enabled) | |
| { | |
| - const std::shared_ptr<tn::Call>& call_cpp = *(const std::shared_ptr<tn::Call>*)call; | |
| - call_cpp->EnableAudio(enabled); | |
| + concrete(call)->EnableAudio(enabled); | |
| } | |
| void call_screen_capture_start(const SharedPtrTnCall* call, XdgSessionType session_type, int epoll_fd) | |
| { | |
| - const std::shared_ptr<tn::Call>& call_cpp = *(const std::shared_ptr<tn::Call>*)call; | |
| tn::XdgSessionType session_type_tn = [&]() -> tn::XdgSessionType { | |
| switch (session_type) { | |
| case XdgSessionType::Unspecified: return tn::XdgSessionType::Unspecified; | |
| @@ -666,22 +663,19 @@ void call_screen_capture_start(const SharedPtrTnCall* call, XdgSessionType sessi | |
| case XdgSessionType::Tty: return tn::XdgSessionType::Unspecified; | |
| } | |
| }(); | |
| - call_cpp->ScreenCapturer()->Start(tn::VideoCapturerDesktopStart(session_type_tn, epoll_fd), tn::ScreenSource(0)); | |
| + concrete(call)->ScreenCapturer()->Start(tn::VideoCapturerDesktopStart(session_type_tn, epoll_fd), tn::ScreenSource(0)); | |
| } | |
| void call_screen_capture_stop(const SharedPtrTnCall* call) | |
| { | |
| - const std::shared_ptr<tn::Call>& call_cpp = *(const std::shared_ptr<tn::Call>*)call; | |
| - call_cpp->ScreenCapturer()->Stop(); | |
| + concrete(call)->ScreenCapturer()->Stop(); | |
| } | |
| void call_broadcast_mouse_exited(const SharedPtrTnCall* call) | |
| { | |
| - const std::shared_ptr<tn::Call>& call_cpp = *(const std::shared_ptr<tn::Call>*)call; | |
| - call_cpp->BroadcastUnbuffered(tn::Protocol::MouseEvent::MouseExited()); | |
| + concrete(call)->BroadcastUnbuffered(tn::Protocol::MouseEvent::MouseExited()); | |
| } | |
| void call_broadcast_mouse_pos(const SharedPtrTnCall* call, float x, float y) | |
| { | |
| - const std::shared_ptr<tn::Call>& call_cpp = *(const std::shared_ptr<tn::Call>*)call; | |
| - call_cpp->BroadcastUnbuffered(tn::Protocol::MouseEvent::MouseMoved(x, y)); | |
| + concrete(call)->BroadcastUnbuffered(tn::Protocol::MouseEvent::MouseMoved(x, y)); | |
| } | |
| void screen_video_sink_new(SharedPtrScreenVideoSink* sink, int event_fd) | |
| @@ -691,43 +685,39 @@ void screen_video_sink_new(SharedPtrScreenVideoSink* sink, int event_fd) | |
| void screen_video_sink_delete(SharedPtrScreenVideoSink* sink) | |
| { | |
| - ((std::shared_ptr<ScreenVideoSink>*)sink)->~shared_ptr(); | |
| + concrete(sink).~shared_ptr(); | |
| } | |
| void screen_video_sink_add(const SharedPtrScreenVideoSink* sink, const SharedPtrTnPeer* peer) | |
| { | |
| - const std::shared_ptr<ScreenVideoSink>& sink_cpp = *((std::shared_ptr<ScreenVideoSink>*)sink); | |
| - const std::shared_ptr<tn::Peer>& peer_cpp = *(std::shared_ptr<tn::Peer>*)peer; | |
| // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
| // TODO: add TargetResolution | |
| - peer_cpp->AddVideoSink(sink_cpp, tn::Peer::VideoSource::Screen); | |
| + concrete(peer)->AddVideoSink(concrete(sink), tn::Peer::VideoSource::Screen); | |
| } | |
| void screen_video_sink_remove(const SharedPtrScreenVideoSink* sink, const SharedPtrTnPeer* peer) | |
| { | |
| - const std::shared_ptr<ScreenVideoSink>& sink_cpp = *((std::shared_ptr<ScreenVideoSink>*)sink); | |
| - const std::shared_ptr<tn::Peer>& peer_cpp = *(std::shared_ptr<tn::Peer>*)peer; | |
| - peer_cpp->RemoveVideoSink(sink_cpp, tn::Peer::VideoSource::Screen); | |
| + concrete(peer)->RemoveVideoSink(concrete(sink), tn::Peer::VideoSource::Screen); | |
| } | |
| void webrtc_video_frame_buffer_addref(WebrtcVideoFrameBuffer* buffer) | |
| { | |
| - ((webrtc::VideoFrameBuffer*)buffer)->AddRef(); | |
| + concrete(buffer).AddRef(); | |
| } | |
| void webrtc_video_frame_buffer_unref(WebrtcVideoFrameBuffer* buffer) | |
| { | |
| - ((webrtc::VideoFrameBuffer*)buffer)->Release(); | |
| + concrete(buffer).Release(); | |
| } | |
| int webrtc_video_frame_buffer_width(WebrtcVideoFrameBuffer* buffer) | |
| { | |
| - return ((webrtc::VideoFrameBuffer*)buffer)->width(); | |
| + return concrete(buffer).width(); | |
| } | |
| int webrtc_video_frame_buffer_height(WebrtcVideoFrameBuffer* buffer) | |
| { | |
| - return ((webrtc::VideoFrameBuffer*)buffer)->height(); | |
| + return concrete(buffer).height(); | |
| } | |
| WebrtcVideoFrameBufferType webrtc_video_frame_buffer_type(WebrtcVideoFrameBuffer* buffer) | |
| { | |
| - switch (((webrtc::VideoFrameBuffer*)buffer)->type()) { | |
| + switch (concrete(buffer).type()) { | |
| case webrtc::VideoFrameBuffer::Type::kNative: return WebrtcVideoFrameBufferType::kNative; | |
| case webrtc::VideoFrameBuffer::Type::kI420: return WebrtcVideoFrameBufferType::kI420; | |
| case webrtc::VideoFrameBuffer::Type::kI420A: return WebrtcVideoFrameBufferType::kI420A; | |
| @@ -748,8 +738,7 @@ void webrtc_video_frame_buffer_get_i420( | |
| uint8_t const** out_v_ptr, | |
| int* out_v_stride | |
| ) { | |
| - webrtc::VideoFrameBuffer* buffer_cpp = (webrtc::VideoFrameBuffer*)buffer; | |
| - const webrtc::I420BufferInterface* i420 = buffer_cpp->GetI420(); | |
| + const webrtc::I420BufferInterface* i420 = concrete(buffer).GetI420(); | |
| *out_y_ptr = i420->DataY(); | |
| *out_y_stride = i420->StrideY(); | |
| *out_u_ptr = i420->DataU(); | |
| @@ -761,12 +750,12 @@ void webrtc_video_frame_buffer_get_i420( | |
| void media_state_destroy(MediaStatePinned* state) | |
| { | |
| - ((std::shared_ptr<tn::Peer>*)&state->peer_sharing_their_screen_pinned)->~shared_ptr(); | |
| + concrete(&state->peer_sharing_their_screen_pinned).~shared_ptr(); | |
| } | |
| void media_state_move(MediaStatePinned* dst, MediaStatePinned* src) | |
| { | |
| - *(std::shared_ptr<tn::Peer>*)&dst->peer_sharing_their_screen_pinned = std::move( | |
| - *(std::shared_ptr<tn::Peer>*)&src->peer_sharing_their_screen_pinned | |
| + concrete(&dst->peer_sharing_their_screen_pinned) = std::move( | |
| + concrete(&src->peer_sharing_their_screen_pinned) | |
| ); | |
| dst->peer_screen_width = src->peer_screen_width; | |
| dst->peer_screen_height = src->peer_screen_height; | |
| diff --git a/shared/vendor/webrtc/src b/shared/vendor/webrtc/src | |
| --- a/shared/vendor/webrtc/src | |
| +++ b/shared/vendor/webrtc/src | |
| @@ -1 +1 @@ | |
| -Subproject commit 07c4b33b53bbd4399fe0f4cc94d64c2ddb5d0dbd | |
| +Subproject commit 07c4b33b53bbd4399fe0f4cc94d64c2ddb5d0dbd-dirty |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment