Remove gui/common/ hack by going through the GUIInterface and fragile
EndGame() hardcoding by saving if and only if a ReplayLogger exists
following 7470e88624
, refs #4020.
Refs D2211, D2213.
Differential Revision: https://code.wildfiregames.com/D2197
Based on patch by: irishninja
Tested on: clang 8.0.1, Jenkins
This was SVN commit r22991.
This commit is contained in:
parent
9425572bb1
commit
35408e7e7e
@ -82,17 +82,3 @@ function cancelOnLoadGameError(msg)
|
||||
|
||||
Engine.ResetCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Also called from the C++ side when ending the game.
|
||||
* The current page can be the summary screen or a message box, so it can't be moved to session/.
|
||||
*/
|
||||
function getReplayMetadata()
|
||||
{
|
||||
let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState");
|
||||
return {
|
||||
"timeElapsed": extendedSimState.timeElapsed,
|
||||
"playerStates": extendedSimState.players,
|
||||
"mapSettings": Engine.GetInitAttributes().settings
|
||||
};
|
||||
}
|
||||
|
@ -109,6 +109,7 @@
|
||||
{"nick": "idanwin"},
|
||||
{"nick": "Imarok", "name": "J. S."},
|
||||
{"nick": "infyquest", "name": "Vijay Kiran Kamuju"},
|
||||
{"nick": "irishninja", "name": "Brian Broll"},
|
||||
{"nick": "IronNerd", "name": "Matthew McMullan"},
|
||||
{"nick": "Itms", "name": "Nicolas Auvray"},
|
||||
{"nick": "Jaison", "name": "Marco tom Suden"},
|
||||
|
@ -42,7 +42,7 @@ var g_Ambient = ["audio/ambient/dayscape/day_temperate_gen_03.ogg"];
|
||||
/**
|
||||
* Map, player and match settings set in gamesetup.
|
||||
*/
|
||||
const g_GameAttributes = deepfreeze(Engine.GetInitAttributes());
|
||||
const g_GameAttributes = deepfreeze(Engine.GuiInterfaceCall("GetInitAttributes"));
|
||||
|
||||
/**
|
||||
* True if this is a multiplayer game.
|
||||
@ -733,7 +733,7 @@ function leaveGame(willRejoin)
|
||||
|
||||
// Before ending the game
|
||||
let replayDirectory = Engine.GetCurrentReplayDirectory();
|
||||
let simData = getReplayMetadata();
|
||||
let simData = Engine.GuiInterfaceCall("GetReplayMetadata");
|
||||
let playerID = Engine.GetPlayerID();
|
||||
|
||||
Engine.EndGame();
|
||||
|
@ -191,6 +191,27 @@ GuiInterface.prototype.GetExtendedSimulationState = function()
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the gamesettings that were chosen at the time the match started.
|
||||
*/
|
||||
GuiInterface.prototype.GetInitAttributes = function()
|
||||
{
|
||||
return InitAttributes;
|
||||
};
|
||||
|
||||
/**
|
||||
* This data will be stored in the replay metadata file after a match has been finished recording.
|
||||
*/
|
||||
GuiInterface.prototype.GetReplayMetadata = function()
|
||||
{
|
||||
let extendedSimState = this.GetExtendedSimulationState();
|
||||
return {
|
||||
"timeElapsed": extendedSimState.timeElapsed,
|
||||
"playerStates": extendedSimState.players,
|
||||
"mapSettings": InitAttributes.settings
|
||||
};
|
||||
};
|
||||
|
||||
GuiInterface.prototype.GetRenamedEntities = function(player)
|
||||
{
|
||||
if (this.miragedEntities[player])
|
||||
@ -1917,6 +1938,8 @@ let exposedFunctions = {
|
||||
|
||||
"GetSimulationState": 1,
|
||||
"GetExtendedSimulationState": 1,
|
||||
"GetInitAttributes": 1,
|
||||
"GetReplayMetadata": 1,
|
||||
"GetRenamedEntities": 1,
|
||||
"ClearRenamedEntities": 1,
|
||||
"GetEntityState": 1,
|
||||
|
@ -102,6 +102,9 @@ CGame::~CGame()
|
||||
if (CProfileManager::IsInitialised())
|
||||
g_Profiler.StructuralReset();
|
||||
|
||||
if (m_ReplayLogger)
|
||||
m_ReplayLogger->SaveMetadata(*m_Simulation2);
|
||||
|
||||
delete m_TurnManager;
|
||||
delete m_GameView;
|
||||
delete m_Simulation2;
|
||||
|
@ -701,10 +701,6 @@ static void ShutdownSDL()
|
||||
|
||||
void EndGame()
|
||||
{
|
||||
if (g_Game && g_Game->IsGameStarted() && !g_Game->IsVisualReplay() &&
|
||||
g_AtlasGameLoop && !g_AtlasGameLoop->running && CRenderer::IsInitialised())
|
||||
VisualReplay::SaveReplayMetadata(g_GUI->GetActiveGUI()->GetScriptInterface().get());
|
||||
|
||||
SAFE_DELETE(g_NetClient);
|
||||
SAFE_DELETE(g_NetServer);
|
||||
SAFE_DELETE(g_Game);
|
||||
|
@ -37,8 +37,11 @@
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/ScriptRuntime.h"
|
||||
#include "scriptinterface/ScriptStats.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpGuiInterface.h"
|
||||
#include "simulation2/helpers/Player.h"
|
||||
#include "simulation2/helpers/SimulationCommand.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/system/CmpPtr.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
@ -101,6 +104,32 @@ void CReplayLogger::Hash(const std::string& hash, bool quick)
|
||||
*m_Stream << "hash " << Hexify(hash) << "\n";
|
||||
}
|
||||
|
||||
void CReplayLogger::SaveMetadata(const CSimulation2& simulation)
|
||||
{
|
||||
CmpPtr<ICmpGuiInterface> cmpGuiInterface(simulation, SYSTEM_ENTITY);
|
||||
if (!cmpGuiInterface)
|
||||
{
|
||||
LOGERROR("Could not save replay metadata!");
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptInterface& scriptInterface = simulation.GetScriptInterface();
|
||||
JSContext* cx = scriptInterface.GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
JS::RootedValue arg(cx);
|
||||
JS::RootedValue metadata(cx);
|
||||
cmpGuiInterface->ScriptCall(INVALID_PLAYER, L"GetReplayMetadata", arg, &metadata);
|
||||
|
||||
const OsPath fileName = g_Game->GetReplayLogger().GetDirectory() / L"metadata.json";
|
||||
CreateDirectories(fileName.Parent(), 0700);
|
||||
|
||||
std::ofstream stream (OsString(fileName).c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
stream << scriptInterface.StringifyJSON(&metadata, false);
|
||||
stream.close();
|
||||
debug_printf("Saved replay metadata to %s\n", fileName.string8().c_str());
|
||||
}
|
||||
|
||||
OsPath CReplayLogger::GetDirectory() const
|
||||
{
|
||||
return m_Directory;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -22,6 +22,7 @@
|
||||
#include "scriptinterface/ScriptTypes.h"
|
||||
|
||||
struct SimulationCommand;
|
||||
class CSimulation2;
|
||||
class ScriptInterface;
|
||||
|
||||
/**
|
||||
@ -49,6 +50,11 @@ public:
|
||||
*/
|
||||
virtual void Hash(const std::string& hash, bool quick) = 0;
|
||||
|
||||
/**
|
||||
* Saves metadata.json containing part of the simulation state used for the summary screen.
|
||||
*/
|
||||
virtual void SaveMetadata(const CSimulation2& simulation) = 0;
|
||||
|
||||
/**
|
||||
* Remember the directory containing the commands.txt file, so that we can save additional files to it.
|
||||
*/
|
||||
@ -64,6 +70,7 @@ public:
|
||||
virtual void StartGame(JS::MutableHandleValue UNUSED(attribs)) { }
|
||||
virtual void Turn(u32 UNUSED(n), u32 UNUSED(turnLength), std::vector<SimulationCommand>& UNUSED(commands)) { }
|
||||
virtual void Hash(const std::string& UNUSED(hash), bool UNUSED(quick)) { }
|
||||
virtual void SaveMetadata(const CSimulation2& UNUSED(simulation)) { };
|
||||
virtual OsPath GetDirectory() const { return OsPath(); }
|
||||
};
|
||||
|
||||
@ -80,6 +87,7 @@ public:
|
||||
virtual void StartGame(JS::MutableHandleValue attribs);
|
||||
virtual void Turn(u32 n, u32 turnLength, std::vector<SimulationCommand>& commands);
|
||||
virtual void Hash(const std::string& hash, bool quick);
|
||||
virtual void SaveMetadata(const CSimulation2& simulation);
|
||||
virtual OsPath GetDirectory() const;
|
||||
|
||||
private:
|
||||
|
@ -473,30 +473,6 @@ void VisualReplay::AddReplayToCache(const ScriptInterface& scriptInterface, cons
|
||||
StoreCacheFile(scriptInterface, cachedReplaysObject);
|
||||
}
|
||||
|
||||
void VisualReplay::SaveReplayMetadata(ScriptInterface* scriptInterface)
|
||||
{
|
||||
JSContext* cx = scriptInterface->GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
JS::RootedValue metadata(cx);
|
||||
JS::RootedValue global(cx, scriptInterface->GetGlobalObject());
|
||||
|
||||
if (!scriptInterface->CallFunction(global, "getReplayMetadata", &metadata))
|
||||
{
|
||||
LOGERROR("Could not save replay metadata!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the directory of the currently active replay
|
||||
const OsPath fileName = g_Game->GetReplayLogger().GetDirectory() / L"metadata.json";
|
||||
CreateDirectories(fileName.Parent(), 0700);
|
||||
|
||||
std::ofstream stream (OsString(fileName).c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
stream << scriptInterface->StringifyJSON(&metadata, false);
|
||||
stream.close();
|
||||
debug_printf("Saved replay metadata to %s\n", fileName.string8().c_str());
|
||||
}
|
||||
|
||||
bool VisualReplay::HasReplayMetadata(const OsPath& directoryName)
|
||||
{
|
||||
const OsPath filePath(GetDirectoryPath() / directoryName / L"metadata.json");
|
||||
|
@ -114,11 +114,6 @@ bool HasReplayMetadata(const OsPath& directoryName);
|
||||
*/
|
||||
JS::Value GetReplayMetadata(ScriptInterface::CxPrivate* pCxPrivate, const OsPath& directoryName);
|
||||
|
||||
/**
|
||||
* Saves the metadata from the session to metadata.json.
|
||||
*/
|
||||
void SaveReplayMetadata(ScriptInterface* scriptInterface);
|
||||
|
||||
/**
|
||||
* Adds a replay to the replayCache.
|
||||
*/
|
||||
|
@ -861,6 +861,9 @@ void CSimulation2::LoadMapSettings()
|
||||
// Initialize here instead of in Update()
|
||||
GetScriptInterface().CallFunctionVoid(global, "LoadMapSettings", m->m_MapSettings);
|
||||
|
||||
GetScriptInterface().FreezeObject(m->m_InitAttributes, true);
|
||||
GetScriptInterface().SetGlobal("InitAttributes", m->m_InitAttributes, true, true, true);
|
||||
|
||||
if (!m->m_StartupScript.empty())
|
||||
GetScriptInterface().LoadScript(L"map startup script", m->m_StartupScript);
|
||||
|
||||
|
@ -34,22 +34,6 @@
|
||||
|
||||
#include <fstream>
|
||||
|
||||
JS::Value JSI_Simulation::GetInitAttributes(ScriptInterface::CxPrivate* pCxPrivate)
|
||||
{
|
||||
if (!g_Game)
|
||||
return JS::UndefinedValue();
|
||||
|
||||
JSContext* cx = g_Game->GetSimulation2()->GetScriptInterface().GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
JS::RootedValue initAttribs(cx);
|
||||
g_Game->GetSimulation2()->GetInitAttributes(&initAttribs);
|
||||
|
||||
return pCxPrivate->pScriptInterface->CloneValueFromOtherContext(
|
||||
g_Game->GetSimulation2()->GetScriptInterface(),
|
||||
initAttribs);
|
||||
}
|
||||
|
||||
JS::Value JSI_Simulation::GuiInterfaceCall(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue data)
|
||||
{
|
||||
if (!g_Game)
|
||||
@ -147,7 +131,6 @@ void JSI_Simulation::SetBoundingBoxDebugOverlay(ScriptInterface::CxPrivate* UNUS
|
||||
|
||||
void JSI_Simulation::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
|
||||
{
|
||||
scriptInterface.RegisterFunction<JS::Value, &GetInitAttributes>("GetInitAttributes");
|
||||
scriptInterface.RegisterFunction<JS::Value, std::wstring, JS::HandleValue, &GuiInterfaceCall>("GuiInterfaceCall");
|
||||
scriptInterface.RegisterFunction<void, JS::HandleValue, &PostNetworkCommand>("PostNetworkCommand");
|
||||
scriptInterface.RegisterFunction<void, &DumpSimState>("DumpSimState");
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
namespace JSI_Simulation
|
||||
{
|
||||
JS::Value GetInitAttributes(ScriptInterface::CxPrivate* pCxPrivate);
|
||||
JS::Value GuiInterfaceCall(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name, JS::HandleValue data);
|
||||
void PostNetworkCommand(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue cmd);
|
||||
entity_id_t PickEntityAtPoint(ScriptInterface::CxPrivate* pCxPrivate, int x, int y);
|
||||
|
Loading…
Reference in New Issue
Block a user