1
1
forked from 0ad/0ad

Alpha 23 "lobby lag" release fix.

Caches the loaded mod versions, so that GetEngineInfo doesn't read the
zip and json files everytime and returns about 1000 times faster.
Adds two missing includes.

The lobby froze multiple times every few seconds on updateGameList().
The gamesetup page was slowed down with every stanza sent and the
load savegame selection page was slowed down per savegame selection,
proportional to the number of installed zipped mods.

Introduced by: d5807cd59f and eca956a513
Differential Revision: https://code.wildfiregames.com/D1518
Reviewed By: wraitii
Comments By: Imarok (in D1512, P121), leper (in the lobby)
This was SVN commit r21823.
This commit is contained in:
elexis 2018-05-24 18:08:56 +00:00
parent 83d228fe7e
commit 44ec2e324e
5 changed files with 43 additions and 10 deletions

View File

@ -80,6 +80,7 @@
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/ScriptStats.h"
#include "scriptinterface/ScriptConversions.h"
#include "scriptinterface/ScriptRuntime.h"
#include "simulation2/Simulation2.h"
#include "lobby/IXmppClient.h"
#include "soundmanager/scripting/JSInterface_Sound.h"
@ -922,6 +923,8 @@ bool Init(const CmdLineArgs& args, int flags)
const int heapGrowthBytesGCTrigger = 20 * 1024 * 1024;
g_ScriptRuntime = ScriptInterface::CreateRuntime(shared_ptr<ScriptRuntime>(), runtimeSize, heapGrowthBytesGCTrigger);
Mod::CacheEnabledModVersions(g_ScriptRuntime);
// Special command-line mode to dump the entity schemas instead of running the game.
// (This must be done after loading VFS etc, but should be done before wasting time
// on anything else.)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Wildfire Games.
/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -79,6 +79,11 @@ extern void RenderCursor(bool RenderingState);
class CmdLineArgs;
class Paths;
extern const std::vector<CStr>& GetMods(const CmdLineArgs& args, int flags);
/**
* Mounts all files of the given mods in the global VFS.
* Make sure to call CacheEnabledModVersions after every call to this.
*/
extern void MountMods(const Paths& paths, const std::vector<CStr>& mods);
/**
* Returns true if successful, false if mods changed and restart_engine was called.

View File

@ -28,9 +28,12 @@
#include "ps/GameSetup/GameSetup.h"
#include "ps/GameSetup/Paths.h"
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/ScriptRuntime.h"
std::vector<CStr> g_modsLoaded;
std::vector<std::vector<CStr>> g_LoadedModVersions;
CmdLineArgs g_args;
JS::Value Mod::GetAvailableMods(const ScriptInterface& scriptInterface)
@ -101,29 +104,38 @@ JS::Value Mod::GetAvailableMods(const ScriptInterface& scriptInterface)
return JS::ObjectValue(*obj);
}
JS::Value Mod::GetLoadedModsWithVersions(const ScriptInterface& scriptInterface)
void Mod::CacheEnabledModVersions(const shared_ptr<ScriptRuntime>& scriptRuntime)
{
ScriptInterface scriptInterface("Engine", "CacheEnabledModVersions", scriptRuntime);
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
JS::RootedValue availableMods(cx, GetAvailableMods(scriptInterface));
JS::RootedValue ret(cx, JS::ObjectValue(*JS_NewArrayObject(cx, 0)));
g_LoadedModVersions.clear();
// Index of the created array
size_t j = 0;
for (size_t i = 0; i < g_modsLoaded.size(); ++i)
for (const CStr& mod : g_modsLoaded)
{
// Ignore user and mod mod as they are irrelevant for compatibility checks
if (g_modsLoaded[i] == "mod" || g_modsLoaded[i] == "user")
if (mod == "mod" || mod == "user")
continue;
CStr version;
JS::RootedValue modData(cx);
if (scriptInterface.GetProperty(availableMods, g_modsLoaded[i].c_str(), &modData))
if (scriptInterface.GetProperty(availableMods, mod.c_str(), &modData))
scriptInterface.GetProperty(modData, "version", version);
scriptInterface.SetPropertyInt(ret, j++, std::vector<CStr>{g_modsLoaded[i], version});
g_LoadedModVersions.push_back({mod, version});
}
return ret;
}
JS::Value Mod::GetLoadedModsWithVersions(const ScriptInterface& scriptInterface)
{
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
JS::RootedValue returnValue(cx);
scriptInterface.ToJSVal(cx, &returnValue, g_LoadedModVersions);
return returnValue;
}
JS::Value Mod::GetEngineInfo(const ScriptInterface& scriptInterface)

View File

@ -22,6 +22,8 @@
#include "ps/GameSetup/CmdLineArgs.h"
#include "scriptinterface/ScriptInterface.h"
class ScriptRuntime;
extern std::vector<CStr> g_modsLoaded;
extern CmdLineArgs g_args;
@ -29,6 +31,14 @@ namespace Mod
{
JS::Value GetAvailableMods(const ScriptInterface& scriptInterface);
/**
* This reads the version numbers from the launched mods.
* It caches the result, since the reading of zip files is slow and
* JS pages can request the version numbers too often easily.
* Make sure this is called after each MountMods call.
*/
void CacheEnabledModVersions(const shared_ptr<ScriptRuntime>& scriptRuntime);
/**
* Get the loaded mods and their version.
* "user" mod and "mod" mod are ignored as they are irrelevant for compatibility checks.

View File

@ -35,6 +35,7 @@
#include "ps/Util.h"
#include "ps/VisualReplay.h"
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/ScriptRuntime.h"
#include "scriptinterface/ScriptStats.h"
#include "simulation2/Simulation2.h"
#include "simulation2/helpers/SimulationCommand.h"
@ -179,6 +180,8 @@ void CReplayPlayer::Replay(bool serializationtest, int rejointestturn, bool oosl
const int heapGrowthBytesGCTrigger = 20 * 1024 * 1024;
g_ScriptRuntime = ScriptInterface::CreateRuntime(shared_ptr<ScriptRuntime>(), runtimeSize, heapGrowthBytesGCTrigger);
Mod::CacheEnabledModVersions(g_ScriptRuntime);
g_Game = new CGame(true, false);
if (serializationtest)
g_Game->GetSimulation2()->EnableSerializationTest();