Network: Made send async in RoomMember
This commit is contained in:
parent
859be35d54
commit
a0626221a5
4 changed files with 70 additions and 25 deletions
|
@ -3,6 +3,7 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include "common/assert.h"
|
||||
|
@ -33,8 +34,10 @@ public:
|
|||
|
||||
std::mutex network_mutex; ///< Mutex that controls access to the `client` variable.
|
||||
/// Thread that receives and dispatches network packets
|
||||
std::unique_ptr<std::thread> receive_thread;
|
||||
void ReceiveLoop();
|
||||
std::unique_ptr<std::thread> loop_thread;
|
||||
std::mutex send_list_mutex; ///< Mutex that controls access to the `send_list` variable.
|
||||
std::list<Packet> send_list; ///< A list that stores all packets to send the async
|
||||
void MemberLoop();
|
||||
void StartLoop();
|
||||
|
||||
/**
|
||||
|
@ -91,7 +94,7 @@ bool RoomMember::RoomMemberImpl::IsConnected() const {
|
|||
return state == State::Joining || state == State::Joined;
|
||||
}
|
||||
|
||||
void RoomMember::RoomMemberImpl::ReceiveLoop() {
|
||||
void RoomMember::RoomMemberImpl::MemberLoop() {
|
||||
// Receive packets while the connection is open
|
||||
while (IsConnected()) {
|
||||
std::lock_guard<std::mutex> lock(network_mutex);
|
||||
|
@ -121,6 +124,9 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
|
|||
case IdMacCollision:
|
||||
SetState(State::MacCollision);
|
||||
break;
|
||||
case IdVersionMismatch:
|
||||
SetState(State::WrongVersion);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -128,22 +134,30 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
|
|||
break;
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
SetState(State::LostConnection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(send_list_mutex);
|
||||
for (const auto& packet : send_list) {
|
||||
ENetPacket* enetPacket = enet_packet_create(packet.GetData(), packet.GetDataSize(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(server, 0, enetPacket);
|
||||
}
|
||||
enet_host_flush(client);
|
||||
send_list.clear();
|
||||
}
|
||||
}
|
||||
Disconnect();
|
||||
};
|
||||
|
||||
void RoomMember::RoomMemberImpl::StartLoop() {
|
||||
receive_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::ReceiveLoop, this);
|
||||
loop_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::MemberLoop, this);
|
||||
}
|
||||
|
||||
void RoomMember::RoomMemberImpl::Send(Packet& packet) {
|
||||
std::lock_guard<std::mutex> lock(network_mutex);
|
||||
ENetPacket* enetPacket =
|
||||
enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(server, 0, enetPacket);
|
||||
enet_host_flush(client);
|
||||
std::lock_guard<std::mutex> lock(send_list_mutex);
|
||||
send_list.push_back(std::move(packet));
|
||||
}
|
||||
|
||||
void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname,
|
||||
|
@ -152,6 +166,7 @@ void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname,
|
|||
packet << static_cast<MessageID>(IdJoinRequest);
|
||||
packet << nickname;
|
||||
packet << preferred_mac;
|
||||
packet << network_version;
|
||||
Send(packet);
|
||||
}
|
||||
|
||||
|
@ -238,11 +253,9 @@ void RoomMember::RoomMemberImpl::Disconnect() {
|
|||
room_information.member_slots = 0;
|
||||
room_information.name.clear();
|
||||
|
||||
if (server) {
|
||||
enet_peer_disconnect(server, 0);
|
||||
} else {
|
||||
if (!server)
|
||||
return;
|
||||
}
|
||||
enet_peer_disconnect(server, 0);
|
||||
|
||||
ENetEvent event;
|
||||
while (enet_host_service(client, &event, ConnectionTimeoutMs) > 0) {
|
||||
|
@ -296,14 +309,14 @@ RoomInformation RoomMember::GetRoomInformation() const {
|
|||
void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port,
|
||||
u16 client_port) {
|
||||
// If the member is connected, kill the connection first
|
||||
if (room_member_impl->receive_thread && room_member_impl->receive_thread->joinable()) {
|
||||
if (room_member_impl->loop_thread && room_member_impl->loop_thread->joinable()) {
|
||||
room_member_impl->SetState(State::Error);
|
||||
room_member_impl->receive_thread->join();
|
||||
room_member_impl->receive_thread.reset();
|
||||
room_member_impl->loop_thread->join();
|
||||
room_member_impl->loop_thread.reset();
|
||||
}
|
||||
// If the thread isn't running but the ptr still exists, reset it
|
||||
else if (room_member_impl->receive_thread) {
|
||||
room_member_impl->receive_thread.reset();
|
||||
else if (room_member_impl->loop_thread) {
|
||||
room_member_impl->loop_thread.reset();
|
||||
}
|
||||
|
||||
ENetAddress address{};
|
||||
|
@ -361,8 +374,8 @@ void RoomMember::SendGameName(const std::string& game_name) {
|
|||
|
||||
void RoomMember::Leave() {
|
||||
room_member_impl->SetState(State::Idle);
|
||||
room_member_impl->receive_thread->join();
|
||||
room_member_impl->receive_thread.reset();
|
||||
room_member_impl->loop_thread->join();
|
||||
room_member_impl->loop_thread.reset();
|
||||
}
|
||||
|
||||
} // namespace Network
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue