Commit Graph

86 Commits

Author SHA1 Message Date
5033a6af07 Never duplicate Scripts when duplicating resources recursively
This allows to duplicate PackedScenes safely
Fixes #108220
2025-08-14 10:26:48 -03:00
4841add19a Fixed local_to_scene duplication of typed dictionary. 2025-08-06 17:04:35 -05:00
d0826b0bfe Fix external resource IDs being lost for default properties 2025-07-31 16:57:35 +02:00
1123d7fd9c Merge pull request #102499 from Jordyfel/resource-docs
Improve documentation of some `Resource` methods
2025-06-28 13:02:54 +02:00
a0f9f5d90a Merge pull request #107770 from RandomShaper/fix_res_dupe_bindings
Enhance bindings of deep resource duplication
2025-06-21 11:14:19 +02:00
7dc37bdc9c Enhance bindings of deep resource duplication 2025-06-20 18:40:41 +02:00
b13a0e1834 Rename String::resize to resize_uninitialized, to better communicate to callers that new characters must be initialized. 2025-06-11 18:13:02 +02:00
342266cfd9 Overhaul Variant::duplicate() for resources
This in the scope of a duplication triggered via any type in the `Variant` realm. that is, the following: `Variant` itself, `Array` and `Dictionary`. That includes invoking `duplicate()` from scripts.

A `duplicate_deep(deep_subresources_mode)` method is added to `Variant`, `Array` and `Dictionary` (for compatibility reasons, simply adding an extra parameter was not possible). The default value for it is `RESOURCE_DEEP_DUPLICATE_NONE`, which is like calling `duplicate(true)`.

Remarks:
- The results of copying resources via those `Variant` types are exactly the same as if the copy were initiated from the `Resource` type at C++.
- In order to keep some separation between `Variant` and the higher-level animal which is `Resource`, `Variant` still contains the original code for that, so it's self-sufficient unless there's a `Resource` involved. Once the deep copy finds a `Resource` that has to be copied according to the duplication parameters, the algorithm invokes the `Resource` duplication machinery. When the stack is unwind back to a nesting level `Variant` can handle, `Variant` duplication logic keeps functioning.

While that is good from a responsibility separation standpoint, that would have a caveat: `Variant` would not be aware of the mapping between original and duplicate subresources and so wouldn't be able to keep preventing multiple duplicates.

To avoid that, this commit also introduces a wormwhole, a sharing mechanism by which `Variant` and `Resource` can collaborate in managing the lifetime of the original-to-duplicates map. The user-visible benefit is that the overduplicate prevention works as broadly as the whole `Variant` entity being copied, including all nesting levels, regardless how disconnected the data members containing resources may be across al the nesting levels. In other words, despite the aforementioned division of duties between `Variant` and `Resource` duplication logic, the duplicates map is shared among them. It's created when first finding a `Resource` and, however how deep the copy was working at that point, the map kept alive unitl the stack is unwind to the root user call, until the first step of the recursion.

Thanks to that common map of duplicates, this commit is able to fix the issue that `Resource::duplicate_for_local_scene()` used to ignore overridden duplicate logic.
2025-05-26 10:06:40 +02:00
2a03b459b9 Overhaul Resource::duplicate()
Thanks to a refactor, `Resource::duplicate_for_local_scene()` and `Resource::duplicate()` are now both users of the same, parametrized, implementation.

`Resource::duplicate()` now honors deepness in a more consistent and predictable fashion. `Resource::duplicate_deep()` is added (instead of just adding a parameter to the former, for compatibility needs).

