Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Net] ENet poll optimizations, fragmented unreliable transfer. #53129

Merged
merged 2 commits into from
Dec 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 52 additions & 36 deletions modules/enet/enet_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,58 +117,36 @@ Ref<ENetPacketPeer> ENetConnection::connect_to_host(const String &p_address, int
return out;
}

ENetConnection::EventType ENetConnection::service(int p_timeout, Event &r_event) {
ERR_FAIL_COND_V_MSG(!host, EVENT_ERROR, "The ENetConnection instance isn't currently active.");
ERR_FAIL_COND_V(r_event.peer.is_valid(), EVENT_ERROR);

// Drop peers that have already been disconnected.
// NOTE: Forcibly disconnected peers (i.e. peers disconnected via
// enet_peer_disconnect*) do not trigger DISCONNECTED events.
List<Ref<ENetPacketPeer>>::Element *E = peers.front();
while (E) {
if (!E->get()->is_active()) {
peers.erase(E->get());
}
E = E->next();
}

ENetEvent event;
int ret = enet_host_service(host, &event, p_timeout);

if (ret < 0) {
return EVENT_ERROR;
} else if (ret == 0) {
return EVENT_NONE;
}
switch (event.type) {
ENetConnection::EventType ENetConnection::_parse_event(const ENetEvent &p_event, Event &r_event) {
switch (p_event.type) {
case ENET_EVENT_TYPE_CONNECT: {
if (event.peer->data == nullptr) {
Ref<ENetPacketPeer> pp = memnew(ENetPacketPeer(event.peer));
if (p_event.peer->data == nullptr) {
Ref<ENetPacketPeer> pp = memnew(ENetPacketPeer(p_event.peer));
peers.push_back(pp);
}
r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data);
r_event.data = event.data;
r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data);
r_event.data = p_event.data;
return EVENT_CONNECT;
} break;
case ENET_EVENT_TYPE_DISCONNECT: {
// A peer disconnected.
if (event.peer->data != nullptr) {
Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data);
if (p_event.peer->data != nullptr) {
Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data);
pp->_on_disconnect();
peers.erase(pp);
r_event.peer = pp;
r_event.data = event.data;
r_event.data = p_event.data;
return EVENT_DISCONNECT;
}
return EVENT_ERROR;
} break;
case ENET_EVENT_TYPE_RECEIVE: {
// Packet reveived.
if (event.peer->data != nullptr) {
Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data);
r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)event.peer->data);
r_event.channel_id = event.channelID;
r_event.packet = event.packet;
if (p_event.peer->data != nullptr) {
Ref<ENetPacketPeer> pp = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data);
r_event.peer = Ref<ENetPacketPeer>((ENetPacketPeer *)p_event.peer->data);
r_event.channel_id = p_event.channelID;
r_event.packet = p_event.packet;
return EVENT_RECEIVE;
}
return EVENT_ERROR;
Expand All @@ -180,6 +158,44 @@ ENetConnection::EventType ENetConnection::service(int p_timeout, Event &r_event)
}
}

ENetConnection::EventType ENetConnection::service(int p_timeout, Event &r_event) {
ERR_FAIL_COND_V_MSG(!host, EVENT_ERROR, "The ENetConnection instance isn't currently active.");
ERR_FAIL_COND_V(r_event.peer.is_valid(), EVENT_ERROR);

// Drop peers that have already been disconnected.
// NOTE: Forcibly disconnected peers (i.e. peers disconnected via
// enet_peer_disconnect*) do not trigger DISCONNECTED events.
List<Ref<ENetPacketPeer>>::Element *E = peers.front();
while (E) {
if (!E->get()->is_active()) {
peers.erase(E->get());
}
E = E->next();
}

ENetEvent event;
int ret = enet_host_service(host, &event, p_timeout);

if (ret < 0) {
return EVENT_ERROR;
} else if (ret == 0) {
return EVENT_NONE;
}
return _parse_event(event, r_event);
}

int ENetConnection::check_events(EventType &r_type, Event &r_event) {
ERR_FAIL_COND_V_MSG(!host, -1, "The ENetConnection instance isn't currently active.");
ENetEvent event;
int ret = enet_host_check_events(host, &event);
if (ret < 0) {
r_type = EVENT_ERROR;
return ret;
}
r_type = _parse_event(event, r_event);
return ret;
}

void ENetConnection::flush() {
ERR_FAIL_COND_MSG(!host, "The ENetConnection instance isn't currently active.");
enet_host_flush(host);
Expand Down
2 changes: 2 additions & 0 deletions modules/enet/enet_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ENetConnection : public RefCounted {
ENetHost *host = nullptr;
List<Ref<ENetPacketPeer>> peers;

EventType _parse_event(const ENetEvent &p_event, Event &r_event);
Error _create(ENetAddress *p_address, int p_max_peers, int p_max_channels, int p_in_bandwidth, int p_out_bandwidth);
Array _service(int p_timeout = 0);
void _broadcast(int p_channel, PackedByteArray p_packet, int p_flags);
Expand Down Expand Up @@ -110,6 +111,7 @@ class ENetConnection : public RefCounted {
void destroy();
Ref<ENetPacketPeer> connect_to_host(const String &p_address, int p_port, int p_channels, int p_data = 0);
EventType service(int p_timeout, Event &r_event);
int check_events(EventType &r_type, Event &r_event);
void flush();
void bandwidth_limit(int p_in_bandwidth = 0, int p_out_bandwidth = 0);
void channel_limit(int p_max_channels);
Expand Down
Loading