[Gameplay] Reduce loom cost
[0ad.git] / source / graphics / MapGenerator.h
blob8019546c4932d0cea7b8d50a6d8333e7c23daf49
1 /* Copyright (C) 2023 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 <atomic>
27 #include <boost/random/linear_congruential.hpp>
28 #include <mutex>
29 #include <set>
30 #include <string>
32 class CMapGeneratorWorker;
34 /**
35 * Random map generator interface. Initialized by CMapReader and then checked
36 * periodically during loading, until it's finished (progress value is 0).
38 * The actual work is performed by CMapGeneratorWorker in a separate thread.
40 class CMapGenerator
42 NONCOPYABLE(CMapGenerator);
44 public:
45 CMapGenerator();
46 ~CMapGenerator();
48 /**
49 * Start the map generator thread
51 * @param scriptFile The VFS path for the script, e.g. "maps/random/latium.js"
52 * @param settings JSON string containing settings for the map generator
54 void GenerateMap(const VfsPath& scriptFile, const std::string& settings);
56 /**
57 * Get status of the map generator thread
59 * @return Progress percentage 1-100 if active, 0 when finished, or -1 on error
61 int GetProgress() const;
63 /**
64 * Get random map data, according to this format:
65 * http://trac.wildfiregames.com/wiki/Random_Map_Generator_Internals#Dataformat
67 * @return StructuredClone containing map data
69 Script::StructuredClone GetResults();
71 private:
72 CMapGeneratorWorker* m_Worker;
76 /**
77 * Random map generator worker thread.
78 * (This is run in a thread so that the GUI remains responsive while loading)
80 * Thread-safety:
81 * - Initialize and constructor/destructor must be called from the main thread.
82 * - ScriptInterface created and destroyed by thread
83 * - StructuredClone used to return JS map data - JS:Values can't be used across threads/contexts.
85 class CMapGeneratorWorker
87 public:
88 CMapGeneratorWorker(ScriptInterface* scriptInterface);
89 ~CMapGeneratorWorker();
91 /**
92 * Start the map generator thread
94 * @param scriptFile The VFS path for the script, e.g. "maps/random/latium.js"
95 * @param settings JSON string containing settings for the map generator
97 void Initialize(const VfsPath& scriptFile, const std::string& settings);
99 /**
100 * Get status of the map generator thread
102 * @return Progress percentage 1-100 if active, 0 when finished, or -1 on error
104 int GetProgress() const;
107 * Get random map data, according to this format:
108 * http://trac.wildfiregames.com/wiki/Random_Map_Generator_Internals#Dataformat
110 * @return StructuredClone containing map data
112 Script::StructuredClone GetResults();
115 * Set initial seed, callback data.
116 * Expose functions, globals and classes defined in this class relevant to the map and test scripts.
118 void InitScriptInterface(const u32 seed);
120 private:
123 * Expose functions defined in this class that are relevant to mapscripts but not the tests.
125 void RegisterScriptFunctions_MapGenerator();
128 * Load all scripts of the given library
130 * @param libraryName VfsPath specifying name of the library (subfolder of ../maps/random/)
131 * @return true if all scripts ran successfully, false if there's an error
133 bool LoadScripts(const VfsPath& libraryName);
136 * Finalize map generation and pass results from the script to the engine.
138 void ExportMap(JS::HandleValue data);
141 * Load an image file and return it as a height array.
143 JS::Value LoadHeightmap(const VfsPath& src);
146 * Load an Atlas terrain file (PMP) returning textures and heightmap.
148 JS::Value LoadMapTerrain(const VfsPath& filename);
151 * Sets the map generation progress, which is one of multiple stages determining the loading screen progress.
153 void SetProgress(int progress);
156 * Microseconds since the epoch.
158 double GetMicroseconds();
161 * Return the template data of the given template name.
163 CParamNode GetTemplate(const std::string& templateName);
166 * Check whether the given template exists.
168 bool TemplateExists(const std::string& templateName);
171 * Returns all template names of simulation entity templates.
173 std::vector<std::string> FindTemplates(const std::string& path, bool includeSubdirectories);
176 * Returns all template names of actors.
178 std::vector<std::string> FindActorTemplates(const std::string& path, bool includeSubdirectories);
181 * Perform the map generation.
183 bool Run();
186 * Currently loaded script librarynames.
188 std::set<VfsPath> m_LoadedLibraries;
191 * Result of the mapscript generation including terrain, entities and environment settings.
193 Script::StructuredClone m_MapData;
196 * Deterministic random number generator.
198 boost::rand48 m_MapGenRNG;
201 * Current map generation progress.
202 * Initialize to `-1`. If something happens before we start, that's a
203 * failure.
205 std::atomic<int> m_Progress{-1};
208 * Provides the script context.
210 ScriptInterface* m_ScriptInterface;
213 * Map generation script to run.
215 VfsPath m_ScriptPath;
218 * Map and simulation settings chosen in the gamesetup stage.
220 std::string m_Settings;
223 * Backend to loading template data.
225 CTemplateLoader m_TemplateLoader;
228 * Holds the completion result of the asynchronous map generation.
229 * TODO: this whole class could really be a future on its own.
231 Future<void> m_WorkerThread;
234 * Avoids thread synchronization issues.
236 std::mutex m_WorkerMutex;
240 #endif //INCLUDED_MAPGENERATOR