godot_ffi/init_level.rs
1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8/// Stage of the Godot initialization process.
9///
10/// Godot's initialization and deinitialization processes are split into multiple stages, like a stack. At each level,
11/// a different amount of engine functionality is available. Deinitialization happens in reverse order.
12///
13/// See also:
14// Explicit HTML links because this is re-exported in godot::init, and we can't document a `use` statement.
15/// - [`InitStage`](enum.InitStage.html): all levels + main loop.
16/// - [`ExtensionLibrary::on_stage_init()`](trait.ExtensionLibrary.html#method.on_stage_init)
17/// - [`ExtensionLibrary::on_stage_deinit()`](trait.ExtensionLibrary.html#method.on_stage_deinit)
18#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
19pub enum InitLevel {
20    /// First level loaded by Godot. Builtin types are available, classes are not.
21    Core,
22
23    /// Second level loaded by Godot. Only server classes and builtins are available.
24    Servers,
25
26    /// Third level loaded by Godot. Most classes are available.
27    Scene,
28
29    /// Fourth level loaded by Godot, only in the editor. All classes are available.
30    Editor,
31}
32
33impl InitLevel {
34    #[doc(hidden)]
35    pub fn from_sys(level: crate::GDExtensionInitializationLevel) -> Self {
36        match level {
37            crate::GDEXTENSION_INITIALIZATION_CORE => Self::Core,
38            crate::GDEXTENSION_INITIALIZATION_SERVERS => Self::Servers,
39            crate::GDEXTENSION_INITIALIZATION_SCENE => Self::Scene,
40            crate::GDEXTENSION_INITIALIZATION_EDITOR => Self::Editor,
41            _ => {
42                eprintln!("WARNING: unknown initialization level {level}");
43                Self::Scene
44            }
45        }
46    }
47
48    #[doc(hidden)]
49    pub fn to_sys(self) -> crate::GDExtensionInitializationLevel {
50        match self {
51            Self::Core => crate::GDEXTENSION_INITIALIZATION_CORE,
52            Self::Servers => crate::GDEXTENSION_INITIALIZATION_SERVERS,
53            Self::Scene => crate::GDEXTENSION_INITIALIZATION_SCENE,
54            Self::Editor => crate::GDEXTENSION_INITIALIZATION_EDITOR,
55        }
56    }
57
58    /// Convert this initialization level to an initialization stage.
59    pub fn to_stage(self) -> InitStage {
60        match self {
61            Self::Core => InitStage::Core,
62            Self::Servers => InitStage::Servers,
63            Self::Scene => InitStage::Scene,
64            Self::Editor => InitStage::Editor,
65        }
66    }
67}
68
69// ----------------------------------------------------------------------------------------------------------------------------------------------
70
71/// Extended initialization stage that includes both initialization levels and the main loop.
72///
73/// This enum extends [`InitLevel`] with a `MainLoop` variant, representing the fully initialized state of Godot
74/// after all initialization levels have been loaded and before any deinitialization begins.
75///
76/// During initialization, stages are loaded in order: `Core` → `Servers` → `Scene` → `Editor` (if in editor) → `MainLoop`.  \
77/// During deinitialization, stages are unloaded in reverse order.
78///
79/// See also:
80/// - [`InitLevel`](enum.InitLevel.html): only levels, without `MainLoop`.
81/// - [`ExtensionLibrary::on_stage_init()`](trait.ExtensionLibrary.html#method.on_stage_init)
82/// - [`ExtensionLibrary::on_stage_deinit()`](trait.ExtensionLibrary.html#method.on_stage_deinit)
83/// - [`ExtensionLibrary::on_main_loop_frame()`](trait.ExtensionLibrary.html#method.on_main_loop_frame)
84#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
85#[non_exhaustive]
86pub enum InitStage {
87    /// First level loaded by Godot. Builtin types are available, classes are not.
88    Core,
89
90    /// Second level loaded by Godot. Only server classes and builtins are available.
91    Servers,
92
93    /// Third level loaded by Godot. Most classes are available.
94    Scene,
95
96    /// Fourth level loaded by Godot, only in the editor. All classes are available.
97    Editor,
98
99    /// The main loop stage, representing the fully initialized state of Godot.
100    ///
101    /// This variant is only available in Godot 4.5+. In earlier versions, it will never be passed to callbacks.
102    #[cfg(since_api = "4.5")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.5")))]
103    MainLoop,
104}
105
106impl InitStage {
107    /// Try to convert this initialization stage to an initialization level.
108    ///
109    /// Returns `None` for [`InitStage::MainLoop`], as it doesn't correspond to a Godot initialization level.
110    pub fn try_to_level(self) -> Option<InitLevel> {
111        match self {
112            Self::Core => Some(InitLevel::Core),
113            Self::Servers => Some(InitLevel::Servers),
114            Self::Scene => Some(InitLevel::Scene),
115            Self::Editor => Some(InitLevel::Editor),
116            #[cfg(since_api = "4.5")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.5")))]
117            Self::MainLoop => None,
118        }
119    }
120}