X Tutup
Skip to content

Core: Clean up headers in core/config, forward-declare MainLoop in OS#111297

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
Repiteo:core/header-cleanup-config
Oct 6, 2025
Merged

Core: Clean up headers in core/config, forward-declare MainLoop in OS#111297
Repiteo merged 1 commit intogodotengine:masterfrom
Repiteo:core/header-cleanup-config

Conversation

@Repiteo
Copy link
Contributor

@Repiteo Repiteo commented Oct 5, 2025

Tackles scope reduction for two files: core/config/engine.h aand core/config/project_settings.h. The latter was inconsequential, but the former revealed several dependency chains for core/os/main_loop.h, despite neither it nor the compilation file using MainLoop in any way.

@Repiteo Repiteo added this to the 4.x milestone Oct 5, 2025
@Repiteo Repiteo requested a review from a team as a code owner October 5, 2025 18:17
@Repiteo Repiteo requested review from a team as code owners October 5, 2025 18:17
@Repiteo Repiteo requested review from a team as code owners October 5, 2025 18:17
@Repiteo Repiteo removed request for a team October 5, 2025 18:17
@Repiteo Repiteo force-pushed the core/header-cleanup-config branch 2 times, most recently from 7e6c5a6 to 555b7f1 Compare October 5, 2025 18:28
Copy link
Member

@Ivorforce Ivorforce left a comment

Choose a reason for hiding this comment

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

Makes sense to me. main_loop.h has a sizable tail of not very common includes.

I'm surprised at how many files are apparently including engine.h and project_setting.h.

@Ivorforce Ivorforce modified the milestones: 4.x, 4.6 Oct 5, 2025
@Repiteo Repiteo force-pushed the core/header-cleanup-config branch from 555b7f1 to ce89cd6 Compare October 5, 2025 18:34
@Repiteo
Copy link
Contributor Author

Repiteo commented Oct 5, 2025

Oh! Now THIS is an exciting revelation. The CI for this PR initially failed on all non-msvc compilers, citing some variation of:

ERROR: In file included from ./core/config/project_settings.h:33,
                 from platform\windows\os_windows.h:36,
                 from platform\windows\godot_windows.cpp:31:
./core/object/object.h:497:24: error: 'ClassDB' in namespace '::' does not name a type
  497 |         friend class ::ClassDB;                                                                                                                 \
      |                        ^~~~~~~
./core/config/project_settings.h:39:9: note: in expansion of macro 'GDCLASS'
   39 |         GDCLASS(ProjectSettings, Object);
      |         ^~~~~~~
./core/object/object.h:497:9: error: friend declaration does not name a class or function
  497 |         friend class ::ClassDB;                                                                                                                 \
      |         ^~~~~~
./core/config/project_settings.h:39:9: note: in expansion of macro 'GDCLASS'
   39 |         GDCLASS(ProjectSettings, Object);
      |         ^~~~~~~

Meaning that, for the first time that I can recall, ClassDB has been decoupled to such an extent that there's incidental header paths which don't include it anymore! This bug was resolved by simply declaring class ClassDB; in the core/object/object.h, but I'm popping off that I encounted it in the first place

\
private:

class ClassDB;
Copy link
Member

Choose a reason for hiding this comment

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

I'm surprised object.h doesn't include ClassDB (anymore?).

Doesn't that mean that any Object that wants to register properties with ADD_PROPERTY now needs to include ClassDB, which is far from obvious?

If that's the only coupling it does make sense to remove it of course, but then do we need to go one step further and turns ADD_PROPERTY and friends into member methods which are implemented in object.cpp (including class_db.h), so callers don't need to include it?

Copy link
Contributor Author

@Repiteo Repiteo Oct 5, 2025

Choose a reason for hiding this comment

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

That exact confusion is why I'm wanting to migrate the macros to class_db.h instead:

I will note that an explicit ClassDB include in compilation files is the paradigm that GDExtension uses, so I don't think it's inherently harmful. But it isn't the most obvious include either, so making them member functions instead could work out


#include <cstdlib>

class MainLoop;
Copy link
Member

Choose a reason for hiding this comment

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

(Oof, GH failed to send my comment, need to retype it all again...)

