Index: ps/trunk/source/ps/Replay.cpp =================================================================== --- ps/trunk/source/ps/Replay.cpp +++ ps/trunk/source/ps/Replay.cpp @@ -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 @@ -72,7 +72,7 @@ JS::RootedValue mods(cx, Mod::GetLoadedModsWithVersions(m_ScriptInterface)); m_ScriptInterface.SetProperty(attribs, "mods", mods); - m_Directory = createDateIndexSubdirectory(VisualReplay::GetDirectoryName()); + m_Directory = createDateIndexSubdirectory(VisualReplay::GetDirectoryPath()); debug_printf("Writing replay to %s\n", m_Directory.string8().c_str()); m_Stream = new std::ofstream(OsString(m_Directory / L"commands.txt").c_str(), std::ofstream::out | std::ofstream::trunc); Index: ps/trunk/source/ps/VisualReplay.h =================================================================== --- ps/trunk/source/ps/VisualReplay.h +++ ps/trunk/source/ps/VisualReplay.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 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 @@ -29,12 +29,20 @@ { /** - * Returns the path to the sim-log directory (that contains the directories with the replay files. - * - * @param scriptInterface - the ScriptInterface in which to create the return data. - * @return OsPath the absolute file path + * Returns the absolute path to the sim-log directory (that contains the directories with the replay files. + */ +OsPath GetDirectoryPath(); + +/** + * Returns the absolute path to the replay cache file. + */ +OsPath GetCacheFilePath(); + +/** + * Returns the absolute path to the temporary replay cache file used to + * always have a valid cache file in place even if bad things happen. */ -OsPath GetDirectoryName(); +OsPath GetTempCacheFilePath(); /** * Replays the commands.txt file in the given subdirectory visually. Index: ps/trunk/source/ps/VisualReplay.cpp =================================================================== --- ps/trunk/source/ps/VisualReplay.cpp +++ ps/trunk/source/ps/VisualReplay.cpp @@ -40,13 +40,19 @@ */ const u8 minimumReplayDuration = 3; -static const OsPath tempCacheFileName = VisualReplay::GetDirectoryName() / L"replayCache_temp.json"; -static const OsPath cacheFileName = VisualReplay::GetDirectoryName() / L"replayCache.json"; +OsPath VisualReplay::GetDirectoryPath() +{ + return Paths(g_args).UserData() / "replays" / engine_version; +} + +OsPath VisualReplay::GetCacheFilePath() +{ + return GetDirectoryPath() / L"replayCache.json"; +} -OsPath VisualReplay::GetDirectoryName() +OsPath VisualReplay::GetTempCacheFilePath() { - const Paths paths(g_args); - return OsPath(paths.UserData() / "replays" / engine_version); + return GetDirectoryPath() / L"replayCache_temp.json"; } bool VisualReplay::StartVisualReplay(const OsPath& directory) @@ -55,7 +61,7 @@ ENSURE(!g_NetClient); ENSURE(!g_Game); - const OsPath replayFile = VisualReplay::GetDirectoryName() / directory / L"commands.txt"; + const OsPath replayFile = VisualReplay::GetDirectoryPath() / directory / L"commands.txt"; if (!FileExists(replayFile)) return false; @@ -69,10 +75,10 @@ JSContext* cx = scriptInterface.GetContext(); JSAutoRequest rq(cx); - if (!FileExists(cacheFileName)) + if (!FileExists(GetCacheFilePath())) return false; - std::ifstream cacheStream(OsString(cacheFileName).c_str()); + std::ifstream cacheStream(OsString(GetCacheFilePath()).c_str()); CStr cacheStr((std::istreambuf_iterator(cacheStream)), std::istreambuf_iterator()); cacheStream.close(); @@ -85,7 +91,7 @@ } LOGWARNING("The replay cache file is corrupted, it will be deleted"); - wunlink(cacheFileName); + wunlink(GetCacheFilePath()); return false; } @@ -95,12 +101,12 @@ JSAutoRequest rq(cx); JS::RootedValue replaysRooted(cx, JS::ObjectValue(*replays)); - std::ofstream cacheStream(OsString(tempCacheFileName).c_str(), std::ofstream::out | std::ofstream::trunc); + std::ofstream cacheStream(OsString(GetTempCacheFilePath()).c_str(), std::ofstream::out | std::ofstream::trunc); cacheStream << scriptInterface.StringifyJSON(&replaysRooted); cacheStream.close(); - wunlink(cacheFileName); - if (wrename(tempCacheFileName, cacheFileName)) + wunlink(GetCacheFilePath()); + if (wrename(GetTempCacheFilePath(), GetCacheFilePath())) LOGERROR("Could not store the replay cache"); } @@ -139,7 +145,7 @@ JS::RootedObject replays(cx, JS_NewArrayObject(cx, 0)); DirectoryNames directories; - if (GetDirectoryEntries(GetDirectoryName(), nullptr, &directories) != INFO::OK) + if (GetDirectoryEntries(GetDirectoryPath(), nullptr, &directories) != INFO::OK) return replays; bool newReplays = false; @@ -155,7 +161,7 @@ // Don't return, because we want to save our progress break; - const OsPath replayFile = GetDirectoryName() / directory / L"commands.txt"; + const OsPath replayFile = GetDirectoryPath() / directory / L"commands.txt"; bool isNew = true; replayCacheMap::iterator it = fileList.find(directory); @@ -325,7 +331,7 @@ JS::Value VisualReplay::LoadReplayData(const ScriptInterface& scriptInterface, const OsPath& directory) { // The directory argument must not be constant, otherwise concatenating will fail - const OsPath replayFile = GetDirectoryName() / directory / L"commands.txt"; + const OsPath replayFile = GetDirectoryPath() / directory / L"commands.txt"; if (!FileExists(replayFile)) return JS::NullValue(); @@ -407,7 +413,7 @@ if (replayDirectory.empty()) return false; - const OsPath directory = GetDirectoryName() / replayDirectory; + const OsPath directory = GetDirectoryPath() / replayDirectory; return DirectoryExists(directory) && DeleteDirectory(directory) == INFO::OK; } @@ -420,7 +426,7 @@ pCxPrivate->pScriptInterface->Eval("({})", &attribs); // Return empty object if file doesn't exist - const OsPath replayFile = GetDirectoryName() / directoryName / L"commands.txt"; + const OsPath replayFile = GetDirectoryPath() / directoryName / L"commands.txt"; if (!FileExists(replayFile)) return attribs; @@ -483,7 +489,7 @@ bool VisualReplay::HasReplayMetadata(const OsPath& directoryName) { - const OsPath filePath(GetDirectoryName() / directoryName / L"metadata.json"); + const OsPath filePath(GetDirectoryPath() / directoryName / L"metadata.json"); if (!FileExists(filePath)) return false; @@ -503,7 +509,7 @@ JSAutoRequest rq(cx); JS::RootedValue metadata(cx); - std::ifstream* stream = new std::ifstream(OsString(GetDirectoryName() / directoryName / L"metadata.json").c_str()); + std::ifstream* stream = new std::ifstream(OsString(GetDirectoryPath() / directoryName / L"metadata.json").c_str()); ENSURE(stream->good()); CStr line; std::getline(*stream, line); Index: ps/trunk/source/ps/scripting/JSInterface_VisualReplay.cpp =================================================================== --- ps/trunk/source/ps/scripting/JSInterface_VisualReplay.cpp +++ ps/trunk/source/ps/scripting/JSInterface_VisualReplay.cpp @@ -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 @@ -61,7 +61,7 @@ CStrW JSI_VisualReplay::GetReplayDirectoryName(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const CStrW& directoryName) { - return wstring_from_utf8(OsPath(VisualReplay::GetDirectoryName() / directoryName).string8()); + return wstring_from_utf8(OsPath(VisualReplay::GetDirectoryPath() / directoryName).string8()); } void JSI_VisualReplay::RegisterScriptFunctions(const ScriptInterface& scriptInterface)