summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar B3n302017-07-08 15:24:47 +0200
committerGravatar B3n302017-07-16 21:28:47 +0200
commit589dc083a58425cadd8390ddd81854dcf054dd27 (patch)
treeb665a2ff519ddbfb7d3f6a035f076342d69c2148
parentMerge pull request #2824 from jroweboy/mingw_compile_test (diff)
downloadyuzu-589dc083a58425cadd8390ddd81854dcf054dd27.tar.gz
yuzu-589dc083a58425cadd8390ddd81854dcf054dd27.tar.xz
yuzu-589dc083a58425cadd8390ddd81854dcf054dd27.zip
Network: Threads for Room and RoomMember
-rw-r--r--src/network/room.cpp38
-rw-r--r--src/network/room.h14
-rw-r--r--src/network/room_member.cpp79
-rw-r--r--src/network/room_member.h1
4 files changed, 119 insertions, 13 deletions
diff --git a/src/network/room.cpp b/src/network/room.cpp
index 48de2f5cb..274cb4159 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <atomic>
6#include <thread>
5#include "enet/enet.h" 7#include "enet/enet.h"
6#include "network/room.h" 8#include "network/room.h"
7 9
@@ -16,8 +18,38 @@ public:
16 18
17 std::atomic<State> state{State::Closed}; ///< Current state of the room. 19 std::atomic<State> state{State::Closed}; ///< Current state of the room.
18 RoomInformation room_information; ///< Information about this room. 20 RoomInformation room_information; ///< Information about this room.
21
22 /// Thread that receives and dispatches network packets
23 std::unique_ptr<std::thread> room_thread;
24
25 /// Thread function that will receive and dispatch messages until the room is destroyed.
26 void ServerLoop();
27 void StartLoop();
19}; 28};
20 29
30// RoomImpl
31void Room::RoomImpl::ServerLoop() {
32 while (state != State::Closed) {
33 ENetEvent event;
34 if (enet_host_service(server, &event, 1000) > 0) {
35 switch (event.type) {
36 case ENET_EVENT_TYPE_RECEIVE:
37 // TODO(B3N30): Select the type of message and handle it
38 enet_packet_destroy(event.packet);
39 break;
40 case ENET_EVENT_TYPE_DISCONNECT:
41 // TODO(B3N30): Handle the disconnect from a client
42 break;
43 }
44 }
45 }
46}
47
48void Room::RoomImpl::StartLoop() {
49 room_thread = std::make_unique<std::thread>(&Room::RoomImpl::ServerLoop, this);
50}
51
52// Room
21Room::Room() : room_impl{std::make_unique<RoomImpl>()} {} 53Room::Room() : room_impl{std::make_unique<RoomImpl>()} {}
22 54
23Room::~Room() = default; 55Room::~Room() = default;
@@ -34,8 +66,7 @@ void Room::Create(const std::string& name, const std::string& server_address, u1
34 66
35 room_impl->room_information.name = name; 67 room_impl->room_information.name = name;
36 room_impl->room_information.member_slots = MaxConcurrentConnections; 68 room_impl->room_information.member_slots = MaxConcurrentConnections;
37 69 room_impl->StartLoop();
38 // TODO(B3N30): Start the receiving thread
39} 70}
40 71
41Room::State Room::GetState() const { 72Room::State Room::GetState() const {
@@ -48,7 +79,8 @@ const RoomInformation& Room::GetRoomInformation() const {
48 79
49void Room::Destroy() { 80void Room::Destroy() {
50 room_impl->state = State::Closed; 81 room_impl->state = State::Closed;
51 // TODO(B3n30): Join the receiving thread 82 room_impl->room_thread->join();
83 room_impl->room_thread.reset();
52 84
53 if (room_impl->server) { 85 if (room_impl->server) {
54 enet_host_destroy(room_impl->server); 86 enet_host_destroy(room_impl->server);
diff --git a/src/network/room.h b/src/network/room.h
index 70c64d5f1..0a6217c11 100644
--- a/src/network/room.h
+++ b/src/network/room.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
8#include <memory> 7#include <memory>
9#include <string> 8#include <string>
10#include "common/common_types.h" 9#include "common/common_types.h"
@@ -19,6 +18,19 @@ struct RoomInformation {
19 u32 member_slots; ///< Maximum number of members in this room 18 u32 member_slots; ///< Maximum number of members in this room
20}; 19};
21 20
21// The different types of messages that can be sent. The first byte of each packet defines the type
22typedef uint8_t MessageID;
23enum RoomMessageTypes {
24 IdJoinRequest = 1,
25 IdJoinSuccess,
26 IdRoomInformation,
27 IdSetGameName,
28 IdWifiPacket,
29 IdChatMessage,
30 IdNameCollision,
31 IdMacCollision
32};
33
22/// This is what a server [person creating a server] would use. 34/// This is what a server [person creating a server] would use.
23class Room final { 35class Room final {
24public: 36public:
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index c87f009f4..e1a0dfdab 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -2,6 +2,9 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <atomic>
6#include <mutex>
7#include <thread>
5#include "common/assert.h" 8#include "common/assert.h"
6#include "enet/enet.h" 9#include "enet/enet.h"
7#include "network/room_member.h" 10#include "network/room_member.h"
@@ -16,10 +19,65 @@ public:
16 ENetPeer* server = nullptr; ///< The server peer the client is connected to 19 ENetPeer* server = nullptr; ///< The server peer the client is connected to
17 20
18 std::atomic<State> state{State::Idle}; ///< Current state of the RoomMember. 21 std::atomic<State> state{State::Idle}; ///< Current state of the RoomMember.
22 void SetState(const State new_state);
23 bool IsConnected() const;
19 24
20 std::string nickname; ///< The nickname of this member. 25 std::string nickname; ///< The nickname of this member.
26
27 std::mutex network_mutex; ///< Mutex that controls access to the `client` variable.
28 /// Thread that receives and dispatches network packets
29 std::unique_ptr<std::thread> receive_thread;
30 void ReceiveLoop();
31 void StartLoop();
21}; 32};
22 33
34// RoomMemberImpl
35void RoomMember::RoomMemberImpl::SetState(const State new_state) {
36 state = new_state;
37 // TODO(B3N30): Invoke the callback functions
38}
39
40bool RoomMember::RoomMemberImpl::IsConnected() const {
41 return state == State::Joining || state == State::Joined;
42}
43
44void RoomMember::RoomMemberImpl::ReceiveLoop() {
45 // Receive packets while the connection is open
46 while (IsConnected()) {
47 std::lock_guard<std::mutex> lock(network_mutex);
48 ENetEvent event;
49 if (enet_host_service(client, &event, 1000) > 0) {
50 if (event.type == ENET_EVENT_TYPE_RECEIVE) {
51 switch (event.packet->data[0]) {
52 // TODO(B3N30): Handle the other message types
53 case IdNameCollision:
54 SetState(State::NameCollision);
55 enet_packet_destroy(event.packet);
56 enet_peer_disconnect(server, 0);
57 enet_peer_reset(server);
58 return;
59 break;
60 case IdMacCollision:
61 SetState(State::MacCollision);
62 enet_packet_destroy(event.packet);
63 enet_peer_disconnect(server, 0);
64 enet_peer_reset(server);
65 return;
66 break;
67 default:
68 break;
69 }
70 enet_packet_destroy(event.packet);
71 }
72 }
73 }
74};
75
76void RoomMember::RoomMemberImpl::StartLoop() {
77 receive_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::ReceiveLoop, this);
78}
79
80// RoomMember
23RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} { 81RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} {
24 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0); 82 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0);
25 ASSERT_MSG(room_member_impl->client != nullptr, "Could not create client"); 83 ASSERT_MSG(room_member_impl->client != nullptr, "Could not create client");
@@ -44,7 +102,7 @@ void RoomMember::Join(const std::string& nick, const char* server_addr, u16 serv
44 enet_host_connect(room_member_impl->client, &address, NumChannels, 0); 102 enet_host_connect(room_member_impl->client, &address, NumChannels, 0);
45 103
46 if (!room_member_impl->server) { 104 if (!room_member_impl->server) {
47 room_member_impl->state = State::Error; 105 room_member_impl->SetState(State::Error);
48 return; 106 return;
49 } 107 }
50 108
@@ -52,22 +110,27 @@ void RoomMember::Join(const std::string& nick, const char* server_addr, u16 serv
52 int net = enet_host_service(room_member_impl->client, &event, ConnectionTimeoutMs); 110 int net = enet_host_service(room_member_impl->client, &event, ConnectionTimeoutMs);
53 if (net > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { 111 if (net > 0 && event.type == ENET_EVENT_TYPE_CONNECT) {
54 room_member_impl->nickname = nick; 112 room_member_impl->nickname = nick;
55 room_member_impl->state = State::Joining; 113 room_member_impl->SetState(State::Joining);
114 room_member_impl->StartLoop();
56 // TODO(B3N30): Send a join request with the nickname to the server 115 // TODO(B3N30): Send a join request with the nickname to the server
57 // TODO(B3N30): Start the receive thread
58 } else { 116 } else {
59 room_member_impl->state = State::CouldNotConnect; 117 room_member_impl->SetState(State::CouldNotConnect);
60 } 118 }
61} 119}
62 120
63bool RoomMember::IsConnected() const { 121bool RoomMember::IsConnected() const {
64 return room_member_impl->state == State::Joining || room_member_impl->state == State::Joined; 122 return room_member_impl->IsConnected();
65} 123}
66 124
67void RoomMember::Leave() { 125void RoomMember::Leave() {
68 enet_peer_disconnect(room_member_impl->server, 0); 126 ASSERT_MSG(room_member_impl->receive_thread != nullptr, "Must be in a room to leave it.");
69 room_member_impl->state = State::Idle; 127 {
70 // TODO(B3N30): Close the receive thread 128 std::lock_guard<std::mutex> lock(room_member_impl->network_mutex);
129 enet_peer_disconnect(room_member_impl->server, 0);
130 room_member_impl->SetState(State::Idle);
131 }
132 room_member_impl->receive_thread->join();
133 room_member_impl->receive_thread.reset();
71 enet_peer_reset(room_member_impl->server); 134 enet_peer_reset(room_member_impl->server);
72} 135}
73 136
diff --git a/src/network/room_member.h b/src/network/room_member.h
index 177622b69..89ec6ae5a 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
8#include <memory> 7#include <memory>
9#include <string> 8#include <string>
10#include "common/common_types.h" 9#include "common/common_types.h"