Update: Translations from eints
[openttd-github.git] / src / script / script_instance.hpp
blob342cb822b6020f1a33f88acd8568f984444a6e74
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD 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, version 2.
4 * OpenTTD 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.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
8 /** @file script_instance.hpp The ScriptInstance tracks a script. */
10 #ifndef SCRIPT_INSTANCE_HPP
11 #define SCRIPT_INSTANCE_HPP
13 #include <variant>
14 #include <squirrel.h>
15 #include "script_suspend.hpp"
16 #include "script_log_types.hpp"
18 #include "../command_type.h"
19 #include "../company_type.h"
20 #include "../fileio_type.h"
22 static const uint SQUIRREL_MAX_DEPTH = 25; ///< The maximum recursive depth for items stored in the savegame.
24 /** Runtime information about a script like a pointer to the squirrel vm and the current state. */
25 class ScriptInstance {
26 private:
27 /** The type of the data that follows in the savegame. */
28 enum SQSaveLoadType {
29 SQSL_INT = 0x00, ///< The following data is an integer.
30 SQSL_STRING = 0x01, ///< The following data is an string.
31 SQSL_ARRAY = 0x02, ///< The following data is an array.
32 SQSL_TABLE = 0x03, ///< The following data is an table.
33 SQSL_BOOL = 0x04, ///< The following data is a boolean.
34 SQSL_NULL = 0x05, ///< A null variable.
35 SQSL_ARRAY_TABLE_END = 0xFF, ///< Marks the end of an array or table, no data follows.
38 public:
39 friend class ScriptObject;
40 friend class ScriptController;
42 typedef std::variant<SQInteger, std::string, SQBool, SQSaveLoadType> ScriptDataVariant;
43 typedef std::list<ScriptDataVariant> ScriptData;
45 /**
46 * Create a new script.
48 ScriptInstance(const char *APIName);
49 virtual ~ScriptInstance();
51 /**
52 * Initialize the script and prepare it for its first run.
53 * @param main_script The full path of the script to load.
54 * @param instance_name The name of the instance out of the script to load.
55 * @param company Which company this script is serving.
57 void Initialize(const std::string &main_script, const std::string &instance_name, CompanyID company);
59 /**
60 * Get the value of a setting of the current instance.
61 * @param name The name of the setting.
62 * @return the value for the setting, or -1 if the setting is not known.
64 virtual int GetSetting(const std::string &name) = 0;
66 /**
67 * Find a library.
68 * @param library The library name to find.
69 * @param version The version the library should have.
70 * @return The library if found, nullptr otherwise.
72 virtual class ScriptInfo *FindLibrary(const std::string &library, int version) = 0;
74 /**
75 * A script in multiplayer waits for the server to handle its DoCommand.
76 * It keeps waiting for this until this function is called.
78 void Continue();
80 /**
81 * Run the GameLoop of a script.
83 void GameLoop();
85 /**
86 * Let the VM collect any garbage.
88 void CollectGarbage();
90 /**
91 * Get the storage of this script.
93 class ScriptStorage *GetStorage();
95 /**
96 * Get the log pointer of this script.
98 ScriptLogTypes::LogData &GetLogData();
101 * Return a true/false reply for a DoCommand.
103 static void DoCommandReturn(ScriptInstance *instance);
106 * Return a VehicleID reply for a DoCommand.
108 static void DoCommandReturnVehicleID(ScriptInstance *instance);
111 * Return a SignID reply for a DoCommand.
113 static void DoCommandReturnSignID(ScriptInstance *instance);
116 * Return a GroupID reply for a DoCommand.
118 static void DoCommandReturnGroupID(ScriptInstance *instance);
121 * Return a GoalID reply for a DoCommand.
123 static void DoCommandReturnGoalID(ScriptInstance *instance);
126 * Return a StoryPageID reply for a DoCommand.
128 static void DoCommandReturnStoryPageID(ScriptInstance *instance);
131 * Return a StoryPageElementID reply for a DoCommand.
133 static void DoCommandReturnStoryPageElementID(ScriptInstance *instance);
136 * Return a LeagueTableID reply for a DoCommand.
138 static void DoCommandReturnLeagueTableID(ScriptInstance *instance);
141 * Return a LeagueTableElementID reply for a DoCommand.
143 static void DoCommandReturnLeagueTableElementID(ScriptInstance *instance);
146 * Get the controller attached to the instance.
148 class ScriptController *GetController() { return controller; }
151 * Return the "this script died" value
153 inline bool IsDead() const { return this->is_dead; }
156 * Return whether the script is alive.
158 inline bool IsAlive() const { return !this->IsDead() && !this->in_shutdown; }
161 * Call the script Save function and save all data in the savegame.
163 void Save();
166 * Don't save any data in the savegame.
168 static void SaveEmpty();
171 * Load data from a savegame.
172 * @param version The version of the script when saving, or -1 if this was
173 * not the original script saving the game.
174 * @return a pointer to loaded data.
176 static ScriptData *Load(int version);
179 * Store loaded data on the stack.
180 * @param data The loaded data to store on the stack.
182 void LoadOnStack(ScriptData *data);
185 * Load and discard data from a savegame.
187 static void LoadEmpty();
190 * Suspends the script for the current tick and then pause the execution
191 * of script. The script will not be resumed from its suspended state
192 * until the script has been unpaused.
194 void Pause();
197 * Checks if the script is paused.
198 * @return true if the script is paused, otherwise false
200 bool IsPaused();
203 * Resume execution of the script. This function will not actually execute
204 * the script, but set a flag so that the script is executed my the usual
205 * mechanism that executes the script.
207 void Unpause();
210 * Get the number of operations the script can execute before being suspended.
211 * This function is safe to call from within a function called by the script.
212 * @return The number of operations to execute.
214 SQInteger GetOpsTillSuspend();
217 * DoCommand callback function for all commands executed by scripts.
218 * @param result The result of the command.
219 * @param tile The tile on which the command was executed.
220 * @param data Command data as given to DoCommandPInternal.
221 * @param result_data Extra data return from the command.
222 * @param cmd cmd as given to DoCommandPInternal.
223 * @return true if we handled result.
225 bool DoCommandCallback(const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd);
228 * Insert an event for this script.
229 * @param event The event to insert.
231 void InsertEvent(class ScriptEvent *event);
234 * Check if the instance is sleeping, which either happened because the
235 * script executed a DoCommand, executed this.Sleep() or it has been
236 * paused.
238 bool IsSleeping() { return this->suspend != 0; }
240 size_t GetAllocatedMemory() const;
243 * Indicate whether this instance is currently being destroyed.
245 inline bool InShutdown() const { return this->in_shutdown; }
248 * Decrease the ref count of a squirrel object.
249 * @param obj The object to release.
251 void ReleaseSQObject(HSQOBJECT *obj);
253 protected:
254 class Squirrel *engine; ///< A wrapper around the squirrel vm.
255 std::string versionAPI; ///< Current API used by this script.
258 * Register all API functions to the VM.
260 virtual void RegisterAPI();
263 * Load squirrel scripts to emulate an older API.
264 * @param api_version: API version to load scripts for
265 * @param dir Subdirectory to find the scripts in
266 * @return true iff script loading should proceed
268 bool LoadCompatibilityScripts(const std::string &api_version, Subdirectory dir);
271 * Tell the script it died.
273 virtual void Died();
276 * Get the callback handling DoCommands in case of networking.
278 virtual CommandCallbackData *GetDoCommandCallback() = 0;
281 * Load the dummy script.
283 virtual void LoadDummyScript() = 0;
285 private:
286 class ScriptController *controller; ///< The script main class.
287 class ScriptStorage *storage; ///< Some global information for each running script.
288 SQObject *instance; ///< Squirrel-pointer to the script main class.
290 bool is_started; ///< Is the scripts constructor executed?
291 bool is_dead; ///< True if the script has been stopped.
292 bool is_save_data_on_stack; ///< Is the save data still on the squirrel stack?
293 int suspend; ///< The amount of ticks to suspend this script before it's allowed to continue.
294 bool is_paused; ///< Is the script paused? (a paused script will not be executed until unpaused)
295 bool in_shutdown; ///< Is this instance currently being destructed?
296 Script_SuspendCallbackProc *callback; ///< Callback that should be called in the next tick the script runs.
297 size_t last_allocated_memory; ///< Last known allocated memory value (for display for crashed scripts)
300 * Call the script Load function if it exists and data was loaded
301 * from a savegame.
303 bool CallLoad();
306 * Save one object (int / string / array / table) to the savegame.
307 * @param vm The virtual machine to get all the data from.
308 * @param index The index on the squirrel stack of the element to save.
309 * @param max_depth The maximum depth recursive arrays / tables will be stored
310 * with before an error is returned.
311 * @param test If true, don't really store the data but only check if it is
312 * valid.
313 * @return True if the saving was successful.
315 static bool SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test);
318 * Load all objects from a savegame.
319 * @return True if the loading was successful.
321 static bool LoadObjects(ScriptData *data);
323 static bool LoadObjects(HSQUIRRELVM vm, ScriptData *data);
326 #endif /* SCRIPT_INSTANCE_HPP */