ScriptManager.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #pragma once
  16. #include <OgreSingleton.h>
  17. #include <OgreString.h>
  18. #include "Event.h"
  19. #include "LuaIncludes.h"
  20. #include "Manager.h"
  21. class Entity;
  22. /**
  23. * Script identifier.
  24. */
  25. struct ScriptId{
  26. /**
  27. * Constructor.
  28. */
  29. ScriptId(): entity(""), function(""){}
  30. /**
  31. * Entity name.
  32. */
  33. Ogre::String entity;
  34. /**
  35. * Function (script) name.
  36. */
  37. Ogre::String function;
  38. };
  39. /**
  40. * A script entity.
  41. */
  42. struct ScriptEntity;
  43. /**
  44. * A script queue.
  45. */
  46. struct QueueScript{
  47. /**
  48. * Constructor.
  49. */
  50. QueueScript():
  51. function(""),
  52. argument1(""),
  53. argument2(""),
  54. argument3(""),
  55. priority(0),
  56. state(NULL),
  57. seconds_to_wait(0),
  58. wait(false),
  59. yield(false)
  60. {}
  61. /**
  62. * Function name.
  63. */
  64. Ogre::String function;
  65. /**
  66. * First function argument.
  67. */
  68. Ogre::String argument1;
  69. /**
  70. * Second function argument.
  71. */
  72. Ogre::String argument2;
  73. /**
  74. * Third function argument.
  75. */
  76. Ogre::String argument3;
  77. /**
  78. * Function priority.
  79. */
  80. int priority;
  81. /**
  82. * Current state.
  83. */
  84. lua_State* state;
  85. /**
  86. * State thread identifier.
  87. *
  88. * Used to store and delete thread.
  89. */
  90. int state_id;
  91. /**
  92. * Seconds to wait for completion.
  93. */
  94. float seconds_to_wait;
  95. /**
  96. * Indicates if the script completion should be waited for,
  97. */
  98. bool wait;
  99. /**
  100. * @todo Understand and document.
  101. */
  102. bool yield;
  103. /**
  104. * The scripts that wait for this one to start.
  105. *
  106. * More than one script can wait: a request for a script that is already queued adds a
  107. * waiter to the queued one.
  108. */
  109. std::vector<ScriptId> paused_scripts_start;
  110. /**
  111. * The scripts that wait for this one to end.
  112. *
  113. * More than one script can wait: a request for a script that is already queued or running
  114. * adds a waiter to the existing one.
  115. */
  116. std::vector<ScriptId> paused_scripts_end;
  117. };
  118. class ScriptManager : public Manager, public Ogre::Singleton<ScriptManager>{
  119. public:
  120. /**
  121. * Script types.
  122. */
  123. enum Type{
  124. /**
  125. * System script.
  126. *
  127. * The script is triggered by a system event.
  128. */
  129. SYSTEM,
  130. /**
  131. * A field or world map entity script.
  132. *
  133. * The script belongs to any of the entities on a map.
  134. */
  135. ENTITY,
  136. /**
  137. * A UI element script.
  138. *
  139. * The script is triggered by a UI element (menu, cursor...)
  140. */
  141. UI,
  142. /**
  143. * A battle entity script.
  144. *
  145. * The script belongs to any of the entities on the battle.
  146. */
  147. BATTLE
  148. };
  149. /**
  150. * Constructor.
  151. */
  152. ScriptManager();
  153. /**
  154. * Destructor.
  155. */
  156. virtual ~ScriptManager();
  157. /**
  158. * Handles an input event.
  159. *
  160. * @param[in] event The event to handle.
  161. */
  162. void Input(const VGears::Event& event) override;
  163. /**
  164. * Updates the state of all scripts of a given type.
  165. *
  166. * @param[in] type Type of the scripts to update.
  167. */
  168. void Update(const Type type);
  169. /**
  170. * Updates the script in the manager with debug information.
  171. */
  172. void UpdateDebug() override;
  173. /**
  174. * Handles resizing events
  175. */
  176. void OnResize() override;
  177. /**
  178. * Clears all field information in the script manager.
  179. */
  180. void ClearField() override;
  181. /**
  182. * Clears all battle information in the script manager.
  183. */
  184. void ClearBattle() override;
  185. /**
  186. * Clears all world map information in the script manager.
  187. */
  188. void ClearWorld() override;
  189. /**
  190. * Runs a lua command string.
  191. *
  192. * No errors are handled, and nothing is returned
  193. *
  194. * @param[in] lua Lua string to run.
  195. */
  196. void RunString(const Ogre::String& lua);
  197. /**
  198. * Runs a lua file.
  199. *
  200. * No errors are handled, and nothing is returned
  201. *
  202. * @param[in] file Path to the lua file to run (relative to the data directory).
  203. */
  204. void RunFile(const Ogre::String& file);
  205. /**
  206. * Initializes Lua binds.
  207. *
  208. * It relates the command available in the field maps to C++ functions.
  209. */
  210. void InitBinds();
  211. /**
  212. * Initializes command bindings
  213. */
  214. void InitCmd();
  215. /**
  216. * Adds an entity to the manager.
  217. *
  218. * Usage depends on the currently active module. The entity will be added to the list of
  219. * entities of the module.
  220. *
  221. * @param[in] type Type of entity to add.
  222. * @param[in] entity_name The entity name.
  223. * @param[in] entity The entity to add.
  224. */
  225. void AddEntity(const Type type, const Ogre::String& entity_name, Entity* entity);
  226. /**
  227. * Deletes an entity from the manager.
  228. *
  229. * Usage depends on the currently active module. The entity will be removed from the list of
  230. * entities of the module. If there is no entity with name ENTITY_NAME and type TYPE,
  231. * nothing will be done.
  232. *
  233. * @param[in] type Type of the entity to remove.
  234. * @param[in] entity_name Name of the entity to remove.
  235. */
  236. void RemoveEntity(const Type type, const Ogre::String& entity_name);
  237. /**
  238. * Adds an script to an entity.
  239. *
  240. * Usage depends on the currently active module. The script will be added to the list of
  241. * scripts of the module.
  242. *
  243. * @param[in] entity_name Name of the entity to add a script to.
  244. * @param[in] function_name Name of the script to add.
  245. * @param[in] priority Script priority. Lower numbers have higher priority.
  246. */
  247. void AddEntityScript(
  248. const Ogre::String& entity_name, const Ogre::String& function_name, int priority
  249. );
  250. /**
  251. * Removes a script of an entity.
  252. *
  253. * @param[in] entity Entity whose script to remove.
  254. * @param[in] index Position of the script in the queue of the entity.
  255. */
  256. void RemoveEntityScript(ScriptEntity& entity, const size_t index);
  257. /**
  258. * Removes the top script of an entity.
  259. *
  260. * The entity must be in one of the currently active modules for it's script to be removed.
  261. *
  262. * @param[in] entity Entity whose first script to remove.
  263. */
  264. void RemoveEntityTopScript(ScriptEntity& entity);
  265. /**
  266. * Retrieves a table.
  267. *
  268. * The retrieved table depends on the currently active module.
  269. *
  270. * @param[in] type Type of script.
  271. * @param[in] name Script name.
  272. * @param[in] state Initial script state.
  273. * @return The table, or a nil reference if it doesn't exist.
  274. * @todo Understand and document.
  275. */
  276. sol::object GetTableByEntityName(
  277. const ScriptManager::Type type, const Ogre::String& name, lua_State* state
  278. ) const;
  279. /**
  280. * Retrieves a script from it's ID.
  281. *
  282. * @param[in] script Script ID.
  283. * @return The script with the corresponding ID, or nullptr if there is none.
  284. */
  285. QueueScript* GetScriptByScriptId(const ScriptId& script) const;
  286. /**
  287. * Retrieves a script entity by it's name and type.
  288. *
  289. * Usage depends on the currently active module. The entity will be searched among the
  290. * entities of the currently active module.
  291. *
  292. * @param[in] type Entity type.
  293. * @param[in] entity_name The entity name.
  294. * @return The entity by that type and name, or nullptr if there is no one that matches.
  295. */
  296. ScriptEntity* GetScriptEntityByName(const Type type, const Ogre::String& entity_name) const;
  297. /**
  298. * Retrieves the current script ID.
  299. *
  300. * @return The currently executing script ID.
  301. */
  302. const ScriptId GetCurrentScriptId() const;
  303. /**
  304. * continues the execution of a script.
  305. *
  306. * @param[in] script The ID of the script to resume.
  307. */
  308. void ContinueScriptExecution(const ScriptId& script);
  309. /**
  310. * Makes an script wait.
  311. *
  312. * @param[in] seconds Number of seconds to wait.
  313. * @todo Does it refer to the current script?
  314. */
  315. int ScriptWait(const float seconds);
  316. /**
  317. * Request an script execution.
  318. *
  319. * The script will execute only if it's not already being executed.
  320. *
  321. * @param[in] type Script type.
  322. * @param[in] entity Entity the scripts belong to.
  323. * @param[in] function Name of the function of the selected entity to execute.
  324. * @param[in] priority Execution priority.
  325. */
  326. void ScriptRequest(
  327. const Type type, const char* entity, const char* function, const int priority
  328. );
  329. /**
  330. * Request a synchronous script execution to start.
  331. *
  332. * @param[in] type Script type.
  333. * @param[in] entity Entity the scripts belong to.
  334. * @param[in] function Name of the function of the selected entity to execute.
  335. * @param[in] priority Execution priority.
  336. * @return -1 on success, 1 if the entity or the script don't exist.
  337. */
  338. int ScriptRequestStartSync(
  339. const Type type, const char* entity, const char* function, const int priority
  340. );
  341. /**
  342. * Request a synchronous script execution to end.
  343. *
  344. * @param[in] type Script type.
  345. * @param[in] entity Entity the scripts belong to.
  346. * @param[in] function Name of the function of the selected entity to execute.
  347. * @param[in] priority Execution priority.
  348. * @return -1 if the execution stops or if the script was not running,
  349. * 1 if the entity or the script don't exist.
  350. */
  351. int ScriptRequestEndSync(
  352. const Type type, const char* entity, const char* function, const int priority
  353. );
  354. /**
  355. * Request a script execution.
  356. *
  357. * @param[in] script_entity Entity the scripts belong to.
  358. * @param[in] function Name of the function of the selected entity to execute.
  359. * @param[in] priority Execution priority.
  360. * @param[in] argument1 First argument for the script.
  361. * @param[in] argument2 Second argument for the script.
  362. * @param[in] start_sync If true, the script will be started synchronously.
  363. * @param[in] end_sync @todo Understand and document.
  364. * @param[in] argument3 Third argument for the script.
  365. * @param[in] allow_duplicate If true, queue this call even if the same function is queued.
  366. * @return True on success, false on error (i.e. if the entity or the script don't exist)
  367. */
  368. bool ScriptRequest(
  369. ScriptEntity* script_entity, const Ogre::String& function,
  370. const int priority, const Ogre::String& argument1,
  371. const Ogre::String& argument2, bool start_sync, bool end_sync,
  372. const Ogre::String& argument3 = "", bool allow_duplicate = false
  373. );
  374. /**
  375. * Adds a script to the stack.
  376. *
  377. * @param[in] value ID of the script to add.
  378. * @todo Verify this documentation.
  379. */
  380. void AddValueToStack(const float value);
  381. private:
  382. /**
  383. * Updates the script while in a field.
  384. */
  385. void UpdateField() override;
  386. /**
  387. * Updates the scripts during a battle.
  388. */
  389. void UpdateBattle() override;
  390. /**
  391. * Updates the scripts while on the world map.
  392. */
  393. void UpdateWorld() override;
  394. /**
  395. * Lua state.
  396. */
  397. lua_State* lua_state_;
  398. /**
  399. * The system script table name.
  400. */
  401. Ogre::String system_table_name_;
  402. /**
  403. * The entity script table name.
  404. */
  405. Ogre::String entity_table_name_;
  406. /**
  407. * The battle entity script table name.
  408. */
  409. Ogre::String battle_table_name_;
  410. /**
  411. * The UI script table name.
  412. */
  413. Ogre::String ui_table_name_;
  414. /**
  415. * The list of map entity scripts.
  416. */
  417. std::vector<ScriptEntity> script_entity_;
  418. /**
  419. * The current script ID.
  420. */
  421. ScriptId current_script_id_;
  422. };
  423. struct ScriptEntity{
  424. /**
  425. * Constructor.
  426. *
  427. *By default, the type is {@see ScriptManager::SYSTEM}.
  428. */
  429. ScriptEntity(): name(""), type(ScriptManager::SYSTEM), resort(false){}
  430. /**
  431. * The script name.
  432. */
  433. Ogre::String name;
  434. /**
  435. * The script type.
  436. */
  437. ScriptManager::Type type;
  438. /**
  439. * The script queue.
  440. */
  441. std::vector<QueueScript> queue;
  442. /**
  443. * @todo Understand and document.
  444. */
  445. bool resort;
  446. };