diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a263810..f43cd008 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -535,9 +535,14 @@ if (ISLE_EXTENSIONS) extensions/src/multiplayer/charactercloner.cpp extensions/src/multiplayer/networkmanager.cpp extensions/src/multiplayer/remoteplayer.cpp - extensions/src/multiplayer/websockettransport.cpp extensions/src/multiplayer/worldstatesync.cpp ) + if(EMSCRIPTEN) + target_sources(lego1 PRIVATE + extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp + extensions/src/multiplayer/platforms/emscripten/callbacks.cpp + ) + endif() endif() if (ISLE_BUILD_APP) @@ -595,7 +600,7 @@ if (ISLE_BUILD_APP) ) if(ISLE_EXTENSIONS) target_sources(isle PRIVATE - extensions/src/multiplayer/wasm_exports.cpp + extensions/src/multiplayer/platforms/emscripten/wasm_exports.cpp ) endif() target_compile_definitions(isle PRIVATE "ISLE_EMSCRIPTEN_HOST=\"${ISLE_EMSCRIPTEN_HOST}\"") diff --git a/extensions/include/extensions/multiplayer.h b/extensions/include/extensions/multiplayer.h index 840f8359..8f9f3958 100644 --- a/extensions/include/extensions/multiplayer.h +++ b/extensions/include/extensions/multiplayer.h @@ -13,6 +13,7 @@ namespace Multiplayer { class NetworkManager; class NetworkTransport; +class PlatformCallbacks; } // namespace Multiplayer namespace Extensions @@ -42,6 +43,7 @@ class MultiplayerExt { private: static Multiplayer::NetworkManager* s_networkManager; static Multiplayer::NetworkTransport* s_transport; + static Multiplayer::PlatformCallbacks* s_callbacks; }; #ifdef EXTENSIONS diff --git a/extensions/include/extensions/multiplayer/networkmanager.h b/extensions/include/extensions/multiplayer/networkmanager.h index adcf41f4..1506afc2 100644 --- a/extensions/include/extensions/multiplayer/networkmanager.h +++ b/extensions/include/extensions/multiplayer/networkmanager.h @@ -1,6 +1,7 @@ #pragma once #include "extensions/multiplayer/networktransport.h" +#include "extensions/multiplayer/platformcallbacks.h" #include "extensions/multiplayer/protocol.h" #include "extensions/multiplayer/remoteplayer.h" #include "extensions/multiplayer/worldstatesync.h" @@ -33,7 +34,7 @@ class NetworkManager : public MxCore { return !strcmp(p_name, NetworkManager::ClassName()) || MxCore::IsA(p_name); } - void Initialize(NetworkTransport* p_transport); + void Initialize(NetworkTransport* p_transport, PlatformCallbacks* p_callbacks); void Shutdown(); void Connect(const char* p_roomId); @@ -78,6 +79,7 @@ class NetworkManager : public MxCore { void SendMessage(const T& p_msg); NetworkTransport* m_transport; + PlatformCallbacks* m_callbacks; WorldStateSync m_worldSync; std::map> m_remotePlayers; diff --git a/extensions/include/extensions/multiplayer/platformcallbacks.h b/extensions/include/extensions/multiplayer/platformcallbacks.h new file mode 100644 index 00000000..d9c3663a --- /dev/null +++ b/extensions/include/extensions/multiplayer/platformcallbacks.h @@ -0,0 +1,15 @@ +#pragma once + +namespace Multiplayer +{ + +class PlatformCallbacks { +public: + virtual ~PlatformCallbacks() = default; + + // Called when the visible player count changes (joins, leaves, world transitions). + // p_count = players visible in current world, or -1 if not in a multiplayer world. + virtual void OnPlayerCountChanged(int p_count) = 0; +}; + +} // namespace Multiplayer diff --git a/extensions/include/extensions/multiplayer/platforms/emscripten/callbacks.h b/extensions/include/extensions/multiplayer/platforms/emscripten/callbacks.h new file mode 100644 index 00000000..2798b196 --- /dev/null +++ b/extensions/include/extensions/multiplayer/platforms/emscripten/callbacks.h @@ -0,0 +1,17 @@ +#pragma once + +#ifdef __EMSCRIPTEN__ + +#include "extensions/multiplayer/platformcallbacks.h" + +namespace Multiplayer +{ + +class EmscriptenCallbacks : public PlatformCallbacks { +public: + void OnPlayerCountChanged(int p_count) override; +}; + +} // namespace Multiplayer + +#endif // __EMSCRIPTEN__ diff --git a/extensions/include/extensions/multiplayer/websockettransport.h b/extensions/include/extensions/multiplayer/platforms/emscripten/websockettransport.h similarity index 100% rename from extensions/include/extensions/multiplayer/websockettransport.h rename to extensions/include/extensions/multiplayer/platforms/emscripten/websockettransport.h diff --git a/extensions/src/multiplayer.cpp b/extensions/src/multiplayer.cpp index 91d6adc4..2dd0a782 100644 --- a/extensions/src/multiplayer.cpp +++ b/extensions/src/multiplayer.cpp @@ -8,8 +8,11 @@ #include "legoentity.h" #include "legogamestate.h" #include "misc.h" + #ifdef __EMSCRIPTEN__ -#include "extensions/multiplayer/websockettransport.h" +#include "extensions/multiplayer/platforms/emscripten/callbacks.h" +#include "extensions/multiplayer/platforms/emscripten/websockettransport.h" + #include #endif @@ -21,6 +24,7 @@ std::string MultiplayerExt::relayUrl; std::string MultiplayerExt::room; Multiplayer::NetworkManager* MultiplayerExt::s_networkManager = nullptr; Multiplayer::NetworkTransport* MultiplayerExt::s_transport = nullptr; +Multiplayer::PlatformCallbacks* MultiplayerExt::s_callbacks = nullptr; void MultiplayerExt::Initialize() { @@ -33,9 +37,10 @@ void MultiplayerExt::Initialize() #ifdef __EMSCRIPTEN__ s_transport = new Multiplayer::WebSocketTransport(relayUrl); + s_callbacks = new Multiplayer::EmscriptenCallbacks(); s_networkManager = new Multiplayer::NetworkManager(); - s_networkManager->Initialize(s_transport); + s_networkManager->Initialize(s_transport, s_callbacks); s_networkManager->Connect(room.c_str()); #endif diff --git a/extensions/src/multiplayer/networkmanager.cpp b/extensions/src/multiplayer/networkmanager.cpp index dd8825c0..d3f06e67 100644 --- a/extensions/src/multiplayer/networkmanager.cpp +++ b/extensions/src/multiplayer/networkmanager.cpp @@ -11,9 +11,6 @@ #include #include #include -#ifdef __EMSCRIPTEN__ -#include -#endif using namespace Multiplayer; @@ -32,8 +29,9 @@ void NetworkManager::SendMessage(const T& p_msg) } NetworkManager::NetworkManager() - : m_transport(nullptr), m_localPeerId(0), m_hostPeerId(0), m_sequence(0), m_lastBroadcastTime(0), - m_lastValidActorId(0), m_localWalkAnimId(0), m_localIdleAnimId(0), m_inIsleWorld(false), m_registered(false) + : m_transport(nullptr), m_callbacks(nullptr), m_localPeerId(0), m_hostPeerId(0), m_sequence(0), + m_lastBroadcastTime(0), m_lastValidActorId(0), m_localWalkAnimId(0), m_localIdleAnimId(0), m_inIsleWorld(false), + m_registered(false) { } @@ -78,9 +76,10 @@ MxResult NetworkManager::Tickle() return SUCCESS; } -void NetworkManager::Initialize(NetworkTransport* p_transport) +void NetworkManager::Initialize(NetworkTransport* p_transport, PlatformCallbacks* p_callbacks) { m_transport = p_transport; + m_callbacks = p_callbacks; m_worldSync.SetTransport(p_transport); } @@ -460,7 +459,10 @@ void NetworkManager::RemoveAllRemotePlayers() void NetworkManager::NotifyPlayerCountChanged() { -#ifdef __EMSCRIPTEN__ + if (!m_callbacks) { + return; + } + int count = -1; if (m_inIsleWorld) { count = 1; // local player @@ -470,17 +472,8 @@ void NetworkManager::NotifyPlayerCountChanged() } } } - // clang-format off - MAIN_THREAD_EM_ASM({ - var canvas = Module.canvas; - if (canvas) { - canvas.dispatchEvent(new CustomEvent('playerCountChanged', { - detail: { count: $0 < 0 ? null : $0 } - })); - } - }, count); - // clang-format on -#endif + + m_callbacks->OnPlayerCountChanged(count); } int8_t NetworkManager::DetectLocalVehicleType() diff --git a/extensions/src/multiplayer/platforms/emscripten/callbacks.cpp b/extensions/src/multiplayer/platforms/emscripten/callbacks.cpp new file mode 100644 index 00000000..f7a891fc --- /dev/null +++ b/extensions/src/multiplayer/platforms/emscripten/callbacks.cpp @@ -0,0 +1,26 @@ +#ifdef __EMSCRIPTEN__ + +#include "extensions/multiplayer/platforms/emscripten/callbacks.h" + +#include + +namespace Multiplayer +{ + +void EmscriptenCallbacks::OnPlayerCountChanged(int p_count) +{ + // clang-format off + MAIN_THREAD_EM_ASM({ + var canvas = Module.canvas; + if (canvas) { + canvas.dispatchEvent(new CustomEvent('playerCountChanged', { + detail: { count: $0 < 0 ? null : $0 } + })); + } + }, p_count); + // clang-format on +} + +} // namespace Multiplayer + +#endif // __EMSCRIPTEN__ diff --git a/extensions/src/multiplayer/platforms/emscripten/wasm_exports.cpp b/extensions/src/multiplayer/platforms/emscripten/wasm_exports.cpp new file mode 100644 index 00000000..f99dc23a --- /dev/null +++ b/extensions/src/multiplayer/platforms/emscripten/wasm_exports.cpp @@ -0,0 +1,39 @@ +#ifdef __EMSCRIPTEN__ + +#include "extensions/multiplayer.h" +#include "extensions/multiplayer/networkmanager.h" + +#include + +using namespace Extensions; + +extern "C" +{ + + EMSCRIPTEN_KEEPALIVE void mp_set_walk_animation(int index) + { + Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); + if (mgr) { + mgr->SetWalkAnimation(static_cast(index)); + } + } + + EMSCRIPTEN_KEEPALIVE void mp_set_idle_animation(int index) + { + Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); + if (mgr) { + mgr->SetIdleAnimation(static_cast(index)); + } + } + + EMSCRIPTEN_KEEPALIVE void mp_trigger_emote(int index) + { + Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); + if (mgr) { + mgr->SendEmote(static_cast(index)); + } + } + +} // extern "C" + +#endif diff --git a/extensions/src/multiplayer/websockettransport.cpp b/extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp similarity index 98% rename from extensions/src/multiplayer/websockettransport.cpp rename to extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp index cf9dcc85..e81228c4 100644 --- a/extensions/src/multiplayer/websockettransport.cpp +++ b/extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp @@ -1,6 +1,6 @@ #ifdef __EMSCRIPTEN__ -#include "extensions/multiplayer/websockettransport.h" +#include "extensions/multiplayer/platforms/emscripten/websockettransport.h" #include #include diff --git a/extensions/src/multiplayer/wasm_exports.cpp b/extensions/src/multiplayer/wasm_exports.cpp deleted file mode 100644 index f3366c28..00000000 --- a/extensions/src/multiplayer/wasm_exports.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifdef __EMSCRIPTEN__ - -#include "extensions/multiplayer.h" -#include "extensions/multiplayer/networkmanager.h" - -#include - -using namespace Extensions; - -extern "C" { - -EMSCRIPTEN_KEEPALIVE void mp_set_walk_animation(int index) -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - mgr->SetWalkAnimation(static_cast(index)); - } -} - -EMSCRIPTEN_KEEPALIVE void mp_set_idle_animation(int index) -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - mgr->SetIdleAnimation(static_cast(index)); - } -} - -EMSCRIPTEN_KEEPALIVE void mp_trigger_emote(int index) -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - mgr->SendEmote(static_cast(index)); - } -} - -} // extern "C" - -#endif