The behavior after this change is as follows:
  - Deep (`deep=true`, formerly `subresources=true`):
    - Previously, only resources found as direct property values of the one to copy would be, recursively, duplicated.
    - Now, in addition, arrays and dictionaries are walked so the copy is truly deep, and only local subresources found across are copied.
    - Previously, subresources would be duplicated as many times as being referenced throughout the main resource.
    - Now, each subresource is only duplicated once and from that point, a referenced to that single copy is used. That's the enhanced behavior that `duplicate_for_local_scene()` already featured.
    - The behavior with respect to packed arrays is still duplication.
    - Formerly, arrays and dictionaries were recursive duplicated, with resources ignored.
    - Now, arrays and dictionaries are recursive duplicated, with resources duplicated.
    - When doing it through `duplicate_deep()`, there's a` deep_subresources_mode` parameter, with various possibilites to control if no resources are duplicated (so arrays, etc. are, but keeping referencing the originals), if only the internal ones are (resources with no non-local path, the default), or if all of them are. The default is to copy every subresource, just like `duplicate(true)`.
  - Not deep (`deep=false`, formerly `subresources=false`): <a name="resource-shallow"></a>
    - Previously, the first level of resources found as direct property values would be duplicated unconditionally. Packed arrays, arrays and dictionaries were non-recursively duplicated.
    - Now, no subresource found at any level in any form will be duplicated, but the original reference kept instead. Packed arrays, arrays and dictionaries are referenced, not duplicated at all.
    - Now, resources found as values of always-duplicate properties are duplicated, recursively or not matching what was requested for the root call.

This commit also changes what's the virtual method to override to customize the duplication (now it's the protected `_duplicate()` instead of the public `duplicate()`).
2025-05-26 10:05:25 +02:00
f5383df83b Overhaul Resource::duplicate_for_local_scene()
- Serves as a first step for future refactors.
- Code is simpler.
- Algorithm is more efficient: instead of two passes (dumb copy + resolve copies), it's single-pass.
- Now obeys `PROPERTY_USAGE_NEVER_DUPLICATE`.
- Now handles deep self-references (the resource to be duplicated being referenced somewhere deep).
2025-05-19 10:01:11 +02:00
8fb3697916 Avoid single character String allocations when appending characters
Removed calls to String::chr() when appending characters to Strings in Expression, Resource, and VariantParser, to avoid creating temporary Strings for each character.  Also updated the Resource case to resize String up front, since size is known.
2025-05-12 17:35:42 -04:00
f7e4987d0e Dictionary::get_key_list use LocalVector instead of List. 2025-04-09 02:46:24 +08:00
581d675eeb Core: Convert Math class to namespace 2025-03-21 10:29:18 -05:00
e281a9ace2 Merge pull request #102650 from bruvzg/emit_changed_spam
Prevent `changed` signal spam on resource reload.
2025-03-14 00:07:59 +01:00
bebe037abf Add ConstIterator to Dictionary. 2025-03-13 01:28:46 +08:00
e9703ee1aa Improve documentation of some Resource methods 2025-02-11 21:55:20 +02:00
da767ebfa2 Prevent changed signal spam on resource reload. 2025-02-11 15:22:49 +02:00
3c304ab7cc Merge pull request #96076 from AThousandShips/improve_null_check_core_drivers
[Core,Drivers] Improve use of `Ref.is_null/valid`
2024-12-23 11:14:58 -06:00
be86ce3103 Apply iwyu suggestion in core. 2024-12-19 00:43:47 +08:00
ec650a2f09 [Core,Drivers] Improve use of Ref.is_null/valid
Use `is_null` over `!is_valid` and vice versa.
2024-11-01 16:50:11 +01:00
38f9769bc6 [Core] Improve error messages with vformat 2024-10-30 15:55:51 +01:00
abf9d24520 Make internal unique scene resource ID deterministic
Changes the Resource::generate_scene_unique_id() to be deterministic and
seedable.

Fixes #97110
2024-09-23 15:07:00 +02:00
bc3dcf3d40 Expose several resource/resource-saver functions 2024-09-22 15:27:13 -04:00
74b9c38d58 ResourceLoader: Add thread-aware resource changed mechanism 2024-09-06 08:57:09 +02:00
e33fdb4296 Use MutexLock in more places 2024-08-29 14:12:59 +02:00
0d1c388991 Fix some legacy code 2024-08-01 12:08:14 +02:00
62d9ce6445 Re-add resource thread-safety measures
These deferring measures were added to aid threaded resource loading in being safe.

