common_engine_methods_and_macros.rst 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. .. _doc_common_engine_methods_and_macros:
  2. Common engine methods and macros
  3. ================================
  4. Godot's C++ codebase makes use of dozens of custom methods and macros which are
  5. used in almost every file. This page is geared towards beginner contributors,
  6. but it can also be useful for those writing custom C++ modules.
  7. Print text
  8. ----------
  9. .. code-block:: cpp
  10. // Prints a message to standard output.
  11. print_line("Message");
  12. // Prints a message to standard output, but only when the engine
  13. // is started with the `--verbose` command line argument.
  14. print_verbose("Message");
  15. // Prints a formatted error or warning message with a trace.
  16. ERR_PRINT("Message");
  17. WARN_PRINT("Message");
  18. // Prints an error or warning message only once per session.
  19. // This can be used to avoid spamming the console output.
  20. ERR_PRINT_ONCE("Message");
  21. WARN_PRINT_ONCE("Message");
  22. If you need to add placeholders in your messages, use format strings as
  23. described below.
  24. Format a string
  25. ---------------
  26. The ``vformat()`` function returns a formatted :ref:`class_String`. It behaves
  27. in a way similar to C's ``sprintf()``:
  28. .. code-block:: cpp
  29. vformat("My name is %s.", "Godette");
  30. vformat("%d bugs on the wall!", 1234);
  31. vformat("Pi is approximately %f.", 3.1416);
  32. // Converts the resulting String into a `const char *`.
  33. // You may need to do this if passing the result as an argument
  34. // to a method that expects a `const char *` instead of a String.
  35. vformat("My name is %s.", "Godette").c_str();
  36. In most cases, try to use ``vformat()`` instead of string concatenation as it
  37. makes for more readable code.
  38. Convert an integer or float to a string
  39. ---------------------------------------
  40. This is mainly useful when printing numbers directly.
  41. .. code-block:: cpp
  42. // Prints "42" using integer-to-string conversion.
  43. print_line(itos(42));
  44. // Prints "123.45" using real-to-string conversion.
  45. print_line(rtos(123.45));
  46. Internationalize a string
  47. -------------------------
  48. There are two types of internationalization in Godot's codebase:
  49. - ``TTR()``: **Editor ("tools") translations** will only be processed in the
  50. editor. If a user uses the same text in one of their projects, it won't be
  51. translated if they provide a translation for it. When contributing to the
  52. engine, this is generally the macro you should use for localizable strings.
  53. - ``RTR()``: **Run-time translations** will be automatically localized in
  54. projects if they provide a translation for the given string. This kind of
  55. translation shouldn't be used in editor-only code.
  56. .. code-block:: cpp
  57. // Returns the translated string that matches the user's locale settings.
  58. // Translations are located in `editor/translations`.
  59. // The localization template is generated automatically; don't modify it.
  60. TTR("Exit the editor?");
  61. To insert placeholders in localizable strings, wrap the localization macro in a
  62. ``vformat()`` call as follows:
  63. .. code-block:: cpp
  64. String file_path = "example.txt";
  65. vformat(TTR("Couldn't open \"%s\" for reading."), file_path);
  66. .. note::
  67. When using ``vformat()`` and a translation macro together, always wrap the
  68. translation macro in ``vformat()``, not the other way around. Otherwise, the
  69. string will never match the translation as it will have the placeholder
  70. already replaced when it's passed to TranslationServer.
  71. Clamp a value
  72. -------------
  73. Godot provides macros for clamping a value with a lower bound (``MAX``), an
  74. upper bound (``MIN``) or both (``CLAMP``):
  75. .. code-block:: cpp
  76. int a = 3;
  77. int b = 5;
  78. MAX(b, 6); // 6
  79. MIN(2, a); // 2
  80. CLAMP(a, 10, 30); // 10
  81. This works with any type that can be compared to other values (like ``int`` and
  82. ``float``).
  83. Microbenchmarking
  84. -----------------
  85. If you want to benchmark a piece of code but don't know how to use a profiler,
  86. use this snippet:
  87. .. code-block:: cpp
  88. uint64_t begin = OS::get_singleton()->get_ticks_usec();
  89. // Your code here...
  90. uint64_t end = OS::get_singleton()->get_ticks_usec();
  91. print_line(vformat("Snippet took %d microseconds", end - begin));
  92. This will print the time spent between the ``begin`` declaration and the ``end``
  93. declaration.
  94. .. note::
  95. You may have to ``#include "core/os/os.h"`` if it's not present already.
  96. When opening a pull request, make sure to remove this snippet as well as the
  97. include if it wasn't there previously.
  98. Get project/editor settings
  99. ---------------------------
  100. There are four macros available for this:
  101. .. code-block:: cpp
  102. // Returns the specified project setting's value,
  103. // defaulting to `false` if it doesn't exist.
  104. GLOBAL_DEF("section/subsection/value", false);
  105. // Returns the specified editor setting's value,
  106. // defaulting to "Untitled" if it doesn't exist.
  107. EDITOR_DEF("section/subsection/value", "Untitled");
  108. If a default value has been specified elsewhere, don't specify it again to avoid
  109. repetition:
  110. .. code-block:: cpp
  111. // Returns the value of the project setting.
  112. GLOBAL_GET("section/subsection/value");
  113. // Returns the value of the editor setting.
  114. EDITOR_GET("section/subsection/value");
  115. It's recommended to use ``GLOBAL_DEF``/``EDITOR_DEF`` only once per setting and
  116. use ``GLOBAL_GET``/``EDITOR_GET`` in all other places where it's referenced.
  117. Error macros
  118. ------------
  119. Godot features many error macros to make error reporting more convenient.
  120. .. warning::
  121. Conditions in error macros work in the **opposite** way of GDScript's
  122. built-in ``assert()`` function. An error is reached if the condition inside
  123. evaluates to ``true``, not ``false``.
  124. .. note::
  125. Only variants with custom messages are documented here, as these should
  126. always be used in new contributions. Make sure the custom message provided
  127. includes enough information for people to diagnose the issue, even if they
  128. don't know C++. In case a method was passed invalid arguments, you can print
  129. the invalid value in question to ease debugging.
  130. For internal error checking where displaying a human-readable message isn't
  131. necessary, remove ``_MSG`` at the end of the macro name and don't supply a
  132. message argument.
  133. Also, always try to return processable data so the engine can keep running
  134. well.
  135. .. code-block:: cpp
  136. // Conditionally prints an error message and returns from the function.
  137. // Use this in methods which don't return a value.
  138. ERR_FAIL_COND_MSG(!mesh.is_valid(), vformat("Couldn't load mesh at: %s", path));
  139. // Conditionally prints an error message and returns `0` from the function.
  140. // Use this in methods which must return a value.
  141. ERR_FAIL_COND_V_MSG(rect.x < 0 || rect.y < 0, 0,
  142. "Couldn't calculate the rectangle's area.");
  143. // Prints an error message if `index` is < 0 or >= `SomeEnum::QUALITY_MAX`,
  144. // then returns from the function.
  145. ERR_FAIL_INDEX_MSG(index, SomeEnum::QUALITY_MAX,
  146. vformat("Invalid quality: %d. See SomeEnum for allowed values.", index));
  147. // Prints an error message if `index` is < 0 >= `some_array.size()`,
  148. // then returns `-1` from the function.
  149. ERR_FAIL_INDEX_V_MSG(index, some_array.size(), -1,
  150. vformat("Item %d is out of bounds.", index));
  151. // Unconditionally prints an error message and returns from the function.
  152. // Only use this if you need to perform complex error checking.
  153. if (!complex_error_checking_routine()) {
  154. ERR_FAIL_MSG("Couldn't reload the filesystem cache.");
  155. }
  156. // Unconditionally prints an error message and returns `false` from the function.
  157. // Only use this if you need to perform complex error checking.
  158. if (!complex_error_checking_routine()) {
  159. ERR_FAIL_V_MSG(false, "Couldn't parse the input arguments.");
  160. }
  161. // Crashes the engine. This should generally never be used
  162. // except for testing crash handling code. Godot's philosophy
  163. // is to never crash, both in the editor and in exported projects.
  164. CRASH_NOW_MSG("Can't predict the future! Aborting.");
  165. .. seealso::
  166. See `core/error_macros.h <https://github.com/godotengine/godot/blob/3.x/core/error_macros.h>`__
  167. in Godot's codebase for more information about each error macro.
  168. Some functions return an error code (materialized by a return type of
  169. ``Error``). This value can be returned directly from an error macro.
  170. See the list of available error codes in
  171. `core/error_list.h <https://github.com/godotengine/godot/blob/3.x/core/error_list.h>`__.