Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept global classes for MainLoop type in project settings #41190

Merged
merged 1 commit into from
Sep 2, 2020
Merged

Accept global classes for MainLoop type in project settings #41190

merged 1 commit into from
Sep 2, 2020

Conversation

Xrayez
Copy link
Contributor

@Xrayez Xrayez commented Aug 11, 2020

Fixes #35822.
Helps godotengine/godot-proposals#1349.

The application/run/main_loop_type setting can handle custom global classes now (classes exposed with class_name keyword). For instance: MySceneTree.

The setting's default is changed from empty to SceneTree as to give some hint of what kind of input is accepted for the main loop type.

Main Loop Type

Tested on both editor and release builds.

Some custom scene tree class:

class_name MySceneTree extends SceneTree

func _initialize():
	print("MySceneTree startup!")

func _finalize():
	print("MySceneTree cleanup!")

func _iteration(_delta):
	return false

func _drop_files(files, from_screen):
	print(files, " ", from_screen)

Test project:

global_class_main_loop.zip

`application/run/main_loop_type` setting can handle custom global
classes (`class_name`).  For instance: `MySceneTree`.

The setting's default is changed from empty to `SceneTree` as to give
some hint of what kind of input is accepted for the main loop type.
@KoBeWi KoBeWi added this to the 4.0 milestone Aug 11, 2020
@dalexeev
Copy link
Member

Note that you can do this:

get_tree().set_script(preload("res://my_scene_tree.gd"))
# my_scene_tree.gd
extends SceneTree

func change_scene(path):
    print("--- %s ---" % path)
    return .change_scene(path)

This will work as expected.

@Xrayez
Copy link
Contributor Author

Xrayez commented Aug 12, 2020

get_tree has to be already initialized to do this. You'd miss the ability to receive the _initialize callback:

void MainLoop::init() {
if (init_script.is_valid()) {
set_script(init_script);
}
if (get_script_instance()) {
get_script_instance()->call("_initialize");
}
}

If your script inherits directly from MainLoop (not SceneTree), then get_tree() is likely to return null as well, so there would be hardly a way to override this via script.

} else {
main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "");
} else { // Not based on script path.
if (!editor && !ClassDB::class_exists(main_loop_type) && ScriptServer::is_global_class(main_loop_type)) {
Copy link
Contributor Author

@Xrayez Xrayez Aug 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!editor && !ClassDB::class_exists(main_loop_type) && ScriptServer::is_global_class(main_loop_type)) {
if (!ClassDB::class_exists(main_loop_type) && ScriptServer::is_global_class(main_loop_type)) {

Technically it's possible to extend/override the main loop of the editor itself upon restart, but if there are any errors (wrong base type, invalid script etc), then the editor will always crash with an alert (you'd have to modify project.godot to revert to previous behavior). 😅

Or make it so that it resets the value to SceneTree if we're running the editor automatically.

@akien-mga akien-mga requested a review from reduz September 2, 2020 09:43
@akien-mga akien-mga merged commit 358e209 into godotengine:master Sep 2, 2020
@akien-mga
Copy link
Member

Thanks!

@Xrayez Xrayez deleted the main-loop-type-class branch September 2, 2020 09:54
@eon-s
Copy link
Contributor

eon-s commented Sep 2, 2020

Can this be added to 3.x too or this depends on GDScript changes?

@Xrayez
Copy link
Contributor Author

Xrayez commented Sep 3, 2020

@eon-s I've tried to apply the same patch to 3.2, patch fails, so needs a dedicated PR for 3.2. If @akien-mga is fine about these changes for 3.2, I could certainly make one. 🙂

I think nothing has changed fundamentally in terms of global classes in 4.0.

@RimaitosLab
Copy link

Hi @Xrayez,
I'm currently trying to run a piece of code before any Node entered the Scene Tree.
In search of a solution, I stumbled upon the possibility to set your own MainLoop. I wanted to set a MainLoop which extends SceneTree but overrides the _initialize() method.
But I receive the error "Error: MainLoop type doesn't exist: MySceneTree".

I'm running Godot v3.3.2.stable on Linux.

I tried to run your example which failed to parse the project.godot file because the '@' raised a "ConfigFile parse error at [omitted]/project.godot:6: Unexpected character.". After manually editing the project.godot file, the example throws the same error as my previous try.

I hope you can help me with that.
Thanks in advance!

@Xrayez
Copy link
Contributor Author

Xrayez commented May 29, 2021

I'm running Godot v3.3.2.stable on Linux.

@RimaitosLab this feature was not backported to Godot 3.x branch, that's why you receive the error, but this is currently implemented in Godot 4.x (which is in development, not released yet).

As I said earlier, it's possible to backport the feature, but I need an approval from the maintainers before doing the backport. 🙂

@RimaitosLab
Copy link

oh sorry, it seems like I misunderstood the conversation.
Well it seems like I'm gonna learn how to compile Godot 😃

@tommyZZM
Copy link

tommyZZM commented Sep 6, 2021

hello @Xrayez @RimaitosLab @eon-s ~

I've tried to backport this feature to 3.x, And it works fine successfully for me. 😄

I've created a pull request here (#52438)

tommyZZM added a commit to tommyZZM/godot that referenced this pull request Sep 6, 2021
sairam4123 pushed a commit to sairam4123/godot that referenced this pull request Nov 10, 2021
lekoder pushed a commit to KoderaSoftwareUnlimited/godot that referenced this pull request Dec 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Project Setting application/run/main_loop_type: existing classes not found
7 participants