mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-24 07:46:54 +00:00
Fixes saving/loading problems introduced in 28bdd8540f.
* CGameLoader created a new JS::Value when assigning to m_Metadata. This means it didn't actually update metadata in SavedGames::Load. The new approach solves this problem and should work well if CScriptValRooted gets replaced in the future. * The cloning in ScriptFunctions.cpp was required. Removing it caused compartment mismatches. * Now CGameLoader loads the metadata unconditinally because we didn't actually use the option to not load load it. Ref #2415 This was SVN commit r15589.
This commit is contained in:
@@ -219,11 +219,14 @@ void StartGame(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal attribs, int p
|
||||
g_Game->StartGame(gameAttribs, "");
|
||||
}
|
||||
|
||||
CScriptVal StartSavedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring name)
|
||||
CScriptVal StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name)
|
||||
{
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
JSContext* cx = sim->GetScriptInterface().GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
// We need to be careful with different compartments and contexts.
|
||||
// The GUI calls this function from the GUI context and expects the return value in the same context.
|
||||
// The game we start from here creates another context and expects data in this context.
|
||||
|
||||
JSContext* cxGui = pCxPrivate->pScriptInterface->GetContext();
|
||||
JSAutoRequest rq(cxGui);
|
||||
|
||||
ENSURE(!g_NetServer);
|
||||
ENSURE(!g_NetClient);
|
||||
@@ -231,27 +234,33 @@ CScriptVal StartSavedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::w
|
||||
ENSURE(!g_Game);
|
||||
|
||||
// Load the saved game data from disk
|
||||
CScriptValRooted metadata;
|
||||
JS::RootedValue guiContextMetadata(cxGui);
|
||||
std::string savedState;
|
||||
Status err = SavedGames::Load(name, sim->GetScriptInterface(), metadata, savedState);
|
||||
Status err = SavedGames::Load(name, *(pCxPrivate->pScriptInterface), &guiContextMetadata, savedState);
|
||||
if (err < 0)
|
||||
return CScriptVal();
|
||||
return JS::UndefinedValue();
|
||||
|
||||
g_Game = new CGame();
|
||||
|
||||
JS::RootedValue gameMetadata(cx, metadata.get());
|
||||
{
|
||||
CSimulation2* sim = g_Game->GetSimulation2();
|
||||
JSContext* cxGame = sim->GetScriptInterface().GetContext();
|
||||
JSAutoRequest rq(cxGame);
|
||||
|
||||
JS::RootedValue gameContextMetadata(cxGame,
|
||||
sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), guiContextMetadata));
|
||||
JS::RootedValue gameInitAttributes(cxGame);
|
||||
sim->GetScriptInterface().GetProperty(gameContextMetadata, "initAttributes", &gameInitAttributes);
|
||||
|
||||
JS::RootedValue gameInitAttributes(cx);
|
||||
sim->GetScriptInterface().GetProperty(gameMetadata, "initAttributes", &gameInitAttributes);
|
||||
int playerID;
|
||||
sim->GetScriptInterface().GetProperty(gameContextMetadata, "player", playerID);
|
||||
|
||||
int playerID;
|
||||
sim->GetScriptInterface().GetProperty(gameMetadata, "player", playerID);
|
||||
// Start the game
|
||||
g_Game->SetPlayerID(playerID);
|
||||
g_Game->StartGame(CScriptValRooted(cxGame, gameInitAttributes), savedState);
|
||||
}
|
||||
|
||||
// Start the game
|
||||
g_Game->SetPlayerID(playerID);
|
||||
g_Game->StartGame(CScriptValRooted(cx, gameInitAttributes), savedState);
|
||||
|
||||
return gameMetadata.get();
|
||||
return guiContextMetadata.get();
|
||||
}
|
||||
|
||||
void SaveGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename, std::wstring description, CScriptVal GUIMetadata)
|
||||
|
||||
Reference in New Issue
Block a user