X Tutup
Skip to content

Expose set_edited and is_edited on EditorInterface#91703

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
Naros:expose-object-edited-status
Dec 2, 2025
Merged

Expose set_edited and is_edited on EditorInterface#91703
Repiteo merged 1 commit intogodotengine:masterfrom
Naros:expose-object-edited-status

Conversation

@Naros
Copy link
Contributor

@Naros Naros commented May 8, 2024

Exposes several tools-based methods on Object.

The reason to expose these is simple. If an editor plugin provides a EditorResourcePreviewGenerator implementation to create thumbnails for custom resources, there isn't a way for the plugin to have the EditorResourcePreview regenerate thumbnails when the resource is modified. In the engine, this is handled by calling set_edited(true), which increments the edited version that is used by the hash algorithm to determine whether the cached thumbnail should be discarded and regenerated.

By exposing these three methods, addons can easily use the thumbnail generator framework and regenerate the thumbnails when the underlying resource is changed rather than requiring an editor restart.

@Naros Naros requested review from a team as code owners May 8, 2024 10:43
@Chaosus Chaosus added this to the 4.x milestone May 8, 2024
@Naros Naros force-pushed the expose-object-edited-status branch 2 times, most recently from 02515d0 to 60d7146 Compare May 8, 2024 15:44
@Naros Naros force-pushed the expose-object-edited-status branch from 60d7146 to 400d3fe Compare May 9, 2024 20:18
@Naros Naros requested a review from AThousandShips May 9, 2024 20:18
@Naros Naros force-pushed the expose-object-edited-status branch from 400d3fe to 2665d37 Compare August 15, 2024 14:32
@Naros Naros requested a review from RedMser August 15, 2024 14:32
@sanderfoobar
Copy link

sanderfoobar commented Sep 1, 2024

Looks OK, its just adding existing methods to the ClassDB registration so shouldn't think too hard about merging this.

Copy link
Member

@Mickeon Mickeon left a comment

Choose a reason for hiding this comment

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

Starting thoughts, I'm not particularly fond of this. Mainly, these methods feel too "technical", "mechanical" to be needing to be exposed. The additional documentation does not help. Yes, these are used by the engine, but what can the user... use this for?
The above questioning is why we decided to "unexpose" Resource's setup_local_to_scene (#67082). The method is literally just an internal method exposed for little to no reason: The user could implement it on their own, and documenting its internal purpose was difficult. So we gotta be a bit careful to expose these willy-nilly.

A quick skim over this has me believe that it would be a better fit to expose this in Resource, instead.

And furthermore, these are purely editor-exclusive, and very situational. Too much to be in Object, personally.
This has me think there's got to be a better way to accomplish what one may need this for. Namely, exposing these methods through another Editor-exclusive class.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Set whether the object has been edited based on the [param edited] value.
If [param edited] is [code]true[/code], the object is marked as edited.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Returns whether the object has been marked as edited using [method set_edited].
Returns [code]true[/code] if the object has been marked as edited through [method set_edited].

@Naros
Copy link
Contributor Author

Naros commented Sep 1, 2024

Starting thoughts, I'm not particularly fond of this. Mainly, these methods feel too "technical", "mechanical" to be needing to be exposed. The additional documentation does not help. Yes, these are used by the engine, but what can the user... use this for?

Hi, @Mickeon. There are several reasons for exposing these methods.

set_edited:

It's common practice in when serializing sub-resources during a save operation to set the resource edited state to false. Without this method, any custom ResourceFormatSaver has no way to reset this state, and the engine will continue to view the resource as modified. This creates a divide in how C++ modules and GDExtension work for plug-ins, meaning that GDExtensions that have custom resource loader/saver are incapable of handling this use case properly.

is_edited:

This one is chosen to be exposed mainly because if GDExtension needs a way to set the state to true or false, it may need a way in the future to query the edited state of the object. So this is purely for convenience.

get_edited_version:

This was being exposed primarily to support hash_edited_version_for_preview; however, in hindsight, maybe it would make more sense to change this and expose hash_edited_version_for_preview instead so that again resources exposed in GDExtension that may want to disable previews, like TileSet, can do so.

A quick skim over this has me believe that it would be a better fit to expose this in Resource, instead.

And furthermore, these are purely editor-exclusive, and very situational. Too much to be in Object, personally. This has me think there's got to be a better way to accomplish what one may need this for. Namely, exposing these methods through another Editor-exclusive class.

For our purposes, exposing this on the Resource class would definitely work, given that's our prime use case with our custom format loader/saver for our plug-in's data; however, I wonder if placing these on EditorInterface would also be better for other non-resource types, such as ConfigFile?

void EditorInterface::set_object_edited(Object* p_object, bool p_edited);
bool EditorInterface::is_object_edited(Object* p_object) const;

As for the get_edited_version or hash_edited_version_for_preview, I think maybe the best play is to expose the latter on the Resource class with a GDVIRTUAL call that can be implemented by custom resources.

Whats your thoughts on that approach @Mickeon ?