They were removed as seemingly unneeded, but it seems they are needed so resources involved in threaded loading interact with others only after "sync points".
2024-07-15 12:15:22 +02:00
b6994a414d Remove no longer needed thread safety measures
This is basically a revertion of commit 84b85d894c.
2024-06-12 18:10:11 +02:00
944b95e1a5 Merge pull request #91897 from RandomShaper/res_unreg_if_true
Add an identity check to resource unregistration from cache
2024-05-16 09:32:03 +02:00
413c11357d Use Core/Scene stringnames consistently 2024-05-13 23:41:07 +02:00
b70afac286 Add an identity check to resource unregistration from cache
This is needed because resources loaded with CACHE_MODE_IGNORE still have path_cache set.
2024-05-13 11:55:50 +02:00
a262d2d881 Add shorthand for using singleton string names 2024-05-11 18:53:08 +02:00
f9b488508c Add PackedVector4Array Variant type
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
2024-05-03 00:58:27 +02:00
c2be2dfbde Fix Resource::get_rid override not working in GDExtension 2024-04-06 01:27:16 +09:00
d5f944ff10 Merge pull request #89261 from paulloz/core/fix-script-reloading-outside-script-editor
Fix how scripts reload outside of ScriptEditor
2024-03-24 01:15:23 +01:00
63674648fb Fix how scripts reload outside of ScriptEditor 2024-03-18 10:29:06 +01:00
1c8ef9e252 Merge pull request #89251 from KoBeWi/fastpector
Speed up inspector updates for TileMap
2024-03-09 00:52:09 +01:00
7319b612f3 Speed up inspector updates for TileMap 2024-03-07 18:01:30 +01:00
42ce14043e Expose scene unique id functionality in Resource 2024-03-07 14:53:58 +01:00
84b85d894c Improve thread safety of resource loading 2024-02-28 15:19:22 +01:00
608b5d2e07 Fix recursive resource local to scene
Any resource that contains other local to scene resources inside of
arrays or dictionaries will now be duplicated and configured.

The case where a scene's node has an exported array/dictionary
property containing local to scene resources is NOT handled here.
2024-01-11 20:02:14 +01:00
f8f8fe0615 Improve message about resources in use at exit 2023-11-28 14:01:08 +01:00
a3627b6e37 Assign temporary path to preloaded resources 2023-11-10 00:43:30 +01:00
79ce0c6e80 Reimplement Resource._local_to_scene_setup & remove workaround
Reimplements the virtual method _setup_local_to_scene, lost in #51970

Also deprecates the redundant `setup_local_to_scene_requested` signal.
2023-09-09 13:51:12 +02:00
4795c3cdfa Clear the previously set state when configuring for a new scene root node
Saving a subscene causes the main scene to be re-instantiated. And the resource
instance in the main scene will be reused when the main scene is re-instantiated.
So for resources with `resource_local_to_scene` enabled, resetting state may be
necessary (at least for `ViewportTexture`).
2023-08-08 23:49:53 +08:00
de4a3fa151 Unify and streamline connecting to Resource changes 2023-07-17 19:35:57 +02:00
c586835541 Make ResourceCache::get_cached_resources thread-safe 2023-02-20 01:02:08 -08:00
bfffb8f254 Fix Resource::duplicate() missing packed arrays 2023-01-28 23:06:44 -05:00
2a65f6812b Add PROPERTY_USAGE_NEVER_DUPLICATE flag and use for script
Co-authored-by: Yakov Borevich <j.borevich@gmail.com>
2023-01-24 16:37:50 -06:00
2bc0bcbd26 PropertyUsage: Rename "DO_NOT_SHARE_ON_DUPLICATE" to "ALWAYS_DUPLICATE" 2023-01-24 16:05:07 -06:00