diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 770bed3353e..f1f7af4415e 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -535,6 +535,10 @@ Ref Resource::duplicate_deep(ResourceDeepDuplicateMode p_deep_subresou return dupe; } +Ref Resource::_duplicate_deep_bind(DeepDuplicateMode p_deep_subresources_mode) const { + return _duplicate_from_variant(true, (ResourceDeepDuplicateMode)p_deep_subresources_mode, 0); +} + Ref Resource::_duplicate_from_variant(bool p_deep, ResourceDeepDuplicateMode p_deep_subresources_mode, int p_recursion_count) const { // A call without deep duplication would have been early-rejected at Variant::duplicate() unless it's the root call. DEV_ASSERT(!(p_recursion_count > 0 && p_deep_subresources_mode == RESOURCE_DEEP_DUPLICATE_NONE)); @@ -724,12 +728,13 @@ void Resource::_bind_methods() { ClassDB::bind_method(D_METHOD("emit_changed"), &Resource::emit_changed); ClassDB::bind_method(D_METHOD("duplicate", "deep"), &Resource::duplicate, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("duplicate_deep", "deep_subresources_mode"), &Resource::duplicate_deep, DEFVAL(RESOURCE_DEEP_DUPLICATE_INTERNAL)); + ClassDB::bind_method(D_METHOD("duplicate_deep", "deep_subresources_mode"), &Resource::_duplicate_deep_bind, DEFVAL(RESOURCE_DEEP_DUPLICATE_INTERNAL)); // For the bindings, it's much more natural to expose this enum from the Variant realm via Resource. - ClassDB::bind_integer_constant(get_class_static(), StringName("ResourceDeepDuplicateMode"), "RESOURCE_DEEP_DUPLICATE_NONE", RESOURCE_DEEP_DUPLICATE_NONE); - ClassDB::bind_integer_constant(get_class_static(), StringName("ResourceDeepDuplicateMode"), "RESOURCE_DEEP_DUPLICATE_INTERNAL", RESOURCE_DEEP_DUPLICATE_INTERNAL); - ClassDB::bind_integer_constant(get_class_static(), StringName("ResourceDeepDuplicateMode"), "RESOURCE_DEEP_DUPLICATE_ALL", RESOURCE_DEEP_DUPLICATE_ALL); + // Therefore, we can't use BIND_ENUM_CONSTANT here because we need some customization. + ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_NONE", RESOURCE_DEEP_DUPLICATE_NONE); + ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_INTERNAL", RESOURCE_DEEP_DUPLICATE_INTERNAL); + ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_ALL", RESOURCE_DEEP_DUPLICATE_ALL); ADD_SIGNAL(MethodInfo("changed")); ADD_SIGNAL(MethodInfo("setup_local_to_scene_requested")); diff --git a/core/io/resource.h b/core/io/resource.h index 7d9b19c83a0..92665b72754 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -96,6 +96,11 @@ private: Variant _duplicate_recursive(const Variant &p_variant, const DuplicateParams &p_params, uint32_t p_usage = 0) const; void _find_sub_resources(const Variant &p_variant, HashSet> &p_resources_found); + // Only for binding the deep duplicate method, so it doesn't need actual members. + enum DeepDuplicateMode : int; + + _ALWAYS_INLINE_ Ref _duplicate_deep_bind(DeepDuplicateMode p_deep_subresources_mode) const; + protected: virtual void _resource_path_changed(); static void _bind_methods(); @@ -183,7 +188,7 @@ public: ~Resource(); }; -VARIANT_ENUM_CAST(ResourceDeepDuplicateMode); +VARIANT_ENUM_CAST(Resource::DeepDuplicateMode); class ResourceCache { friend class Resource; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index b3f16d76c4a..cc7a528c83a 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -2206,6 +2206,8 @@ static void _register_variant_builtin_methods_math() { bind_static_method(Color, from_rgba8, sarray("r8", "g8", "b8", "a8"), varray(255)); } +VARIANT_ENUM_CAST(ResourceDeepDuplicateMode); + static void _register_variant_builtin_methods_misc() { /* RID */ diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 98c9e7c7910..9567b46a220 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -341,7 +341,7 @@ Duplicates this array, deeply, like [method duplicate][code](true)[/code], with extra control over how subresources are handled. - [param deep_subresources_mode] must be one of the values from [enum Resource.ResourceDeepDuplicateMode]. By default, only internal resources will be duplicated (recursively). + [param deep_subresources_mode] must be one of the values from [enum Resource.DeepDuplicateMode]. By default, only internal resources will be duplicated (recursively). diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index e2c2b12c39e..143ec6ad14e 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -197,7 +197,7 @@ Duplicates this dictionary, deeply, like [method duplicate][code](true)[/code], with extra control over how subresources are handled. - [param deep_subresources_mode] must be one of the values from [enum Resource.ResourceDeepDuplicateMode]. By default, only internal resources will be duplicated (recursively). + [param deep_subresources_mode] must be one of the values from [enum Resource.DeepDuplicateMode]. By default, only internal resources will be duplicated (recursively). diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 510a8dd64fc..0d4e73d4d7d 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -54,7 +54,7 @@ Duplicates this resource, returning a new resource with its [code]export[/code]ed or [constant PROPERTY_USAGE_STORAGE] properties copied from the original. If [param deep] is [code]false[/code], a [b]shallow[/b] copy is returned: nested [Array], [Dictionary], and [Resource] properties are not duplicated and are shared with the original resource. - If [param deep] is [code]true[/code], a [b]deep[/b] copy is returned: all nested arrays, dictionaries, and packed arrays are also duplicated (recursively). Any [Resource] found inside will only be duplicated if it's local, like [constant RESOURCE_DEEP_DUPLICATE_INTERNAL] used with [method duplicate_deep]. + If [param deep] is [code]true[/code], a [b]deep[/b] copy is returned: all nested arrays, dictionaries, and packed arrays are also duplicated (recursively). Any [Resource] found inside will only be duplicated if it's local, like [constant DEEP_DUPLICATE_INTERNAL] used with [method duplicate_deep]. The following exceptions apply: - Subresource properties with the [constant PROPERTY_USAGE_ALWAYS_DUPLICATE] flag are always duplicated (recursively or not, depending on [param deep]). - Subresource properties with the [constant PROPERTY_USAGE_NEVER_DUPLICATE] flag are never duplicated. @@ -64,10 +64,10 @@ - + Duplicates this resource, deeply, like [method duplicate][code](true)[/code], with extra control over how subresources are handled. - [param deep_subresources_mode] must be one of the values from [enum ResourceDeepDuplicateMode]. + [param deep_subresources_mode] must be one of the values from [enum DeepDuplicateMode]. @@ -186,13 +186,13 @@ - + No subresorces at all are duplicated. This is useful even in a deep duplication to have all the arrays and dictionaries duplicated but still pointing to the original resources. - + Only subresources without a path or with a scene-local path will be duplicated. - + Every subresource found will be duplicated, even if it has a non-local path. In other words, even potentially big resources stored separately will be duplicated.