Use StructuredClone in m_GuiMessageQueue

The elements have to be cloned either way. Now they don't have to be
traced when they are in the queue.
This commit is contained in:
phosit 2024-11-10 18:18:40 +01:00
parent 2a2d5de350
commit f23dde2f73
No known key found for this signature in database
GPG key ID: C9430B600671C268
3 changed files with 11 additions and 34 deletions

View file

@ -77,8 +77,6 @@ CNetClient::CNetClient(CGame* game, const CStrW& username, const CStr& hostJID)
{
m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it
JS_AddExtraGCRootsTracer(GetScriptInterface().GetGeneralJSContext(), CNetClient::Trace, this);
// Set up transitions for session
AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, &OnConnect, this);
@ -146,13 +144,6 @@ CNetClient::~CNetClient()
m_ClientTurnManager->OnDestroyConnection();
DestroyConnection();
JS_RemoveExtraGCRootsTracer(GetScriptInterface().GetGeneralJSContext(), CNetClient::Trace, this);
}
void CNetClient::TraceMember(JSTracer *trc)
{
for (JS::Heap<JS::Value>& guiMessage : m_GuiMessageQueue)
JS::TraceEdge(trc, &guiMessage, "m_GuiMessageQueue");
}
void CNetClient::SetGamePassword(const CStr& hashedPassword)
@ -366,7 +357,7 @@ void CNetClient::CheckServerConnection()
}
}
void CNetClient::GuiPoll(JS::MutableHandleValue ret)
void CNetClient::GuiPoll(const ScriptRequest& rq, JS::MutableHandleValue ret)
{
if (m_GuiMessageQueue.empty())
{
@ -374,7 +365,7 @@ void CNetClient::GuiPoll(JS::MutableHandleValue ret)
return;
}
ret.set(m_GuiMessageQueue.front());
Script::ReadStructuredClone(rq, m_GuiMessageQueue.front(), ret);
m_GuiMessageQueue.pop_front();
}
@ -386,7 +377,7 @@ std::string CNetClient::TestReadGuiMessages()
JS::RootedValue msg(rq.cx);
while (true)
{
GuiPoll(&msg);
GuiPoll(rq, &msg);
if (msg.isUndefined())
break;
r += Script::ToString(rq, &msg) + "\n";

View file

@ -27,6 +27,7 @@
#include "ps/CStr.h"
#include "scriptinterface/Object.h"
#include "scriptinterface/ScriptRequest.h"
#include "scriptinterface/StructuredClone.h"
#include <ctime>
#include <deque>
@ -81,19 +82,6 @@ public:
virtual ~CNetClient();
/**
* We assume that adding a tracing function that's only called
* during GC is better for performance than using a
* PersistentRooted<T> where each value needs to be added to
* the root set.
*/
static void Trace(JSTracer *trc, void *data)
{
reinterpret_cast<CNetClient*>(data)->TraceMember(trc);
}
void TraceMember(JSTracer *trc);
void SetControllerSecret(const std::string& secret);
bool IsController() const { return m_IsController; }
@ -168,7 +156,7 @@ public:
*
* @return next message, or the value 'undefined' if the queue is empty
*/
void GuiPoll(JS::MutableHandleValue);
void GuiPoll(const ScriptRequest& rq, JS::MutableHandleValue ret);
/**
* Add a message to the queue, to be read by GuiPoll.
@ -181,7 +169,7 @@ public:
JS::RootedValue message(rq.cx);
Script::CreateObject(rq, &message, args...);
m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
m_GuiMessageQueue.push_back(Script::WriteStructuredClone(rq, message));
}
/**
@ -356,7 +344,7 @@ private:
CStr m_GUID;
/// Queue of messages for GuiPoll
std::deque<JS::Heap<JS::Value>> m_GuiMessageQueue;
std::deque<Script::StructuredClone> m_GuiMessageQueue;
/// Serialized game state received when joining an in-progress game
std::string m_JoinSyncBuffer;

View file

@ -196,16 +196,14 @@ CStr GetPlayerGUID()
return g_NetClient->GetGUID();
}
JS::Value PollNetworkClient(const ScriptInterface& guiInterface)
JS::Value PollNetworkClient(const ScriptRequest& rq)
{
if (!g_NetClient)
return JS::UndefinedValue();
// Convert from net client context to GUI script context
ScriptRequest rqNet(g_NetClient->GetScriptInterface());
JS::RootedValue pollNet(rqNet.cx);
g_NetClient->GuiPoll(&pollNet);
return Script::CloneValueFromOtherCompartment(guiInterface, g_NetClient->GetScriptInterface(), pollNet);
JS::RootedValue message{rq.cx};
g_NetClient->GuiPoll(rq, &message);
return message;
}
void SendGameSetupMessage(const ScriptInterface& scriptInterface, JS::HandleValue attribs1)