Skip to content

Commit

Permalink
Add godot app lifecycle callbacks to modules.
Browse files Browse the repository at this point in the history
This feature add a mechanism that emits a notification when a specific app lifecycle phase
is executed.
It call the callback on:
- Setup begins (`Main::setup`) LIFECYCLE_PHASE_SETUP_BEGIN
- Setup2 begins (`Main::setup2`) LIFECYCLE_PHASE_SETUP2_BEGIN
- Setup2 done (`Main::setup2`) LIFECYCLE_PHASE_SETUP2_DONE
- Start begins (`Main::start`) LIFECYCLE_PHASE_START_BEGIN
- Start done (`Main::start`) LIFECYCLE_PHASE_START_DONE
- Cleanup begins (`Main::cleanup`) LIFECYCLE_PHASE_CLEANUP_BEGIN
- Cleanup done (`Main::cleanup`) LIFECYCLE_PHASE_CLEANUP_DONE

----

To use it, it's enough to implement the function
`void MODULENAME_lifecycle_callback(int);` to `yourmodule/register_types.h` and
define the macro: `#define MODULE_MODULENAME_HAS_LIFECYCLE_CALLBACK`

For example, if we need to register a new singleton in the GLTF module, we
can write the following:
```c++
// .h

void gltf_lifecycle_callback(int p_lifecycle_phase);

// .cpp

void gltf_lifecycle_callback(int p_lifecycle_phase) {
	switch (p_lifecycle_phase) {
		case LIFECYCLE_PHASE_STARTUP_BEGIN:
			// TODO Init here the singleton.
			break;
		case LIFECYCLE_PHASE_CLEANUP_BEGIN:
			// TODO Clear here the singleton.
			break;
	}
}
```

Implements the proposal: godotengine/godot-proposals#1593
The proposal code is different than this implementation because this
code is using the adviced implementation the core dev adviced.
  • Loading branch information
AndreaCatania committed Jul 5, 2021
1 parent 6bf26fb commit 9c15657
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 0 deletions.
7 changes: 7 additions & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) {
*/

Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
call_modules_lifecycle_callback(LIFECYCLE_PHASE_SETUP_BEGIN);
OS::get_singleton()->initialize();

engine = memnew(Engine);
Expand Down Expand Up @@ -1464,6 +1465,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}

Error Main::setup2(Thread::ID p_main_tid_override) {
call_modules_lifecycle_callback(LIFECYCLE_PHASE_POST_SETUP_BEGIN);
preregister_module_types();
preregister_server_types();

Expand Down Expand Up @@ -1843,6 +1845,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
print_verbose("EDITOR API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
MAIN_PRINT("Main: Done");

call_modules_lifecycle_callback(LIFECYCLE_PHASE_SETUP_DONE);
return OK;
}

Expand All @@ -1851,6 +1854,7 @@ static MainTimerSync main_timer_sync;

bool Main::start() {
ERR_FAIL_COND_V(!_start_success, false);
call_modules_lifecycle_callback(LIFECYCLE_PHASE_START_BEGIN);

bool hasicon = false;
String positional_arg;
Expand Down Expand Up @@ -2434,6 +2438,7 @@ bool Main::start() {

OS::get_singleton()->set_main_loop(main_loop);

call_modules_lifecycle_callback(LIFECYCLE_PHASE_START_DONE);
return true;
}

Expand Down Expand Up @@ -2632,6 +2637,7 @@ void Main::force_redraw() {
* The order matters as some of those steps are linked with each other.
*/
void Main::cleanup(bool p_force) {
call_modules_lifecycle_callback(LIFECYCLE_PHASE_CLEANUP_BEGIN);
if (!p_force) {
ERR_FAIL_COND(!_start_success);
}
Expand Down Expand Up @@ -2742,4 +2748,5 @@ void Main::cleanup(bool p_force) {
unregister_core_types();

OS::get_singleton()->finalize_core();
call_modules_lifecycle_callback(LIFECYCLE_PHASE_CLEANUP_DONE);
}
10 changes: 10 additions & 0 deletions main/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@
#include "core/os/thread.h"
#include "core/typedefs.h"

enum LifecyclePhase {
LIFECYCLE_PHASE_SETUP_BEGIN,
LIFECYCLE_PHASE_POST_SETUP_BEGIN,
LIFECYCLE_PHASE_SETUP_DONE,
LIFECYCLE_PHASE_START_BEGIN,
LIFECYCLE_PHASE_START_DONE,
LIFECYCLE_PHASE_CLEANUP_BEGIN,
LIFECYCLE_PHASE_CLEANUP_DONE
};

class Main {
static void print_help(const char *p_binary);
static uint64_t last_ticks;
Expand Down
11 changes: 11 additions & 0 deletions methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ def write_modules(modules):
preregister_cpp = ""
register_cpp = ""
unregister_cpp = ""
call_lifecycle_callback_cpp = ""

for name, path in modules.items():
try:
Expand All @@ -252,6 +253,11 @@ def write_modules(modules):
unregister_cpp += "#ifdef MODULE_" + name.upper() + "_ENABLED\n"
unregister_cpp += "\tunregister_" + name + "_types();\n"
unregister_cpp += "#endif\n"
call_lifecycle_callback_cpp += "#ifdef MODULE_" + name.upper() + "_ENABLED\n"
call_lifecycle_callback_cpp += "#ifdef MODULE_" + name.upper() + "_HAS_LIFECYCLE_CALLBACK\n"
call_lifecycle_callback_cpp += "\t" + name + "_lifecycle_callback(p_phase);\n"
call_lifecycle_callback_cpp += "#endif\n"
call_lifecycle_callback_cpp += "#endif\n"
except OSError:
pass

Expand All @@ -274,11 +280,16 @@ def write_modules(modules):
void unregister_module_types() {
%s
}
void call_modules_lifecycle_callback(int p_phase) {
%s
}
""" % (
includes_cpp,
preregister_cpp,
register_cpp,
unregister_cpp,
call_lifecycle_callback_cpp,
)

# NOTE: It is safe to generate this file here, since this is still executed serially
Expand Down
1 change: 1 addition & 0 deletions modules/register_module_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@
void preregister_module_types();
void register_module_types();
void unregister_module_types();
void call_modules_lifecycle_callback(int p_phase);

#endif // REGISTER_MODULE_TYPES_H

0 comments on commit 9c15657

Please sign in to comment.