Support random map script tests, fixes #4827.
Differential Revision: https://code.wildfiregames.com/D2085 Comments By: wraitii This was SVN commit r23455.
This commit is contained in:
parent
67a4c18c74
commit
0a6db43c83
@ -1,14 +1,16 @@
|
||||
function RandomMapLogger()
|
||||
{
|
||||
this.lastTime = undefined;
|
||||
this.startTime = Engine.GetMicroseconds();
|
||||
this.startTime = Engine.GetMicroseconds ? Engine.GetMicroseconds() : 0;
|
||||
this.prefix = ""; // seems noisy
|
||||
|
||||
// Don't print in test cases
|
||||
if (g_MapSettings.Name)
|
||||
this.printDirectly(
|
||||
this.prefix +
|
||||
"Generating " + g_MapSettings.Name +
|
||||
" of size " + g_MapSettings.Size +
|
||||
" and " + getNumPlayers() + " players.\n");
|
||||
" and " + (g_MapSettings.PlayerData.length - 1) + " players.\n");
|
||||
}
|
||||
|
||||
RandomMapLogger.prototype.printDirectly = function(string)
|
||||
|
@ -0,0 +1,91 @@
|
||||
Engine.LoadLibrary("rmgen");
|
||||
|
||||
var g_MapSettings = { "Size": 512 };
|
||||
var g_Map = new RandomMap(0, "blackness");
|
||||
|
||||
// Test that that it checks by value, not by reference
|
||||
{
|
||||
let tileClass = new TileClass(2);
|
||||
let reference1 = new Vector2D(1, 1);
|
||||
let reference2 = new Vector2D(1, 1);
|
||||
tileClass.add(reference1);
|
||||
TS_ASSERT(tileClass.has(reference2));
|
||||
}
|
||||
|
||||
// Test out-of-bounds
|
||||
{
|
||||
let tileClass = new TileClass(32);
|
||||
let absentPoints = [
|
||||
new Vector2D(0, 0),
|
||||
new Vector2D(0, 1),
|
||||
new Vector2D(1, 0),
|
||||
new Vector2D(-1, -1),
|
||||
new Vector2D(2048, 0),
|
||||
new Vector2D(0, NaN),
|
||||
new Vector2D(0, Infinity)
|
||||
];
|
||||
|
||||
for (let point of absentPoints)
|
||||
TS_ASSERT(!tileClass.has(point));
|
||||
}
|
||||
|
||||
// Test multi-insertion
|
||||
{
|
||||
let tileClass = new TileClass(32);
|
||||
let point = new Vector2D(1, 1);
|
||||
|
||||
tileClass.add(point);
|
||||
tileClass.add(point);
|
||||
TS_ASSERT_EQUALS(tileClass.countMembersInRadius(point, 0), 1);
|
||||
|
||||
// Still one point remaining
|
||||
tileClass.remove(point);
|
||||
tileClass.remove(point);
|
||||
TS_ASSERT(!tileClass.has(point));
|
||||
}
|
||||
|
||||
// Test multi-insertion removal
|
||||
{
|
||||
let tileClass = new TileClass(32);
|
||||
let point = new Vector2D(2, 7);
|
||||
|
||||
tileClass.add(point);
|
||||
tileClass.add(point);
|
||||
tileClass.remove(point);
|
||||
TS_ASSERT(tileClass.has(point));
|
||||
|
||||
tileClass.remove(point);
|
||||
TS_ASSERT(!tileClass.has(point));
|
||||
}
|
||||
|
||||
// Test multi-insertion removal
|
||||
{
|
||||
let tileClass = new TileClass(55);
|
||||
let point = new Vector2D(5, 4);
|
||||
|
||||
for (let i = 0; i < 50; ++i)
|
||||
tileClass.add(point);
|
||||
|
||||
tileClass.remove(point);
|
||||
TS_ASSERT(tileClass.has(point));
|
||||
|
||||
tileClass.remove(point);
|
||||
TS_ASSERT(tileClass.has(point));
|
||||
}
|
||||
|
||||
// Test getters
|
||||
{
|
||||
let tileClass = new TileClass(88);
|
||||
let point = new Vector2D(5, 1);
|
||||
tileClass.add(point);
|
||||
|
||||
let point2 = new Vector2D(4, 9);
|
||||
tileClass.add(point2);
|
||||
|
||||
TS_ASSERT_EQUALS(tileClass.countMembersInRadius(point, 1), 1);
|
||||
TS_ASSERT_EQUALS(tileClass.countMembersInRadius(point, 100), 2);
|
||||
|
||||
TS_ASSERT_EQUALS(tileClass.countNonMembersInRadius(point, 1), 4);
|
||||
TS_ASSERT_EQUALS(tileClass.countNonMembersInRadius(point, 2), 12);
|
||||
TS_ASSERT_EQUALS(tileClass.countNonMembersInRadius(point, 3), 28);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -57,7 +57,8 @@ MapGeneratorInterruptCallback(JSContext* UNUSED(cx))
|
||||
return true;
|
||||
}
|
||||
|
||||
CMapGeneratorWorker::CMapGeneratorWorker()
|
||||
CMapGeneratorWorker::CMapGeneratorWorker(ScriptInterface* scriptInterface) :
|
||||
m_ScriptInterface(scriptInterface)
|
||||
{
|
||||
// If something happens before we initialize, that's a failure
|
||||
m_Progress = -1;
|
||||
@ -66,6 +67,7 @@ CMapGeneratorWorker::CMapGeneratorWorker()
|
||||
CMapGeneratorWorker::~CMapGeneratorWorker()
|
||||
{
|
||||
// Wait for thread to end
|
||||
if (m_WorkerThread.joinable())
|
||||
m_WorkerThread.join();
|
||||
}
|
||||
|
||||
@ -116,13 +118,6 @@ bool CMapGeneratorWorker::Run()
|
||||
JSContext* cx = m_ScriptInterface->GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
m_ScriptInterface->SetCallbackData(static_cast<void*> (this));
|
||||
|
||||
// Replace RNG with a seeded deterministic function
|
||||
m_ScriptInterface->ReplaceNondeterministicRNG(m_MapGenRNG);
|
||||
|
||||
RegisterScriptFunctions();
|
||||
|
||||
// Parse settings
|
||||
JS::RootedValue settingsVal(cx);
|
||||
if (!m_ScriptInterface->ParseJSON(m_Settings, &settingsVal) && settingsVal.isUndefined())
|
||||
@ -144,7 +139,9 @@ bool CMapGeneratorWorker::Run()
|
||||
!m_ScriptInterface->GetProperty(settingsVal, "Seed", seed))
|
||||
LOGWARNING("CMapGeneratorWorker::Run: No seed value specified - using 0");
|
||||
|
||||
m_MapGenRNG.seed(seed);
|
||||
InitScriptInterface(seed);
|
||||
|
||||
RegisterScriptFunctions_MapGenerator();
|
||||
|
||||
// Copy settings to global variable
|
||||
JS::RootedValue global(cx, m_ScriptInterface->GetGlobalObject());
|
||||
@ -165,8 +162,13 @@ bool CMapGeneratorWorker::Run()
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapGeneratorWorker::RegisterScriptFunctions()
|
||||
void CMapGeneratorWorker::InitScriptInterface(const u32 seed)
|
||||
{
|
||||
m_ScriptInterface->SetCallbackData(static_cast<void*>(this));
|
||||
|
||||
m_ScriptInterface->ReplaceNondeterministicRNG(m_MapGenRNG);
|
||||
m_MapGenRNG.seed(seed);
|
||||
|
||||
// VFS
|
||||
JSI_VFS::RegisterScriptFunctions_Maps(*m_ScriptInterface);
|
||||
|
||||
@ -178,17 +180,6 @@ void CMapGeneratorWorker::RegisterScriptFunctions()
|
||||
m_ScriptInterface->RegisterFunction<JS::Value, VfsPath, CMapGeneratorWorker::LoadHeightmap>("LoadHeightmapImage");
|
||||
m_ScriptInterface->RegisterFunction<JS::Value, VfsPath, CMapGeneratorWorker::LoadMapTerrain>("LoadMapTerrain");
|
||||
|
||||
// Progression and profiling
|
||||
m_ScriptInterface->RegisterFunction<void, int, CMapGeneratorWorker::SetProgress>("SetProgress");
|
||||
m_ScriptInterface->RegisterFunction<double, CMapGeneratorWorker::GetMicroseconds>("GetMicroseconds");
|
||||
m_ScriptInterface->RegisterFunction<void, JS::HandleValue, CMapGeneratorWorker::ExportMap>("ExportMap");
|
||||
|
||||
// Template functions
|
||||
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CMapGeneratorWorker::GetTemplate>("GetTemplate");
|
||||
m_ScriptInterface->RegisterFunction<bool, std::string, CMapGeneratorWorker::TemplateExists>("TemplateExists");
|
||||
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindTemplates>("FindTemplates");
|
||||
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates");
|
||||
|
||||
// Engine constants
|
||||
|
||||
// Length of one tile of the terrain grid in metres.
|
||||
@ -199,6 +190,20 @@ void CMapGeneratorWorker::RegisterScriptFunctions()
|
||||
m_ScriptInterface->SetGlobal("MAP_BORDER_WIDTH", static_cast<int>(MAP_EDGE_TILES));
|
||||
}
|
||||
|
||||
void CMapGeneratorWorker::RegisterScriptFunctions_MapGenerator()
|
||||
{
|
||||
// Template functions
|
||||
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CMapGeneratorWorker::GetTemplate>("GetTemplate");
|
||||
m_ScriptInterface->RegisterFunction<bool, std::string, CMapGeneratorWorker::TemplateExists>("TemplateExists");
|
||||
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindTemplates>("FindTemplates");
|
||||
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates");
|
||||
|
||||
// Progression and profiling
|
||||
m_ScriptInterface->RegisterFunction<void, int, CMapGeneratorWorker::SetProgress>("SetProgress");
|
||||
m_ScriptInterface->RegisterFunction<double, CMapGeneratorWorker::GetMicroseconds>("GetMicroseconds");
|
||||
m_ScriptInterface->RegisterFunction<void, JS::HandleValue, CMapGeneratorWorker::ExportMap>("ExportMap");
|
||||
}
|
||||
|
||||
int CMapGeneratorWorker::GetProgress()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_WorkerMutex);
|
||||
@ -410,7 +415,7 @@ JS::Value CMapGeneratorWorker::LoadMapTerrain(ScriptInterface::CxPrivate* pCxPri
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CMapGenerator::CMapGenerator() : m_Worker(new CMapGeneratorWorker())
|
||||
CMapGenerator::CMapGenerator() : m_Worker(new CMapGeneratorWorker(nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -86,7 +86,7 @@ private:
|
||||
class CMapGeneratorWorker
|
||||
{
|
||||
public:
|
||||
CMapGeneratorWorker();
|
||||
CMapGeneratorWorker(ScriptInterface* scriptInterface);
|
||||
~CMapGeneratorWorker();
|
||||
|
||||
/**
|
||||
@ -112,12 +112,18 @@ public:
|
||||
*/
|
||||
shared_ptr<ScriptInterface::StructuredClone> GetResults();
|
||||
|
||||
/**
|
||||
* Set initial seed, callback data.
|
||||
* Expose functions, globals and classes defined in this class relevant to the map and test scripts.
|
||||
*/
|
||||
void InitScriptInterface(const u32 seed);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Expose functions defined in this class to the script.
|
||||
* Expose functions defined in this class that are relevant to mapscripts but not the tests.
|
||||
*/
|
||||
void RegisterScriptFunctions();
|
||||
void RegisterScriptFunctions_MapGenerator();
|
||||
|
||||
/**
|
||||
* Load all scripts of the given library
|
||||
|
54
source/graphics/tests/test_MapGenerator.h
Normal file
54
source/graphics/tests/test_MapGenerator.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "graphics/MapGenerator.h"
|
||||
#include "ps/Filesystem.h"
|
||||
#include "simulation2/system/ComponentTest.h"
|
||||
|
||||
class TestMapGenerator : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void setUp()
|
||||
{
|
||||
g_VFS = CreateVfs();
|
||||
g_VFS->Mount(L"", DataDir() / "mods" / "mod", VFS_MOUNT_MUST_EXIST);
|
||||
g_VFS->Mount(L"", DataDir() / "mods" / "public", VFS_MOUNT_MUST_EXIST, 1); // ignore directory-not-found errors
|
||||
CXeromyces::Startup();
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
CXeromyces::Terminate();
|
||||
g_VFS.reset();
|
||||
}
|
||||
|
||||
void test_mapgen_scripts()
|
||||
{
|
||||
VfsPaths paths;
|
||||
TS_ASSERT_OK(vfs::GetPathnames(g_VFS, L"maps/random/tests/", L"test_*.js", paths));
|
||||
|
||||
for (const VfsPath& path : paths)
|
||||
{
|
||||
ScriptInterface scriptInterface("Engine", "MapGenerator", g_ScriptRuntime);
|
||||
ScriptTestSetup(scriptInterface);
|
||||
|
||||
CMapGeneratorWorker worker(&scriptInterface);
|
||||
worker.InitScriptInterface(0);
|
||||
scriptInterface.LoadGlobalScriptFile(path);
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user