So this one warrants discussion. It may be worth it, but it's a bit of an anti-pattern IMO to forward-declare a class that it returns by a public method of a class (here MainLoop *OS::get_main_loop() and void OS::set_main_loop(MainLoop *p_main_loop).

It means that any class that uses this API from OS not only needs to include core/os/os.h, but also core/os/main_loop.h. That's unconventional IMO, and leads to surprises, as it seemed to be the case for you:

The latter was inconsequential, but the former revealed several dependency chains for core/os/main_loop.h, despite neither it nor the compilation file using MainLoop in any way.

Those compilation files all use MainLoop via OS::get_singleton()->get_main_loop().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm... I'm not sure if I agree with it being an anti-pattern. If this was the only thing this class did then maybe, but not every file that calls OS is doing so for MainLoop.

They led to surprises for me because the implicit link is now broken, but that's an inevitability with this type of change. If we're wanting to move more towards including files with intent, then weeding out those that aren't is the price we gotta pay

Copy link
Member

@Ivorforce Ivorforce Oct 5, 2025

Choose a reason for hiding this comment

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

I agree that it's not optimal. Ideally C++ wouldn't put us in a position where we choose between usability of an interface and compile time, but unfortunately that's just how the language is. Like Repiteo, I don't consider it an anti-pattern, just an inconvenience.

Besides needing to omit includes in some locations for technical reasons (cyclic dependencies), we have a problem of extremely long include chains in some spots. We will, I'm fully convinced, make the trade-off of requiring an additional include in some locations. From my perspective, this is a matter of judging each situation on a case by case basis.

In this specific instance, I'd say that it's worth it, because OS is a kitchen sink class, where only a handful of users will interface with the MainLoop class.

Copy link
Member

Choose a reason for hiding this comment

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

Should we make it a policy to document such incomplete return types with some comment that shows up in IDEs? What syntax gets picked up, /// comments?

Copy link
Member

@akien-mga akien-mga Oct 5, 2025

Choose a reason for hiding this comment

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

To further illustrate my point, given the platform-related changes in this PR, I fully expect that this will cause a compilation error for third-party platform ports (e.g. consoles, homebrews) when they update. It could also potentially break a first-party platform we don't test on CI, though I think that's only visionOS and its calls to OS::get_main_loop are all shared with iOS through drivers/apple_embedded.

But yeah, I agree that this is worth doing for OS in this case. It's indeed a very commonly included class while only a handful of includers need to call get_main_loop(), so that's a good rationale for making it an incomplete definition.

Note that the title of this commit/PR is a bit misleading, as the biggest impact of this PR is the change to core/os/os.h which is not in core/config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's a bit superfluous, but there's no real harm in it. Adjusted to the // NOTE: syntax specified in the docs

Copy link
Member

Choose a reason for hiding this comment

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

Do // comments get picked up as documentation tooltips in IDEs?

Copy link
Member

Choose a reason for hiding this comment

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

It does in CLion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It can in VSCode, though that technically depends on the extension. Both the Microsoft C/C++ and clangd extensions support it, which should cover most relevant cases

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good, then I prefer the // Note: style too, Doxygen subjectively doesn't look very nice to me :P

@AThousandShips AThousandShips changed the title Core: Cleanup headers in core/config Core: Clean up headers in core/config Oct 5, 2025
@Repiteo Repiteo force-pushed the core/header-cleanup-config branch from ce89cd6 to 1284bf4 Compare October 5, 2025 22:08
@Repiteo Repiteo removed the discussion label Oct 5, 2025
@akien-mga akien-mga changed the title Core: Clean up headers in core/config Core: Clean up headers in core/config, forward-declare MainLoop in OS Oct 6, 2025
- `MainLoop` now forward-declared in `OS`
@Repiteo Repiteo force-pushed the core/header-cleanup-config branch from 1284bf4 to 5935a32 Compare October 6, 2025 14:43
@Repiteo Repiteo merged commit 8d6426e into godotengine:master Oct 6, 2025
20 checks passed
@Repiteo Repiteo deleted the core/header-cleanup-config branch October 6, 2025 19:35
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.

3 participants

X Tutup