From 00ac03c8e7a96657de5b537cfc0396509546374e Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sun, 4 Jul 2021 14:18:10 +0200 Subject: Use a class instead of lambdas for signals. --- src/WebRTCLibPeerConnection.cpp | 18 ++++-------------- src/WebRTCLibPeerConnection.hpp | 32 ++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/WebRTCLibPeerConnection.cpp b/src/WebRTCLibPeerConnection.cpp index d95b1e6..4b83ae6 100644 --- a/src/WebRTCLibPeerConnection.cpp +++ b/src/WebRTCLibPeerConnection.cpp @@ -174,14 +174,12 @@ godot_error WebRTCLibPeerConnection::add_ice_candidate(const char *sdpMidName, i godot_error WebRTCLibPeerConnection::poll() { ERR_FAIL_COND_V(peer_connection.get() == nullptr, GODOT_ERR_UNCONFIGURED); - std::function signal; while (!signal_queue.empty()) { mutex_signal_queue->lock(); - signal = signal_queue.front(); + Signal signal = signal_queue.front(); signal_queue.pop(); mutex_signal_queue->unlock(); - - signal(); + signal.emit(this); } return GODOT_OK; } @@ -244,15 +242,7 @@ WebRTCLibPeerConnection::~WebRTCLibPeerConnection() { void WebRTCLibPeerConnection::queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1, const godot::Variant &p_arg2, const godot::Variant &p_arg3) { mutex_signal_queue->lock(); - signal_queue.push( - [this, p_name, p_argc, p_arg1, p_arg2, p_arg3] { - if (p_argc == 1) { - emit_signal(p_name, p_arg1); - } else if (p_argc == 2) { - emit_signal(p_name, p_arg1, p_arg2); - } else { - emit_signal(p_name, p_arg1, p_arg2, p_arg3); - } - }); + const godot::Variant argv[3] = { p_arg1, p_arg2, p_arg3 }; + signal_queue.push(Signal(p_name, p_argc, argv)); mutex_signal_queue->unlock(); } diff --git a/src/WebRTCLibPeerConnection.hpp b/src/WebRTCLibPeerConnection.hpp index 8c5d9b8..c209cf1 100644 --- a/src/WebRTCLibPeerConnection.hpp +++ b/src/WebRTCLibPeerConnection.hpp @@ -5,8 +5,7 @@ #include "api/peer_connection_interface.h" // interface for all things needed from WebRTC #include "media/base/media_engine.h" // needed for CreateModularPeerConnectionFactory -#include // std::function -#include // mutex @TODO replace std::mutex with Godot mutex +#include #include "net/WebRTCPeerConnectionNative.hpp" @@ -43,7 +42,6 @@ public: /* helper functions */ void queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1 = godot::Variant(), const godot::Variant &p_arg2 = godot::Variant(), const godot::Variant &p_arg3 = godot::Variant()); - // void queue_signal(godot::StringName p_name, Variant_ARG_LIST); void queue_packet(uint8_t *, int); /** PeerConnectionObserver callback functions **/ @@ -82,12 +80,38 @@ public: void OnFailure(webrtc::RTCError error) override; }; + class Signal { + godot::String method; + godot::Variant argv[3]; + int argc = 0; + public: + Signal(godot::String p_method, int p_argc, const godot::Variant *p_argv) { + method = p_method; + argc = p_argc; + for (int i = 0; i < argc; i++) { + argv[i] = p_argv[i]; + } + } + + void emit(godot::Object *p_object) { + if (argc == 0) { + p_object->emit_signal(method); + } else if (argc == 1) { + p_object->emit_signal(method, argv[0]); + } else if (argc == 2) { + p_object->emit_signal(method, argv[0], argv[1]); + } else if (argc == 3) { + p_object->emit_signal(method, argv[0], argv[1], argv[2]); + } + } + }; + GodotPCO pco; rtc::scoped_refptr ptr_ssdo; rtc::scoped_refptr ptr_csdo; std::mutex *mutex_signal_queue = nullptr; - std::queue > signal_queue; + std::queue signal_queue; rtc::scoped_refptr pc_factory; rtc::scoped_refptr peer_connection; -- cgit v1.2.3 From ce3f086ec46f23358df086005fa14558def0d12f Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 9 Jul 2021 01:31:29 +0200 Subject: Move observers implementations into PeerConnection. --- src/WebRTCLibObservers.cpp | 53 ----------------------------------------- src/WebRTCLibPeerConnection.cpp | 19 +++++++++++++++ src/WebRTCLibPeerConnection.hpp | 41 +++++++++++++++++++------------ 3 files changed, 45 insertions(+), 68 deletions(-) delete mode 100644 src/WebRTCLibObservers.cpp diff --git a/src/WebRTCLibObservers.cpp b/src/WebRTCLibObservers.cpp deleted file mode 100644 index 6d8f15f..0000000 --- a/src/WebRTCLibObservers.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "WebRTCLibDataChannel.hpp" -#include "WebRTCLibPeerConnection.hpp" - -using namespace godot_webrtc; - -// CreateSessionObseerver -WebRTCLibPeerConnection::GodotCSDO::GodotCSDO(WebRTCLibPeerConnection *parent) { - this->parent = parent; -} - -void WebRTCLibPeerConnection::GodotCSDO::OnSuccess(webrtc::SessionDescriptionInterface *desc) { - // serialize this offer and send it to the remote peer: - std::string sdp; // sdp = session description protocol - desc->ToString(&sdp); - parent->queue_signal("session_description_created", 2, desc->type().c_str(), sdp.c_str()); -}; - -void WebRTCLibPeerConnection::GodotCSDO::OnFailure(webrtc::RTCError error){}; - -// SetSessionObseerver -WebRTCLibPeerConnection::GodotSSDO::GodotSSDO(WebRTCLibPeerConnection *parent) { - this->parent = parent; -} - -void WebRTCLibPeerConnection::GodotSSDO::OnSuccess(){}; -void WebRTCLibPeerConnection::GodotSSDO::OnFailure(webrtc::RTCError error){}; - -// PeerConnectionObserver -WebRTCLibPeerConnection::GodotPCO::GodotPCO(WebRTCLibPeerConnection *parent) { - this->parent = parent; -} - -void WebRTCLibPeerConnection::GodotPCO::OnDataChannel(rtc::scoped_refptr data_channel) { - parent->queue_signal("data_channel_received", 1, WebRTCLibDataChannel::new_data_channel(data_channel)); -} - -void WebRTCLibPeerConnection::GodotPCO::OnIceCandidate(const webrtc::IceCandidateInterface *candidate) { - godot::Dictionary candidateSDP; - godot::String candidateSdpMidName = candidate->sdp_mid().c_str(); - int candidateSdpMlineIndexName = candidate->sdp_mline_index(); - std::string sdp; - candidate->ToString(&sdp); - godot::String candidateSdpName = sdp.c_str(); - - parent->queue_signal("ice_candidate_created", 3, candidateSdpMidName, candidateSdpMlineIndexName, candidateSdpName); -} - -void WebRTCLibPeerConnection::GodotPCO::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) {} -void WebRTCLibPeerConnection::GodotPCO::OnAddStream(rtc::scoped_refptr stream) {} -void WebRTCLibPeerConnection::GodotPCO::OnRemoveStream(rtc::scoped_refptr stream) {} -void WebRTCLibPeerConnection::GodotPCO::OnRenegotiationNeeded() {} -void WebRTCLibPeerConnection::GodotPCO::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) {} -void WebRTCLibPeerConnection::GodotPCO::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) {} diff --git a/src/WebRTCLibPeerConnection.cpp b/src/WebRTCLibPeerConnection.cpp index 4b83ae6..eedeff0 100644 --- a/src/WebRTCLibPeerConnection.cpp +++ b/src/WebRTCLibPeerConnection.cpp @@ -7,6 +7,25 @@ using namespace godot_webrtc; std::unique_ptr WebRTCLibPeerConnection::signaling_thread = nullptr; +// PeerConnectionObserver +void WebRTCLibPeerConnection::GodotPCO::OnIceCandidate(const webrtc::IceCandidateInterface *candidate) { + godot::Dictionary candidateSDP; + godot::String candidateSdpMidName = candidate->sdp_mid().c_str(); + int candidateSdpMlineIndexName = candidate->sdp_mline_index(); + std::string sdp; + candidate->ToString(&sdp); + godot::String candidateSdpName = sdp.c_str(); + parent->queue_signal("ice_candidate_created", 3, candidateSdpMidName, candidateSdpMlineIndexName, candidateSdpName); +} + +// CreateSessionDescriptionObserver +void WebRTCLibPeerConnection::GodotCSDO::OnSuccess(webrtc::SessionDescriptionInterface *desc) { + // serialize this offer and send it to the remote peer: + std::string sdp; + desc->ToString(&sdp); + parent->queue_signal("session_description_created", 2, desc->type().c_str(), sdp.c_str()); +} + void WebRTCLibPeerConnection::initialize_signaling() { if (signaling_thread.get() == nullptr) { signaling_thread = rtc::Thread::Create(); diff --git a/src/WebRTCLibPeerConnection.hpp b/src/WebRTCLibPeerConnection.hpp index c209cf1..f6a92a7 100644 --- a/src/WebRTCLibPeerConnection.hpp +++ b/src/WebRTCLibPeerConnection.hpp @@ -49,35 +49,46 @@ public: public: WebRTCLibPeerConnection *parent; - GodotPCO(WebRTCLibPeerConnection *parent); - void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override; - void OnAddStream(rtc::scoped_refptr stream) override; - void OnRemoveStream(rtc::scoped_refptr stream) override; - void OnDataChannel(rtc::scoped_refptr data_channel) override; - void OnRenegotiationNeeded() override; - void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override; - void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override; + GodotPCO(WebRTCLibPeerConnection *p_parent) { + parent = p_parent; + } void OnIceCandidate(const webrtc::IceCandidateInterface *candidate) override; + + void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override {} + void OnAddStream(rtc::scoped_refptr stream) override {} + void OnRemoveStream(rtc::scoped_refptr stream) override {} + void OnDataChannel(rtc::scoped_refptr data_channel) override {} + void OnRenegotiationNeeded() override {} + void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override {} + void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override {} }; /** CreateSessionDescriptionObserver callback functions **/ class GodotCSDO : public webrtc::CreateSessionDescriptionObserver { public: - WebRTCLibPeerConnection *parent; + WebRTCLibPeerConnection *parent = nullptr; - GodotCSDO(WebRTCLibPeerConnection *parent); + GodotCSDO(WebRTCLibPeerConnection *p_parent) { + parent = p_parent; + } void OnSuccess(webrtc::SessionDescriptionInterface *desc) override; - void OnFailure(webrtc::RTCError error) override; + void OnFailure(webrtc::RTCError error) override { + ERR_PRINT(godot::String(error.message())); + } }; /** SetSessionDescriptionObserver callback functions **/ class GodotSSDO : public webrtc::SetSessionDescriptionObserver { public: - WebRTCLibPeerConnection *parent; + WebRTCLibPeerConnection *parent = nullptr; - GodotSSDO(WebRTCLibPeerConnection *parent); - void OnSuccess() override; - void OnFailure(webrtc::RTCError error) override; + GodotSSDO(WebRTCLibPeerConnection *p_parent) { + parent = p_parent; + } + void OnSuccess() override {} + void OnFailure(webrtc::RTCError error) override { + ERR_PRINT(godot::String(error.message())); + } }; class Signal { -- cgit v1.2.3 From 04fbae6ce38550fac2a8be3786405949563304d5 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 9 Jul 2021 03:15:05 +0200 Subject: Properly wait success callback before creating answers. --- src/WebRTCLibPeerConnection.cpp | 12 +++++++++++- src/WebRTCLibPeerConnection.hpp | 6 ++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/WebRTCLibPeerConnection.cpp b/src/WebRTCLibPeerConnection.cpp index eedeff0..eb4e8cc 100644 --- a/src/WebRTCLibPeerConnection.cpp +++ b/src/WebRTCLibPeerConnection.cpp @@ -18,6 +18,14 @@ void WebRTCLibPeerConnection::GodotPCO::OnIceCandidate(const webrtc::IceCandidat parent->queue_signal("ice_candidate_created", 3, candidateSdpMidName, candidateSdpMlineIndexName, candidateSdpName); } +// SetSessionDescriptionObserver +void WebRTCLibPeerConnection::GodotSSDO::OnSuccess() { + if (make_offer) { + make_offer = false; + parent->peer_connection->CreateAnswer(parent->ptr_csdo, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); + } +} + // CreateSessionDescriptionObserver void WebRTCLibPeerConnection::GodotCSDO::OnSuccess(webrtc::SessionDescriptionInterface *desc) { // serialize this offer and send it to the remote peer: @@ -161,8 +169,10 @@ godot_error WebRTCLibPeerConnection::create_offer() { godot_error WebRTCLibPeerConnection::set_remote_description(const char *type, const char *sdp) { ERR_FAIL_COND_V(peer_connection.get() == nullptr, GODOT_ERR_UNCONFIGURED); std::unique_ptr desc = _MAKE_DESC(type, sdp); + if (desc->GetType() == webrtc::SdpType::kOffer) { + ptr_ssdo->make_offer = true; + } peer_connection->SetRemoteDescription(ptr_ssdo, desc.release()); - peer_connection->CreateAnswer(ptr_csdo, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); return GODOT_OK; } diff --git a/src/WebRTCLibPeerConnection.hpp b/src/WebRTCLibPeerConnection.hpp index f6a92a7..85ef33f 100644 --- a/src/WebRTCLibPeerConnection.hpp +++ b/src/WebRTCLibPeerConnection.hpp @@ -40,7 +40,7 @@ public: ~WebRTCLibPeerConnection(); /* helper functions */ - +private: void queue_signal(godot::String p_name, int p_argc, const godot::Variant &p_arg1 = godot::Variant(), const godot::Variant &p_arg2 = godot::Variant(), const godot::Variant &p_arg3 = godot::Variant()); void queue_packet(uint8_t *, int); @@ -81,12 +81,14 @@ public: class GodotSSDO : public webrtc::SetSessionDescriptionObserver { public: WebRTCLibPeerConnection *parent = nullptr; + bool make_offer = false; GodotSSDO(WebRTCLibPeerConnection *p_parent) { parent = p_parent; } - void OnSuccess() override {} + void OnSuccess() override; void OnFailure(webrtc::RTCError error) override { + make_offer = false; ERR_PRINT(godot::String(error.message())); } }; -- cgit v1.2.3