summaryrefslogtreecommitdiff
path: root/src/network/room_member.cpp
diff options
context:
space:
mode:
authorGravatar B3n302017-08-19 19:14:33 +0200
committerGravatar James Rowe2017-08-19 11:14:33 -0600
commit5d0a1e7efddf234234d54fe97395f6975f8d1a28 (patch)
treecef0c9114f39af64c2971509fb2d0197c73cc155 /src/network/room_member.cpp
parentMerge pull request #2881 from MerryMage/dsp-firm-check (diff)
downloadyuzu-5d0a1e7efddf234234d54fe97395f6975f8d1a28.tar.gz
yuzu-5d0a1e7efddf234234d54fe97395f6975f8d1a28.tar.xz
yuzu-5d0a1e7efddf234234d54fe97395f6975f8d1a28.zip
Added missing parts in libnetwork (#2838)
* Network: Set and send the game information over enet Added Callbacks for RoomMember and GetMemberList to Room in preparation for web_services.
Diffstat (limited to 'src/network/room_member.cpp')
-rw-r--r--src/network/room_member.cpp128
1 files changed, 118 insertions, 10 deletions
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index dac9bacae..f229ec6fd 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -5,6 +5,7 @@
5#include <atomic> 5#include <atomic>
6#include <list> 6#include <list>
7#include <mutex> 7#include <mutex>
8#include <set>
8#include <thread> 9#include <thread>
9#include "common/assert.h" 10#include "common/assert.h"
10#include "enet/enet.h" 11#include "enet/enet.h"
@@ -25,6 +26,9 @@ public:
25 /// Information about the room we're connected to. 26 /// Information about the room we're connected to.
26 RoomInformation room_information; 27 RoomInformation room_information;
27 28
29 /// The current game name, id and version
30 GameInfo current_game_info;
31
28 std::atomic<State> state{State::Idle}; ///< Current state of the RoomMember. 32 std::atomic<State> state{State::Idle}; ///< Current state of the RoomMember.
29 void SetState(const State new_state); 33 void SetState(const State new_state);
30 bool IsConnected() const; 34 bool IsConnected() const;
@@ -37,6 +41,24 @@ public:
37 std::unique_ptr<std::thread> loop_thread; 41 std::unique_ptr<std::thread> loop_thread;
38 std::mutex send_list_mutex; ///< Mutex that controls access to the `send_list` variable. 42 std::mutex send_list_mutex; ///< Mutex that controls access to the `send_list` variable.
39 std::list<Packet> send_list; ///< A list that stores all packets to send the async 43 std::list<Packet> send_list; ///< A list that stores all packets to send the async
44
45 template <typename T>
46 using CallbackSet = std::set<CallbackHandle<T>>;
47 std::mutex callback_mutex; ///< The mutex used for handling callbacks
48
49 class Callbacks {
50 public:
51 template <typename T>
52 CallbackSet<T>& Get();
53
54 private:
55 CallbackSet<WifiPacket> callback_set_wifi_packet;
56 CallbackSet<ChatEntry> callback_set_chat_messages;
57 CallbackSet<RoomInformation> callback_set_room_information;
58 CallbackSet<State> callback_set_state;
59 };
60 Callbacks callbacks; ///< All CallbackSets to all events
61
40 void MemberLoop(); 62 void MemberLoop();
41 63
42 void StartLoop(); 64 void StartLoop();
@@ -84,12 +106,20 @@ public:
84 * Disconnects the RoomMember from the Room 106 * Disconnects the RoomMember from the Room
85 */ 107 */
86 void Disconnect(); 108 void Disconnect();
109
110 template <typename T>
111 void Invoke(const T& data);
112
113 template <typename T>
114 CallbackHandle<T> Bind(std::function<void(const T&)> callback);
87}; 115};
88 116
89// RoomMemberImpl 117// RoomMemberImpl
90void RoomMember::RoomMemberImpl::SetState(const State new_state) { 118void RoomMember::RoomMemberImpl::SetState(const State new_state) {
91 state = new_state; 119 if (state != new_state) {
92 // TODO(B3N30): Invoke the callback functions 120 state = new_state;
121 Invoke<State>(state);
122 }
93} 123}
94 124
95bool RoomMember::RoomMemberImpl::IsConnected() const { 125bool RoomMember::RoomMemberImpl::IsConnected() const {
@@ -195,9 +225,10 @@ void RoomMember::RoomMemberImpl::HandleRoomInformationPacket(const ENetEvent* ev
195 for (auto& member : member_information) { 225 for (auto& member : member_information) {
196 packet >> member.nickname; 226 packet >> member.nickname;
197 packet >> member.mac_address; 227 packet >> member.mac_address;
198 packet >> member.game_name; 228 packet >> member.game_info.name;
229 packet >> member.game_info.id;
199 } 230 }
200 // TODO(B3N30): Invoke callbacks 231 Invoke(room_information);
201} 232}
202 233
203void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) { 234void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) {
@@ -209,7 +240,7 @@ void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) {
209 240
210 // Parse the MAC Address from the packet 241 // Parse the MAC Address from the packet
211 packet >> mac_address; 242 packet >> mac_address;
212 // TODO(B3N30): Invoke callbacks 243 SetState(State::Joined);
213} 244}
214 245
215void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) { 246void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) {
@@ -235,7 +266,7 @@ void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) {
235 266
236 packet >> wifi_packet.data; 267 packet >> wifi_packet.data;
237 268
238 // TODO(B3N30): Invoke callbacks 269 Invoke<WifiPacket>(wifi_packet);
239} 270}
240 271
241void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) { 272void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) {
@@ -248,7 +279,7 @@ void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) {
248 ChatEntry chat_entry{}; 279 ChatEntry chat_entry{};
249 packet >> chat_entry.nickname; 280 packet >> chat_entry.nickname;
250 packet >> chat_entry.message; 281 packet >> chat_entry.message;
251 // TODO(B3N30): Invoke callbacks 282 Invoke<ChatEntry>(chat_entry);
252} 283}
253 284
254void RoomMember::RoomMemberImpl::Disconnect() { 285void RoomMember::RoomMemberImpl::Disconnect() {
@@ -276,6 +307,46 @@ void RoomMember::RoomMemberImpl::Disconnect() {
276 server = nullptr; 307 server = nullptr;
277} 308}
278 309
310template <>
311RoomMember::RoomMemberImpl::CallbackSet<WifiPacket>& RoomMember::RoomMemberImpl::Callbacks::Get() {
312 return callback_set_wifi_packet;
313}
314
315template <>
316RoomMember::RoomMemberImpl::CallbackSet<RoomMember::State>&
317RoomMember::RoomMemberImpl::Callbacks::Get() {
318 return callback_set_state;
319}
320
321template <>
322RoomMember::RoomMemberImpl::CallbackSet<RoomInformation>&
323RoomMember::RoomMemberImpl::Callbacks::Get() {
324 return callback_set_room_information;
325}
326
327template <>
328RoomMember::RoomMemberImpl::CallbackSet<ChatEntry>& RoomMember::RoomMemberImpl::Callbacks::Get() {
329 return callback_set_chat_messages;
330}
331
332template <typename T>
333void RoomMember::RoomMemberImpl::Invoke(const T& data) {
334 std::lock_guard<std::mutex> lock(callback_mutex);
335 CallbackSet<T> callback_set = callbacks.Get<T>();
336 for (auto const& callback : callback_set)
337 (*callback)(data);
338}
339
340template <typename T>
341RoomMember::CallbackHandle<T> RoomMember::RoomMemberImpl::Bind(
342 std::function<void(const T&)> callback) {
343 std::lock_guard<std::mutex> lock(callback_mutex);
344 CallbackHandle<T> handle;
345 handle = std::make_shared<std::function<void(const T&)>>(callback);
346 callbacks.Get<T>().insert(handle);
347 return handle;
348}
349
279// RoomMember 350// RoomMember
280RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} { 351RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} {
281 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0); 352 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0);
@@ -339,6 +410,7 @@ void RoomMember::Join(const std::string& nick, const char* server_addr, u16 serv
339 room_member_impl->SetState(State::Joining); 410 room_member_impl->SetState(State::Joining);
340 room_member_impl->StartLoop(); 411 room_member_impl->StartLoop();
341 room_member_impl->SendJoinRequest(nick, preferred_mac); 412 room_member_impl->SendJoinRequest(nick, preferred_mac);
413 SendGameInfo(room_member_impl->current_game_info);
342 } else { 414 } else {
343 room_member_impl->SetState(State::CouldNotConnect); 415 room_member_impl->SetState(State::CouldNotConnect);
344 } 416 }
@@ -366,17 +438,53 @@ void RoomMember::SendChatMessage(const std::string& message) {
366 room_member_impl->Send(std::move(packet)); 438 room_member_impl->Send(std::move(packet));
367} 439}
368 440
369void RoomMember::SendGameName(const std::string& game_name) { 441void RoomMember::SendGameInfo(const GameInfo& game_info) {
442 room_member_impl->current_game_info = game_info;
443 if (!IsConnected())
444 return;
445
370 Packet packet; 446 Packet packet;
371 packet << static_cast<u8>(IdSetGameName); 447 packet << static_cast<u8>(IdSetGameInfo);
372 packet << game_name; 448 packet << game_info.name;
449 packet << game_info.id;
373 room_member_impl->Send(std::move(packet)); 450 room_member_impl->Send(std::move(packet));
374} 451}
375 452
453RoomMember::CallbackHandle<RoomMember::State> RoomMember::BindOnStateChanged(
454 std::function<void(const RoomMember::State&)> callback) {
455 return room_member_impl->Bind(callback);
456}
457
458RoomMember::CallbackHandle<WifiPacket> RoomMember::BindOnWifiPacketReceived(
459 std::function<void(const WifiPacket&)> callback) {
460 return room_member_impl->Bind(callback);
461}
462
463RoomMember::CallbackHandle<RoomInformation> RoomMember::BindOnRoomInformationChanged(
464 std::function<void(const RoomInformation&)> callback) {
465 return room_member_impl->Bind(callback);
466}
467
468RoomMember::CallbackHandle<ChatEntry> RoomMember::BindOnChatMessageRecieved(
469 std::function<void(const ChatEntry&)> callback) {
470 return room_member_impl->Bind(callback);
471}
472
473template <typename T>
474void RoomMember::Unbind(CallbackHandle<T> handle) {
475 std::lock_guard<std::mutex> lock(room_member_impl->callback_mutex);
476 room_member_impl->callbacks.Get<T>().erase(handle);
477}
478
376void RoomMember::Leave() { 479void RoomMember::Leave() {
377 room_member_impl->SetState(State::Idle); 480 room_member_impl->SetState(State::Idle);
378 room_member_impl->loop_thread->join(); 481 room_member_impl->loop_thread->join();
379 room_member_impl->loop_thread.reset(); 482 room_member_impl->loop_thread.reset();
380} 483}
381 484
485template void RoomMember::Unbind(CallbackHandle<WifiPacket>);
486template void RoomMember::Unbind(CallbackHandle<RoomMember::State>);
487template void RoomMember::Unbind(CallbackHandle<RoomInformation>);
488template void RoomMember::Unbind(CallbackHandle<ChatEntry>);
489
382} // namespace Network 490} // namespace Network