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:
Yves
2014-07-31 14:44:51 +00:00
parent cf563657b6
commit 2ae74221c7
3 changed files with 56 additions and 29 deletions
+26 -17
View File
@@ -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)