@Naros Naros requested a review from Mickeon September 16, 2024 09:47
@Mickeon
Copy link
Member

Mickeon commented Sep 16, 2024

Sorry for not having much else to add. I am mostly looking at this from a general user perspective. Whether this is actually implemented should not be up to me.

I wonder if placing these on EditorInterface would also be better for other non-resource types, such as ConfigFile?

As I hinted at, delegating this to another class may be a better choice. So, personally, yes.

@Naros Naros force-pushed the expose-object-edited-status branch from 2665d37 to d5050ba Compare January 5, 2025 20:01
@Naros
Copy link
Contributor Author

Naros commented Jan 5, 2025

@AThousandShips so I decided on the following, in an attempt to get this into 4.4.

  1. I removed exposing the get_edited_version from this PR. That is more directed toward rendering of thumbnails and I'd like to look at that work from a separate PR as I believe there may be other changes to align GDE and C++ modules in this area.
  2. I removed exposing the set_edited and is_edited on Object and provided delegators from EditorInterface instead.

Let me know if you think anything else is needed here.

@Naros Naros changed the title Expose set_edited, is_edited, and get_edited_version Expose set_edited and is_edited on EditorInterface Jan 5, 2025
@Naros Naros force-pushed the expose-object-edited-status branch from d5050ba to dd2a9ea Compare November 24, 2025 10:36
@Naros Naros requested a review from a team November 24, 2025 10:36
@Naros Naros force-pushed the expose-object-edited-status branch from dd2a9ea to f575861 Compare November 29, 2025 16:11
Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

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

Thanks!

This makes sense to me. Having it on EditorInterface sounds good, because these are only for editor plugins. The docs seem pretty clear, although, I think they would be even better with @Mickeon's suggestions above

@Naros Naros force-pushed the expose-object-edited-status branch from f575861 to a37bc88 Compare November 30, 2025 15:38
@Naros
Copy link
Contributor Author

Naros commented Nov 30, 2025

@dsnopek applied @Mickeon 's suggestions from above. Please take another pass.

Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@KoBeWi
Copy link
Member

KoBeWi commented Nov 30, 2025

Any example plugin to test this?
I checked how it works with my plugin and setting or not setting edited does not seem to make any difference.

This one is chosen to be exposed mainly because if GDExtension needs a way to set the state to true or false, it may need a way in the future to query the edited state of the object. So this is purely for convenience.

Sounds like theoretical use-case.

@Naros
Copy link
Contributor Author

Naros commented Nov 30, 2025

In Orchestrator for example, we want to have a way to mark our custom Resource as edited when a user makes some UI modification. Right now we either need to implement this behavior with custom is_edited / set_edited methods on our resource or maintain this state elsewhere in the UI.

In addition, there are several spots in the editor where it explicitly uses Resource::is_edited. For example, in the EditorFileSystem::_copy_file method, the editor explicitly checks whether a resource is modified before it is copied, and if it is, it explicitly calls save on it to avoid changes being lost and discrepancies.

Another example is in EditorNode::_find_and_save_resource, it again checks whether the Resource::is_edited, and only triggers the ResourceSaver::save call if the resource is flagged as edited. The same also applies in EditorNode::_save_external_resources.

A custom resource that implements its own edited tracking can't make use of any of this behavior at all.

So it's not only just a matter of convenience for tracking the state within one's own plugin, but it's also about making sure our custom resources work just like any other Godot resource does, @KoBeWi .

@KoBeWi
Copy link
Member

KoBeWi commented Nov 30, 2025

Ah, so it's for resources edited outside the inspector?

}

void EditorInterface::set_object_edited(Object *p_object, bool p_edited) {
ERR_FAIL_COND_MSG(!p_object, "Cannot change edited status on a null object");
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ERR_FAIL_COND_MSG(!p_object, "Cannot change edited status on a null object");
ERR_FAIL_NULL_MSG(p_object, "Cannot change edited status on a null object.");

}

bool EditorInterface::is_object_edited(Object *p_object) const {
ERR_FAIL_COND_V_MSG(!p_object, false, "Cannot check edit status on a null object");
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ERR_FAIL_COND_V_MSG(!p_object, false, "Cannot check edit status on a null object");
ERR_FAIL_NULL_V_MSG(p_object, false, "Cannot check edit status on a null object.");

@Naros Naros force-pushed the expose-object-edited-status branch from a37bc88 to ff561c1 Compare December 1, 2025 11:43
@Naros Naros requested a review from AThousandShips December 1, 2025 11:43
@Repiteo Repiteo requested review from KoBeWi and removed request for a team December 2, 2025 16:13
Copy link
Member

@KoBeWi KoBeWi left a comment

Choose a reason for hiding this comment

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

Still not convinced about is_object_edited(), but otherwise looks fine.

@Repiteo Repiteo modified the milestones: 4.x, 4.6 Dec 2, 2025
@Repiteo Repiteo merged commit 82e4493 into godotengine:master Dec 2, 2025
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Dec 2, 2025

Thanks!

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.

10 participants

X Tutup