summaryrefslogtreecommitdiff
path: root/modules/webrtc
diff options
context:
space:
mode:
Diffstat (limited to 'modules/webrtc')
-rw-r--r--modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml12
-rw-r--r--modules/webrtc/doc_classes/WebRTCPeerConnection.xml39
-rw-r--r--modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml24
-rw-r--r--modules/webrtc/library_godot_webrtc.js196
-rw-r--r--modules/webrtc/webrtc_data_channel_extension.cpp148
-rw-r--r--modules/webrtc/webrtc_data_channel_extension.h59
-rw-r--r--modules/webrtc/webrtc_peer_connection.cpp13
-rw-r--r--modules/webrtc/webrtc_peer_connection.h19
-rw-r--r--modules/webrtc/webrtc_peer_connection_extension.cpp72
-rw-r--r--modules/webrtc/webrtc_peer_connection_extension.h33
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.cpp23
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.h14
12 files changed, 285 insertions, 367 deletions
diff --git a/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml b/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml
index 5387deaa47..a10ea25b8c 100644
--- a/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml
+++ b/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml
@@ -48,7 +48,7 @@
</description>
</method>
<method name="_get_packet" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<param index="0" name="r_buffer" type="const uint8_t **" />
<param index="1" name="r_buffer_size" type="int32_t*" />
<description>
@@ -60,12 +60,12 @@
</description>
</method>
<method name="_get_ready_state" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="WebRTCDataChannel.ChannelState" />
<description>
</description>
</method>
<method name="_get_write_mode" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="WebRTCDataChannel.WriteMode" />
<description>
</description>
</method>
@@ -80,12 +80,12 @@
</description>
</method>
<method name="_poll" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<description>
</description>
</method>
<method name="_put_packet" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<param index="0" name="p_buffer" type="const uint8_t*" />
<param index="1" name="p_buffer_size" type="int" />
<description>
@@ -93,7 +93,7 @@
</method>
<method name="_set_write_mode" qualifiers="virtual">
<return type="void" />
- <param index="0" name="p_write_mode" type="int" />
+ <param index="0" name="p_write_mode" type="int" enum="WebRTCDataChannel.WriteMode" />
<description>
</description>
</method>
diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
index e99aeb4f51..4ecc71ddbb 100644
--- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
+++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -67,6 +67,18 @@
Returns the connection state. See [enum ConnectionState].
</description>
</method>
+ <method name="get_gathering_state" qualifiers="const">
+ <return type="int" enum="WebRTCPeerConnection.GatheringState" />
+ <description>
+ Returns the ICE [enum GatheringState] of the connection. This lets you detect, for example, when collection of ICE candidates has finished.
+ </description>
+ </method>
+ <method name="get_signaling_state" qualifiers="const">
+ <return type="int" enum="WebRTCPeerConnection.SignalingState" />
+ <description>
+ Returns the [enum SignalingState] on the local end of the connection while connecting or reconnecting to another peer.
+ </description>
+ </method>
<method name="initialize">
<return type="int" enum="Error" />
<param index="0" name="configuration" type="Dictionary" default="{}" />
@@ -165,5 +177,32 @@
<constant name="STATE_CLOSED" value="5" enum="ConnectionState">
The peer connection is closed (after calling [method close] for example).
</constant>
+ <constant name="GATHERING_STATE_NEW" value="0" enum="GatheringState">
+ The peer connection was just created and hasn't done any networking yet.
+ </constant>
+ <constant name="GATHERING_STATE_GATHERING" value="1" enum="GatheringState">
+ The ICE agent is in the process of gathering candidates for the connection.
+ </constant>
+ <constant name="GATHERING_STATE_COMPLETE" value="2" enum="GatheringState">
+ The ICE agent has finished gathering candidates. If something happens that requires collecting new candidates, such as a new interface being added or the addition of a new ICE server, the state will revert to gathering to gather those candidates.
+ </constant>
+ <constant name="SIGNALING_STATE_STABLE" value="0" enum="SignalingState">
+ There is no ongoing exchange of offer and answer underway. This may mean that the [WebRTCPeerConnection] is new ([constant STATE_NEW]) or that negotiation is complete and a connection has been established ([constant STATE_CONNECTED]).
+ </constant>
+ <constant name="SIGNALING_STATE_HAVE_LOCAL_OFFER" value="1" enum="SignalingState">
+ The local peer has called [method set_local_description], passing in SDP representing an offer (usually created by calling [method create_offer]), and the offer has been applied successfully.
+ </constant>
+ <constant name="SIGNALING_STATE_HAVE_REMOTE_OFFER" value="2" enum="SignalingState">
+ The remote peer has created an offer and used the signaling server to deliver it to the local peer, which has set the offer as the remote description by calling [method set_remote_description].
+ </constant>
+ <constant name="SIGNALING_STATE_HAVE_LOCAL_PRANSWER" value="3" enum="SignalingState">
+ The offer sent by the remote peer has been applied and an answer has been created and applied by calling [method set_local_description]. This provisional answer describes the supported media formats and so forth, but may not have a complete set of ICE candidates included. Further candidates will be delivered separately later.
+ </constant>
+ <constant name="SIGNALING_STATE_HAVE_REMOTE_PRANSWER" value="4" enum="SignalingState">
+ A provisional answer has been received and successfully applied in response to an offer previously sent and established by calling [method set_local_description].
+ </constant>
+ <constant name="SIGNALING_STATE_CLOSED" value="5" enum="SignalingState">
+ The [WebRTCPeerConnection] has been closed.
+ </constant>
</constants>
</class>
diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml b/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml
index e22e939a66..474d2f6a89 100644
--- a/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml
+++ b/modules/webrtc/doc_classes/WebRTCPeerConnectionExtension.xml
@@ -8,7 +8,7 @@
</tutorials>
<methods>
<method name="_add_ice_candidate" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<param index="0" name="p_sdp_mid_name" type="String" />
<param index="1" name="p_sdp_mline_index" type="int" />
<param index="2" name="p_sdp_name" type="String" />
@@ -28,35 +28,45 @@
</description>
</method>
<method name="_create_offer" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<description>
</description>
</method>
<method name="_get_connection_state" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="WebRTCPeerConnection.ConnectionState" />
+ <description>
+ </description>
+ </method>
+ <method name="_get_gathering_state" qualifiers="virtual const">
+ <return type="int" enum="WebRTCPeerConnection.GatheringState" />
+ <description>
+ </description>
+ </method>
+ <method name="_get_signaling_state" qualifiers="virtual const">
+ <return type="int" enum="WebRTCPeerConnection.SignalingState" />
<description>
</description>
</method>
<method name="_initialize" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<param index="0" name="p_config" type="Dictionary" />
<description>
</description>
</method>
<method name="_poll" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<description>
</description>
</method>
<method name="_set_local_description" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<param index="0" name="p_type" type="String" />
<param index="1" name="p_sdp" type="String" />
<description>
</description>
</method>
<method name="_set_remote_description" qualifiers="virtual">
- <return type="int" />
+ <return type="int" enum="Error" />
<param index="0" name="p_type" type="String" />
<param index="1" name="p_sdp" type="String" />
<description>
diff --git a/modules/webrtc/library_godot_webrtc.js b/modules/webrtc/library_godot_webrtc.js
index e57e4299e0..e6604eecd7 100644
--- a/modules/webrtc/library_godot_webrtc.js
+++ b/modules/webrtc/library_godot_webrtc.js
@@ -220,64 +220,123 @@ mergeInto(LibraryManager.library, GodotRTCDataChannel);
const GodotRTCPeerConnection = {
$GodotRTCPeerConnection__deps: ['$IDHandler', '$GodotRuntime', '$GodotRTCDataChannel'],
$GodotRTCPeerConnection: {
- onstatechange: function (p_id, p_conn, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return;
- }
- let state;
- switch (p_conn.iceConnectionState) {
- case 'new':
- state = 0;
- break;
- case 'checking':
- state = 1;
- break;
- case 'connected':
- case 'completed':
- state = 2;
- break;
- case 'disconnected':
- state = 3;
- break;
- case 'failed':
- state = 4;
- break;
- case 'closed':
- default:
- state = 5;
- break;
- }
- callback(state);
+ // Enums
+ ConnectionState: {
+ 'new': 0,
+ 'connecting': 1,
+ 'connected': 2,
+ 'disconnected': 3,
+ 'failed': 4,
+ 'closed': 5,
},
- onicecandidate: function (p_id, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref || !event.candidate) {
- return;
+ ConnectionStateCompat: {
+ // Using values from IceConnectionState for browsers that do not support ConnectionState (notably Firefox).
+ 'new': 0,
+ 'checking': 1,
+ 'connected': 2,
+ 'completed': 2,
+ 'disconnected': 3,
+ 'failed': 4,
+ 'closed': 5,
+ },
+
+ IceGatheringState: {
+ 'new': 0,
+ 'gathering': 1,
+ 'complete': 2,
+ },
+
+ SignalingState: {
+ 'stable': 0,
+ 'have-local-offer': 1,
+ 'have-remote-offer': 2,
+ 'have-local-pranswer': 3,
+ 'have-remote-pranswer': 4,
+ 'closed': 5,
+ },
+
+ // Callbacks
+ create: function (config, onConnectionChange, onSignalingChange, onIceGatheringChange, onIceCandidate, onDataChannel) {
+ let conn = null;
+ try {
+ conn = new RTCPeerConnection(config);
+ } catch (e) {
+ GodotRuntime.error(e);
+ return 0;
}
- const c = event.candidate;
- const candidate_str = GodotRuntime.allocString(c.candidate);
- const mid_str = GodotRuntime.allocString(c.sdpMid);
- callback(mid_str, c.sdpMLineIndex, candidate_str);
- GodotRuntime.free(candidate_str);
- GodotRuntime.free(mid_str);
+ const id = IDHandler.add(conn);
+
+ if ('connectionState' in conn && conn['connectionState'] !== undefined) {
+ // Use "connectionState" if supported
+ conn.onconnectionstatechange = function (event) {
+ if (!IDHandler.get(id)) {
+ return;
+ }
+ onConnectionChange(GodotRTCPeerConnection.ConnectionState[conn.connectionState] || 0);
+ };
+ } else {
+ // Fall back to using "iceConnectionState" when "connectionState" is not supported (notably Firefox).
+ conn.oniceconnectionstatechange = function (event) {
+ if (!IDHandler.get(id)) {
+ return;
+ }
+ onConnectionChange(GodotRTCPeerConnection.ConnectionStateCompat[conn.iceConnectionState] || 0);
+ };
+ }
+ conn.onicegatheringstatechange = function (event) {
+ if (!IDHandler.get(id)) {
+ return;
+ }
+ onIceGatheringChange(GodotRTCPeerConnection.IceGatheringState[conn.iceGatheringState] || 0);
+ };
+ conn.onsignalingstatechange = function (event) {
+ if (!IDHandler.get(id)) {
+ return;
+ }
+ onSignalingChange(GodotRTCPeerConnection.SignalingState[conn.signalingState] || 0);
+ };
+ conn.onicecandidate = function (event) {
+ if (!IDHandler.get(id)) {
+ return;
+ }
+ const c = event.candidate;
+ if (!c || !c.candidate) {
+ return;
+ }
+ const candidate_str = GodotRuntime.allocString(c.candidate);
+ const mid_str = GodotRuntime.allocString(c.sdpMid);
+ onIceCandidate(mid_str, c.sdpMLineIndex, candidate_str);
+ GodotRuntime.free(candidate_str);
+ GodotRuntime.free(mid_str);
+ };
+ conn.ondatachannel = function (event) {
+ if (!IDHandler.get(id)) {
+ return;
+ }
+ const cid = IDHandler.add(event.channel);
+ onDataChannel(cid);
+ };
+ return id;
},
- ondatachannel: function (p_id, callback, event) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
+ destroy: function (p_id) {
+ const conn = IDHandler.get(p_id);
+ if (!conn) {
return;
}
-
- const cid = IDHandler.add(event.channel);
- callback(cid);
+ conn.onconnectionstatechange = null;
+ conn.oniceconnectionstatechange = null;
+ conn.onicegatheringstatechange = null;
+ conn.onsignalingstatechange = null;
+ conn.onicecandidate = null;
+ conn.ondatachannel = null;
+ IDHandler.remove(p_id);
},
onsession: function (p_id, callback, session) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
+ if (!IDHandler.get(p_id)) {
return;
}
const type_str = GodotRuntime.allocString(session.type);
@@ -297,27 +356,19 @@ const GodotRTCPeerConnection = {
},
},
- godot_js_rtc_pc_create__sig: 'iiiiii',
- godot_js_rtc_pc_create: function (p_config, p_ref, p_on_state_change, p_on_candidate, p_on_datachannel) {
- const onstatechange = GodotRuntime.get_func(p_on_state_change).bind(null, p_ref);
- const oncandidate = GodotRuntime.get_func(p_on_candidate).bind(null, p_ref);
- const ondatachannel = GodotRuntime.get_func(p_on_datachannel).bind(null, p_ref);
-
- const config = JSON.parse(GodotRuntime.parseString(p_config));
- let conn = null;
- try {
- conn = new RTCPeerConnection(config);
- } catch (e) {
- GodotRuntime.error(e);
- return 0;
- }
-
- const base = GodotRTCPeerConnection;
- const id = IDHandler.add(conn);
- conn.oniceconnectionstatechange = base.onstatechange.bind(null, id, conn, onstatechange);
- conn.onicecandidate = base.onicecandidate.bind(null, id, oncandidate);
- conn.ondatachannel = base.ondatachannel.bind(null, id, ondatachannel);
- return id;
+ godot_js_rtc_pc_create__sig: 'iiiiiiii',
+ godot_js_rtc_pc_create: function (p_config, p_ref, p_on_connection_state_change, p_on_ice_gathering_state_change, p_on_signaling_state_change, p_on_ice_candidate, p_on_datachannel) {
+ const wrap = function (p_func) {
+ return GodotRuntime.get_func(p_func).bind(null, p_ref);
+ };
+ return GodotRTCPeerConnection.create(
+ JSON.parse(GodotRuntime.parseString(p_config)),
+ wrap(p_on_connection_state_change),
+ wrap(p_on_signaling_state_change),
+ wrap(p_on_ice_gathering_state_change),
+ wrap(p_on_ice_candidate),
+ wrap(p_on_datachannel)
+ );
},
godot_js_rtc_pc_close__sig: 'vi',
@@ -331,14 +382,7 @@ const GodotRTCPeerConnection = {
godot_js_rtc_pc_destroy__sig: 'vi',
godot_js_rtc_pc_destroy: function (p_id) {
- const ref = IDHandler.get(p_id);
- if (!ref) {
- return;
- }
- ref.oniceconnectionstatechange = null;
- ref.onicecandidate = null;
- ref.ondatachannel = null;
- IDHandler.remove(p_id);
+ GodotRTCPeerConnection.destroy(p_id);
},
godot_js_rtc_pc_offer_create__sig: 'viiii',
diff --git a/modules/webrtc/webrtc_data_channel_extension.cpp b/modules/webrtc/webrtc_data_channel_extension.cpp
index b7ea8d22bb..4e16b77e81 100644
--- a/modules/webrtc/webrtc_data_channel_extension.cpp
+++ b/modules/webrtc/webrtc_data_channel_extension.cpp
@@ -56,160 +56,20 @@ void WebRTCDataChannelExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_buffered_amount);
}
-int WebRTCDataChannelExtension::get_available_packet_count() const {
- int count;
- if (GDVIRTUAL_CALL(_get_available_packet_count, count)) {
- return count;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_available_packet_count is unimplemented!");
- return -1;
-}
-
Error WebRTCDataChannelExtension::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- int err;
+ Error err;
if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) {
- return (Error)err;
+ return err;
}
WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_packet_native is unimplemented!");
return FAILED;
}
Error WebRTCDataChannelExtension::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- int err;
+ Error err;
if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) {
- return (Error)err;
+ return err;
}
WARN_PRINT_ONCE("WebRTCDataChannelExtension::_put_packet_native is unimplemented!");
return FAILED;
}
-
-int WebRTCDataChannelExtension::get_max_packet_size() const {
- int size;
- if (GDVIRTUAL_CALL(_get_max_packet_size, size)) {
- return size;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_max_packet_size is unimplemented!");
- return 0;
-}
-
-Error WebRTCDataChannelExtension::poll() {
- int err;
- if (GDVIRTUAL_CALL(_poll, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_poll is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
-void WebRTCDataChannelExtension::close() {
- if (GDVIRTUAL_CALL(_close)) {
- return;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_close is unimplemented!");
-}
-
-void WebRTCDataChannelExtension::set_write_mode(WriteMode p_mode) {
- if (GDVIRTUAL_CALL(_set_write_mode, p_mode)) {
- return;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_set_write_mode is unimplemented!");
-}
-
-WebRTCDataChannel::WriteMode WebRTCDataChannelExtension::get_write_mode() const {
- int mode;
- if (GDVIRTUAL_CALL(_get_write_mode, mode)) {
- return (WriteMode)mode;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_write_mode is unimplemented!");
- return WRITE_MODE_BINARY;
-}
-
-bool WebRTCDataChannelExtension::was_string_packet() const {
- bool was_string;
- if (GDVIRTUAL_CALL(_was_string_packet, was_string)) {
- return was_string;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_was_string_packet is unimplemented!");
- return false;
-}
-
-WebRTCDataChannel::ChannelState WebRTCDataChannelExtension::get_ready_state() const {
- int state;
- if (GDVIRTUAL_CALL(_get_ready_state, state)) {
- return (ChannelState)state;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_ready_state is unimplemented!");
- return STATE_CLOSED;
-}
-
-String WebRTCDataChannelExtension::get_label() const {
- String label;
- if (GDVIRTUAL_CALL(_get_label, label)) {
- return label;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_label is unimplemented!");
- return label;
-}
-
-bool WebRTCDataChannelExtension::is_ordered() const {
- bool ordered;
- if (GDVIRTUAL_CALL(_is_ordered, ordered)) {
- return ordered;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_is_ordered is unimplemented!");
- return false;
-}
-
-int WebRTCDataChannelExtension::get_id() const {
- int id;
- if (GDVIRTUAL_CALL(_get_id, id)) {
- return id;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_id is unimplemented!");
- return -1;
-}
-
-int WebRTCDataChannelExtension::get_max_packet_life_time() const {
- int lifetime;
- if (GDVIRTUAL_CALL(_get_max_packet_life_time, lifetime)) {
- return lifetime;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_max_packet_life_time is unimplemented!");
- return -1;
-}
-
-int WebRTCDataChannelExtension::get_max_retransmits() const {
- int retransmits;
- if (GDVIRTUAL_CALL(_get_max_retransmits, retransmits)) {
- return retransmits;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_max_retransmits is unimplemented!");
- return -1;
-}
-
-String WebRTCDataChannelExtension::get_protocol() const {
- String protocol;
- if (GDVIRTUAL_CALL(_get_protocol, protocol)) {
- return protocol;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_protocol is unimplemented!");
- return protocol;
-}
-
-bool WebRTCDataChannelExtension::is_negotiated() const {
- bool negotiated;
- if (GDVIRTUAL_CALL(_is_negotiated, negotiated)) {
- return negotiated;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_is_negotiated is unimplemented!");
- return false;
-}
-
-int WebRTCDataChannelExtension::get_buffered_amount() const {
- int amount;
- if (GDVIRTUAL_CALL(_get_buffered_amount, amount)) {
- return amount;
- }
- WARN_PRINT_ONCE("WebRTCDataChannelExtension::_get_buffered_amount is unimplemented!");
- return -1;
-}
diff --git a/modules/webrtc/webrtc_data_channel_extension.h b/modules/webrtc/webrtc_data_channel_extension.h
index 83bb627815..467163ed93 100644
--- a/modules/webrtc/webrtc_data_channel_extension.h
+++ b/modules/webrtc/webrtc_data_channel_extension.h
@@ -33,6 +33,7 @@
#include "webrtc_data_channel.h"
+#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
@@ -44,53 +45,33 @@ protected:
static void _bind_methods();
public:
- virtual void set_write_mode(WriteMode mode) override;
- virtual WriteMode get_write_mode() const override;
- virtual bool was_string_packet() const override;
+ EXBIND0R(Error, poll);
+ EXBIND0(close);
- virtual ChannelState get_ready_state() const override;
- virtual String get_label() const override;
- virtual bool is_ordered() const override;
- virtual int get_id() const override;
- virtual int get_max_packet_life_time() const override;
- virtual int get_max_retransmits() const override;
- virtual String get_protocol() const override;
- virtual bool is_negotiated() const override;
- virtual int get_buffered_amount() const override;
+ EXBIND1(set_write_mode, WriteMode);
+ EXBIND0RC(WriteMode, get_write_mode);
- virtual Error poll() override;
- virtual void close() override;
+ EXBIND0RC(bool, was_string_packet);
+
+ EXBIND0RC(ChannelState, get_ready_state);
+ EXBIND0RC(String, get_label);
+ EXBIND0RC(bool, is_ordered);
+ EXBIND0RC(int, get_id);
+ EXBIND0RC(int, get_max_packet_life_time);
+ EXBIND0RC(int, get_max_retransmits);
+ EXBIND0RC(String, get_protocol);
+ EXBIND0RC(bool, is_negotiated);
+ EXBIND0RC(int, get_buffered_amount);
/** Inherited from PacketPeer: **/
- virtual int get_available_packet_count() const override;
+ EXBIND0RC(int, get_available_packet_count);
+ EXBIND0RC(int, get_max_packet_size);
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override;
- virtual int get_max_packet_size() const override;
-
/** GDExtension **/
- GDVIRTUAL0RC(int, _get_available_packet_count);
- GDVIRTUAL2R(int, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>);
- GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int);
- GDVIRTUAL0RC(int, _get_max_packet_size);
-
- GDVIRTUAL0R(int, _poll);
- GDVIRTUAL0(_close);
-
- GDVIRTUAL1(_set_write_mode, int);
- GDVIRTUAL0RC(int, _get_write_mode);
-
- GDVIRTUAL0RC(bool, _was_string_packet);
-
- GDVIRTUAL0RC(int, _get_ready_state);
- GDVIRTUAL0RC(String, _get_label);
- GDVIRTUAL0RC(bool, _is_ordered);
- GDVIRTUAL0RC(int, _get_id);
- GDVIRTUAL0RC(int, _get_max_packet_life_time);
- GDVIRTUAL0RC(int, _get_max_retransmits);
- GDVIRTUAL0RC(String, _get_protocol);
- GDVIRTUAL0RC(bool, _is_negotiated);
- GDVIRTUAL0RC(int, _get_buffered_amount);
+ GDVIRTUAL2R(Error, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>);
+ GDVIRTUAL2R(Error, _put_packet, GDNativeConstPtr<const uint8_t>, int);
WebRTCDataChannelExtension() {}
};
diff --git a/modules/webrtc/webrtc_peer_connection.cpp b/modules/webrtc/webrtc_peer_connection.cpp
index d885b9262b..5aa891d35c 100644
--- a/modules/webrtc/webrtc_peer_connection.cpp
+++ b/modules/webrtc/webrtc_peer_connection.cpp
@@ -69,6 +69,8 @@ void WebRTCPeerConnection::_bind_methods() {
ClassDB::bind_method(D_METHOD("close"), &WebRTCPeerConnection::close);
ClassDB::bind_method(D_METHOD("get_connection_state"), &WebRTCPeerConnection::get_connection_state);
+ ClassDB::bind_method(D_METHOD("get_gathering_state"), &WebRTCPeerConnection::get_gathering_state);
+ ClassDB::bind_method(D_METHOD("get_signaling_state"), &WebRTCPeerConnection::get_signaling_state);
ADD_SIGNAL(MethodInfo("session_description_created", PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::STRING, "sdp")));
ADD_SIGNAL(MethodInfo("ice_candidate_created", PropertyInfo(Variant::STRING, "media"), PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::STRING, "name")));
@@ -80,6 +82,17 @@ void WebRTCPeerConnection::_bind_methods() {
BIND_ENUM_CONSTANT(STATE_DISCONNECTED);
BIND_ENUM_CONSTANT(STATE_FAILED);
BIND_ENUM_CONSTANT(STATE_CLOSED);
+
+ BIND_ENUM_CONSTANT(GATHERING_STATE_NEW);
+ BIND_ENUM_CONSTANT(GATHERING_STATE_GATHERING);
+ BIND_ENUM_CONSTANT(GATHERING_STATE_COMPLETE);
+
+ BIND_ENUM_CONSTANT(SIGNALING_STATE_STABLE);
+ BIND_ENUM_CONSTANT(SIGNALING_STATE_HAVE_LOCAL_OFFER);
+ BIND_ENUM_CONSTANT(SIGNALING_STATE_HAVE_REMOTE_OFFER);
+ BIND_ENUM_CONSTANT(SIGNALING_STATE_HAVE_LOCAL_PRANSWER);
+ BIND_ENUM_CONSTANT(SIGNALING_STATE_HAVE_REMOTE_PRANSWER);
+ BIND_ENUM_CONSTANT(SIGNALING_STATE_CLOSED);
}
WebRTCPeerConnection::WebRTCPeerConnection() {
diff --git a/modules/webrtc/webrtc_peer_connection.h b/modules/webrtc/webrtc_peer_connection.h
index 122ea3d00f..76f29f9d68 100644
--- a/modules/webrtc/webrtc_peer_connection.h
+++ b/modules/webrtc/webrtc_peer_connection.h
@@ -47,6 +47,21 @@ public:
STATE_CLOSED
};
+ enum GatheringState {
+ GATHERING_STATE_NEW,
+ GATHERING_STATE_GATHERING,
+ GATHERING_STATE_COMPLETE,
+ };
+
+ enum SignalingState {
+ SIGNALING_STATE_STABLE,
+ SIGNALING_STATE_HAVE_LOCAL_OFFER,
+ SIGNALING_STATE_HAVE_REMOTE_OFFER,
+ SIGNALING_STATE_HAVE_LOCAL_PRANSWER,
+ SIGNALING_STATE_HAVE_REMOTE_PRANSWER,
+ SIGNALING_STATE_CLOSED,
+ };
+
private:
static StringName default_extension;
@@ -57,6 +72,8 @@ public:
static void set_default_extension(const StringName &p_name);
virtual ConnectionState get_connection_state() const = 0;
+ virtual GatheringState get_gathering_state() const = 0;
+ virtual SignalingState get_signaling_state() const = 0;
virtual Error initialize(Dictionary p_config = Dictionary()) = 0;
virtual Ref<WebRTCDataChannel> create_data_channel(String p_label, Dictionary p_options = Dictionary()) = 0;
@@ -74,5 +91,7 @@ public:
};
VARIANT_ENUM_CAST(WebRTCPeerConnection::ConnectionState);
+VARIANT_ENUM_CAST(WebRTCPeerConnection::GatheringState);
+VARIANT_ENUM_CAST(WebRTCPeerConnection::SignalingState);
#endif // WEBRTC_PEER_CONNECTION_H
diff --git a/modules/webrtc/webrtc_peer_connection_extension.cpp b/modules/webrtc/webrtc_peer_connection_extension.cpp
index 85c04b3b19..592a1f8a97 100644
--- a/modules/webrtc/webrtc_peer_connection_extension.cpp
+++ b/modules/webrtc/webrtc_peer_connection_extension.cpp
@@ -32,6 +32,8 @@
void WebRTCPeerConnectionExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_connection_state);
+ GDVIRTUAL_BIND(_get_gathering_state);
+ GDVIRTUAL_BIND(_get_signaling_state);
GDVIRTUAL_BIND(_initialize, "p_config");
GDVIRTUAL_BIND(_create_data_channel, "p_label", "p_config");
GDVIRTUAL_BIND(_create_offer);
@@ -42,24 +44,6 @@ void WebRTCPeerConnectionExtension::_bind_methods() {
GDVIRTUAL_BIND(_close);
}
-WebRTCPeerConnection::ConnectionState WebRTCPeerConnectionExtension::get_connection_state() const {
- int state;
- if (GDVIRTUAL_CALL(_get_connection_state, state)) {
- return (ConnectionState)state;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_get_connection_state is unimplemented!");
- return STATE_DISCONNECTED;
-}
-
-Error WebRTCPeerConnectionExtension::initialize(Dictionary p_config) {
- int err;
- if (GDVIRTUAL_CALL(_initialize, p_config, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_initialize is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
Ref<WebRTCDataChannel> WebRTCPeerConnectionExtension::create_data_channel(String p_label, Dictionary p_options) {
Object *ret = nullptr;
if (GDVIRTUAL_CALL(_create_data_channel, p_label, p_options, ret)) {
@@ -70,55 +54,3 @@ Ref<WebRTCDataChannel> WebRTCPeerConnectionExtension::create_data_channel(String
WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_create_data_channel is unimplemented!");
return nullptr;
}
-
-Error WebRTCPeerConnectionExtension::create_offer() {
- int err;
- if (GDVIRTUAL_CALL(_create_offer, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_create_offer is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
-Error WebRTCPeerConnectionExtension::set_local_description(String p_type, String p_sdp) {
- int err;
- if (GDVIRTUAL_CALL(_set_local_description, p_type, p_sdp, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_set_local_description is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
-Error WebRTCPeerConnectionExtension::set_remote_description(String p_type, String p_sdp) {
- int err;
- if (GDVIRTUAL_CALL(_set_remote_description, p_type, p_sdp, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_set_remote_description is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
-Error WebRTCPeerConnectionExtension::add_ice_candidate(String p_sdp_mid_name, int p_sdp_mline_index, String p_sdp_name) {
- int err;
- if (GDVIRTUAL_CALL(_add_ice_candidate, p_sdp_mid_name, p_sdp_mline_index, p_sdp_name, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_add_ice_candidate is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
-Error WebRTCPeerConnectionExtension::poll() {
- int err;
- if (GDVIRTUAL_CALL(_poll, err)) {
- return (Error)err;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_poll is unimplemented!");
- return ERR_UNCONFIGURED;
-}
-
-void WebRTCPeerConnectionExtension::close() {
- if (GDVIRTUAL_CALL(_close)) {
- return;
- }
- WARN_PRINT_ONCE("WebRTCPeerConnectionExtension::_close is unimplemented!");
-}
diff --git a/modules/webrtc/webrtc_peer_connection_extension.h b/modules/webrtc/webrtc_peer_connection_extension.h
index bde19c173b..085069debb 100644
--- a/modules/webrtc/webrtc_peer_connection_extension.h
+++ b/modules/webrtc/webrtc_peer_connection_extension.h
@@ -33,6 +33,7 @@
#include "webrtc_peer_connection.h"
+#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/gdvirtual.gen.inc"
#include "core/object/script_language.h"
#include "core/variant/native_ptr.h"
@@ -44,27 +45,23 @@ protected:
static void _bind_methods();
public:
- virtual ConnectionState get_connection_state() const override;
-
- virtual Error initialize(Dictionary p_config = Dictionary()) override;
+ // FIXME Can't be directly exposed due to issues in exchanging Ref(s) between godot and extensions.
+ // See godot-cpp GH-652 .
virtual Ref<WebRTCDataChannel> create_data_channel(String p_label, Dictionary p_options = Dictionary()) override;
- virtual Error create_offer() override;
- virtual Error set_remote_description(String type, String sdp) override;
- virtual Error set_local_description(String type, String sdp) override;
- virtual Error add_ice_candidate(String p_sdp_mid_name, int p_sdp_mline_index, String p_sdp_name) override;
- virtual Error poll() override;
- virtual void close() override;
+ GDVIRTUAL2R(Object *, _create_data_channel, String, Dictionary);
+ // EXBIND2R(Ref<WebRTCDataChannel>, create_data_channel, String, Dictionary);
/** GDExtension **/
- GDVIRTUAL0RC(int, _get_connection_state);
- GDVIRTUAL1R(int, _initialize, Dictionary);
- GDVIRTUAL2R(Object *, _create_data_channel, String, Dictionary);
- GDVIRTUAL0R(int, _create_offer);
- GDVIRTUAL2R(int, _set_remote_description, String, String);
- GDVIRTUAL2R(int, _set_local_description, String, String);
- GDVIRTUAL3R(int, _add_ice_candidate, String, int, String);
- GDVIRTUAL0R(int, _poll);
- GDVIRTUAL0(_close);
+ EXBIND0RC(ConnectionState, get_connection_state);
+ EXBIND0RC(GatheringState, get_gathering_state);
+ EXBIND0RC(SignalingState, get_signaling_state);
+ EXBIND1R(Error, initialize, Dictionary);
+ EXBIND0R(Error, create_offer);
+ EXBIND2R(Error, set_remote_description, String, String);
+ EXBIND2R(Error, set_local_description, String, String);
+ EXBIND3R(Error, add_ice_candidate, String, int, String);
+ EXBIND0R(Error, poll);
+ EXBIND0(close);
WebRTCPeerConnectionExtension() {}
};
diff --git a/modules/webrtc/webrtc_peer_connection_js.cpp b/modules/webrtc/webrtc_peer_connection_js.cpp
index f48705253b..a371312ae9 100644
--- a/modules/webrtc/webrtc_peer_connection_js.cpp
+++ b/modules/webrtc/webrtc_peer_connection_js.cpp
@@ -51,6 +51,16 @@ void WebRTCPeerConnectionJS::_on_connection_state_changed(void *p_obj, int p_sta
peer->_conn_state = (ConnectionState)p_state;
}
+void WebRTCPeerConnectionJS::_on_gathering_state_changed(void *p_obj, int p_state) {
+ WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj);
+ peer->_gathering_state = (GatheringState)p_state;
+}
+
+void WebRTCPeerConnectionJS::_on_signaling_state_changed(void *p_obj, int p_state) {
+ WebRTCPeerConnectionJS *peer = static_cast<WebRTCPeerConnectionJS *>(p_obj);
+ peer->_signaling_state = (SignalingState)p_state;
+}
+
void WebRTCPeerConnectionJS::_on_error(void *p_obj) {
ERR_PRINT("RTCPeerConnection error!");
}
@@ -100,7 +110,7 @@ Error WebRTCPeerConnectionJS::initialize(Dictionary p_config) {
_conn_state = STATE_NEW;
String config = Variant(p_config).to_json_string();
- _js_id = godot_js_rtc_pc_create(config.utf8().get_data(), this, &_on_connection_state_changed, &_on_ice_candidate, &_on_data_channel);
+ _js_id = godot_js_rtc_pc_create(config.utf8().get_data(), this, &_on_connection_state_changed, &_on_gathering_state_changed, &_on_signaling_state_changed, &_on_ice_candidate, &_on_data_channel);
return _js_id ? OK : FAILED;
}
@@ -117,14 +127,19 @@ Error WebRTCPeerConnectionJS::poll() {
return OK;
}
+WebRTCPeerConnection::GatheringState WebRTCPeerConnectionJS::get_gathering_state() const {
+ return _gathering_state;
+}
+
+WebRTCPeerConnection::SignalingState WebRTCPeerConnectionJS::get_signaling_state() const {
+ return _signaling_state;
+}
+
WebRTCPeerConnection::ConnectionState WebRTCPeerConnectionJS::get_connection_state() const {
return _conn_state;
}
WebRTCPeerConnectionJS::WebRTCPeerConnectionJS() {
- _conn_state = STATE_NEW;
- _js_id = 0;
-
Dictionary config;
initialize(config);
}
diff --git a/modules/webrtc/webrtc_peer_connection_js.h b/modules/webrtc/webrtc_peer_connection_js.h
index 50266129e4..e62ad6af28 100644
--- a/modules/webrtc/webrtc_peer_connection_js.h
+++ b/modules/webrtc/webrtc_peer_connection_js.h
@@ -37,11 +37,13 @@
extern "C" {
typedef void (*RTCOnIceConnectionStateChange)(void *p_obj, int p_state);
+typedef void (*RTCOnIceGatheringStateChange)(void *p_obj, int p_state);
+typedef void (*RTCOnSignalingStateChange)(void *p_obj, int p_state);
typedef void (*RTCOnIceCandidate)(void *p_obj, const char *p_mid, int p_mline_idx, const char *p_candidate);
typedef void (*RTCOnDataChannel)(void *p_obj, int p_id);
typedef void (*RTCOnSession)(void *p_obj, const char *p_type, const char *p_sdp);
typedef void (*RTCOnError)(void *p_obj);
-extern int godot_js_rtc_pc_create(const char *p_config, void *p_obj, RTCOnIceConnectionStateChange p_on_state_change, RTCOnIceCandidate p_on_candidate, RTCOnDataChannel p_on_datachannel);
+extern int godot_js_rtc_pc_create(const char *p_config, void *p_obj, RTCOnIceConnectionStateChange p_on_connection_state_change, RTCOnIceGatheringStateChange p_on_gathering_state_change, RTCOnSignalingStateChange p_on_signaling_state_change, RTCOnIceCandidate p_on_candidate, RTCOnDataChannel p_on_datachannel);
extern void godot_js_rtc_pc_close(int p_id);
extern void godot_js_rtc_pc_destroy(int p_id);
extern void godot_js_rtc_pc_offer_create(int p_id, void *p_obj, RTCOnSession p_on_session, RTCOnError p_on_error);
@@ -55,10 +57,14 @@ class WebRTCPeerConnectionJS : public WebRTCPeerConnection {
GDCLASS(WebRTCPeerConnectionJS, WebRTCPeerConnection);
private:
- int _js_id;
- ConnectionState _conn_state;
+ int _js_id = 0;
+ ConnectionState _conn_state = STATE_NEW;
+ GatheringState _gathering_state = GATHERING_STATE_NEW;
+ SignalingState _signaling_state = SIGNALING_STATE_STABLE;
static void _on_connection_state_changed(void *p_obj, int p_state);
+ static void _on_gathering_state_changed(void *p_obj, int p_state);
+ static void _on_signaling_state_changed(void *p_obj, int p_state);
static void _on_ice_candidate(void *p_obj, const char *p_mid_name, int p_mline_idx, const char *p_candidate);
static void _on_data_channel(void *p_obj, int p_channel);
static void _on_session_created(void *p_obj, const char *p_type, const char *p_session);
@@ -66,6 +72,8 @@ private:
public:
virtual ConnectionState get_connection_state() const override;
+ virtual GatheringState get_gathering_state() const override;
+ virtual SignalingState get_signaling_state() const override;
virtual Error initialize(Dictionary configuration = Dictionary()) override;
virtual Ref<WebRTCDataChannel> create_data_channel(String p_channel_name, Dictionary p_channel_config = Dictionary()) override;