1 /* Copyright (C) 2021 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_MAPGENERATOR
19 #define INCLUDED_MAPGENERATOR
21 #include "ps/FileIo.h"
22 #include "ps/Future.h"
23 #include "ps/TemplateLoader.h"
24 #include "scriptinterface/StructuredClone.h"
26 #include <boost/random/linear_congruential.hpp>
31 class CMapGeneratorWorker
;
34 * Random map generator interface. Initialized by CMapReader and then checked
35 * periodically during loading, until it's finished (progress value is 0).
37 * The actual work is performed by CMapGeneratorWorker in a separate thread.
41 NONCOPYABLE(CMapGenerator
);
48 * Start the map generator thread
50 * @param scriptFile The VFS path for the script, e.g. "maps/random/latium.js"
51 * @param settings JSON string containing settings for the map generator
53 void GenerateMap(const VfsPath
& scriptFile
, const std::string
& settings
);
56 * Get status of the map generator thread
58 * @return Progress percentage 1-100 if active, 0 when finished, or -1 on error
63 * Get random map data, according to this format:
64 * http://trac.wildfiregames.com/wiki/Random_Map_Generator_Internals#Dataformat
66 * @return StructuredClone containing map data
68 Script::StructuredClone
GetResults();
71 CMapGeneratorWorker
* m_Worker
;
76 * Random map generator worker thread.
77 * (This is run in a thread so that the GUI remains responsive while loading)
80 * - Initialize and constructor/destructor must be called from the main thread.
81 * - ScriptInterface created and destroyed by thread
82 * - StructuredClone used to return JS map data - JS:Values can't be used across threads/contexts.
84 class CMapGeneratorWorker
87 CMapGeneratorWorker(ScriptInterface
* scriptInterface
);
88 ~CMapGeneratorWorker();
91 * Start the map generator thread
93 * @param scriptFile The VFS path for the script, e.g. "maps/random/latium.js"
94 * @param settings JSON string containing settings for the map generator
96 void Initialize(const VfsPath
& scriptFile
, const std::string
& settings
);
99 * Get status of the map generator thread
101 * @return Progress percentage 1-100 if active, 0 when finished, or -1 on error
106 * Get random map data, according to this format:
107 * http://trac.wildfiregames.com/wiki/Random_Map_Generator_Internals#Dataformat
109 * @return StructuredClone containing map data
111 Script::StructuredClone
GetResults();
114 * Set initial seed, callback data.
115 * Expose functions, globals and classes defined in this class relevant to the map and test scripts.
117 void InitScriptInterface(const u32 seed
);
122 * Expose functions defined in this class that are relevant to mapscripts but not the tests.
124 void RegisterScriptFunctions_MapGenerator();
127 * Load all scripts of the given library
129 * @param libraryName VfsPath specifying name of the library (subfolder of ../maps/random/)
130 * @return true if all scripts ran successfully, false if there's an error
132 bool LoadScripts(const VfsPath
& libraryName
);
135 * Finalize map generation and pass results from the script to the engine.
137 void ExportMap(JS::HandleValue data
);
140 * Load an image file and return it as a height array.
142 JS::Value
LoadHeightmap(const VfsPath
& src
);
145 * Load an Atlas terrain file (PMP) returning textures and heightmap.
147 JS::Value
LoadMapTerrain(const VfsPath
& filename
);
150 * Sets the map generation progress, which is one of multiple stages determining the loading screen progress.
152 void SetProgress(int progress
);
155 * Microseconds since the epoch.
157 double GetMicroseconds();
160 * Return the template data of the given template name.
162 CParamNode
GetTemplate(const std::string
& templateName
);
165 * Check whether the given template exists.
167 bool TemplateExists(const std::string
& templateName
);
170 * Returns all template names of simulation entity templates.
172 std::vector
<std::string
> FindTemplates(const std::string
& path
, bool includeSubdirectories
);
175 * Returns all template names of actors.
177 std::vector
<std::string
> FindActorTemplates(const std::string
& path
, bool includeSubdirectories
);
180 * Perform the map generation.
185 * Currently loaded script librarynames.
187 std::set
<VfsPath
> m_LoadedLibraries
;
190 * Result of the mapscript generation including terrain, entities and environment settings.
192 Script::StructuredClone m_MapData
;
195 * Deterministic random number generator.
197 boost::rand48 m_MapGenRNG
;
200 * Current map generation progress.
205 * Provides the script context.
207 ScriptInterface
* m_ScriptInterface
;
210 * Map generation script to run.
212 VfsPath m_ScriptPath
;
215 * Map and simulation settings chosen in the gamesetup stage.
217 std::string m_Settings
;
220 * Backend to loading template data.
222 CTemplateLoader m_TemplateLoader
;
225 * Holds the completion result of the asynchronous map generation.
226 * TODO: this whole class could really be a future on its own.
228 Future
<void> m_WorkerThread
;
231 * Avoids thread synchronization issues.
233 std::mutex m_WorkerMutex
;
237 #endif //INCLUDED_MAPGENERATOR