Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions core/extension/gdextension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,19 @@ String GDExtensionResourceLoader::get_resource_type(const String &p_path) const
}

#ifdef TOOLS_ENABLED
void GDExtensionResourceLoader::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
Ref<GDExtension> gdext = ResourceLoader::load(p_path);
if (gdext.is_null()) {
return;
}

for (const StringName class_name : gdext->get_classes_used()) {
if (ClassDB::class_exists(class_name)) {
r_classes->insert(class_name);
}
}
}

bool GDExtension::has_library_changed() const {
return loader->has_library_changed();
}
Expand Down
3 changes: 3 additions & 0 deletions core/extension/gdextension.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class GDExtensionResourceLoader : public ResourceFormatLoader {
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
virtual bool handles_type(const String &p_type) const override;
virtual String get_resource_type(const String &p_path) const override;
#ifdef TOOLS_ENABLED
virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes) override;
#endif // TOOLS_ENABLED
};

#ifdef TOOLS_ENABLED
Expand Down
39 changes: 35 additions & 4 deletions core/io/resource_format_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "core/io/missing_resource.h"
#include "core/object/script_language.h"
#include "core/version.h"
#include "scene/resources/packed_scene.h"

//#define print_bl(m_what) print_line(m_what)
#define print_bl(m_what) (void)(m_what)
Expand Down Expand Up @@ -937,11 +938,10 @@ void ResourceLoaderBinary::get_classes_used(Ref<FileAccess> p_f, HashSet<StringN
return;
}

for (int i = 0; i < internal_resources.size(); i++) {
p_f->seek(internal_resources[i].offset);
for (const IntResource &res : internal_resources) {
p_f->seek(res.offset);
String t = get_unicode_string();
ERR_FAIL_COND(p_f->get_error() != OK);
if (t != String()) {
if (!p_f->get_error() && t != String() && ClassDB::class_exists(t)) {
p_classes->insert(t);
}
}
Expand Down Expand Up @@ -1518,6 +1518,37 @@ void ResourceFormatLoaderBinary::get_classes_used(const String &p_path, HashSet<
loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
loader.res_path = loader.local_path;
loader.get_classes_used(f, r_classes);

// Fetch the nodes inside scene files.
if (loader.type == "PackedScene") {
ERR_FAIL_COND(loader.load() != OK);

Ref<SceneState> state = Ref<PackedScene>(loader.get_resource())->get_state();
for (int i = 0; i < state->get_node_count(); i++) {
const StringName node_name = state->get_node_type(i);
if (ClassDB::class_exists(node_name)) {
r_classes->insert(node_name);
}

// Fetch the values of properties in the node.
for (int j = 0; j < state->get_node_property_count(i); j++) {
const Variant var = state->get_node_property_value(i, j);
if (var.get_type() != Variant::OBJECT) {
continue;
}

const Object *obj = var.get_validated_object();
if (obj == nullptr) {
continue;
}

const StringName obj_name = obj->get_class_name();
if (ClassDB::class_exists(obj_name)) {
r_classes->insert(obj_name);
}
}
}
}
}

String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const {
Expand Down
25 changes: 25 additions & 0 deletions core/io/resource_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons

return pat.metadata;
}

void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat, false);
Expand All @@ -456,6 +457,18 @@ void ResourceFormatImporter::get_dependencies(const String &p_path, List<String>
ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types);
}

void ResourceFormatImporter::get_build_dependencies(const String &p_path, HashSet<String> *r_dependencies) {
if (!exists(p_path)) {
return;
}

List<Ref<ResourceImporter>> valid_importers;
get_importers_for_file(p_path, &valid_importers);
for (Ref<ResourceImporter> importer : valid_importers) {
importer->get_build_dependencies(p_path, r_dependencies);
}
}

Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) const {
for (int i = 0; i < importers.size(); i++) {
if (importers[i]->get_importer_name() == p_name) {
Expand Down Expand Up @@ -555,9 +568,21 @@ ResourceFormatImporter::ResourceFormatImporter() {

//////////////

void ResourceImporter::get_build_dependencies(const String &p_path, HashSet<String> *r_dependencies) {
Vector<String> ret;
if (GDVIRTUAL_CALL(_get_build_dependencies, p_path, ret)) {
for (int i = 0; i < ret.size(); i++) {
r_dependencies->insert(ret[i]);
}
return;
}
}

void ResourceImporter::_bind_methods() {
BIND_ENUM_CONSTANT(IMPORT_ORDER_DEFAULT);
BIND_ENUM_CONSTANT(IMPORT_ORDER_SCENE);

GDVIRTUAL_BIND(_get_build_dependencies, "path");
}

/////
Expand Down
6 changes: 6 additions & 0 deletions core/io/resource_importer.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class ResourceFormatImporter : public ResourceFormatLoader {
virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes) override;
virtual bool exists(const String &p_path) const override;

void get_build_dependencies(const String &p_path, HashSet<String> *r_dependencies);

virtual int get_import_order(const String &p_path) const override;

Error get_import_order_threads_and_importer(const String &p_path, int &r_order, bool &r_can_threads, String &r_importer) const;
Expand Down Expand Up @@ -106,6 +108,8 @@ class ResourceImporter : public RefCounted {
GDCLASS(ResourceImporter, RefCounted);

protected:
GDVIRTUAL1RC(Vector<String>, _get_build_dependencies, String)

static void _bind_methods();

public:
Expand Down Expand Up @@ -155,6 +159,8 @@ class ResourceImporter : public RefCounted {
virtual Error import_group_file(const String &p_group_file, const HashMap<String, HashMap<StringName, Variant>> &p_source_file_options, const HashMap<String, String> &p_base_paths) { return ERR_UNAVAILABLE; }
virtual bool are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const { return true; }
virtual String get_import_settings_string() const { return String(); }

virtual void get_build_dependencies(const String &p_path, HashSet<String> *r_build_dependencies);
};

VARIANT_ENUM_CAST(ResourceImporter::ImportOrder);
Expand Down
24 changes: 24 additions & 0 deletions core/object/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2152,6 +2152,30 @@ bool ClassDB::is_class_runtime(const StringName &p_class) {
return ti->is_runtime;
}

#ifdef TOOLS_ENABLED
void ClassDB::add_class_dependency(const StringName &p_class, const StringName &p_dependency) {
Locker::Lock lock(Locker::STATE_WRITE);

ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class));
if (classes[p_class].dependency_list.find(p_dependency)) {
ERR_FAIL();
}

classes[p_class].dependency_list.push_back(p_dependency);
}

void ClassDB::get_class_dependencies(const StringName &p_class, List<StringName> *r_rependencies) {
Locker::Lock lock(Locker::STATE_READ);

ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_NULL_MSG(ti, vformat("Cannot get class '%s'.", String(p_class)));

for (const StringName &dep : ti->dependency_list) {
r_rependencies->push_back(dep);
}
}
#endif // TOOLS_ENABLED

void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) {
if (resource_base_extensions.has(p_extension)) {
return;
Expand Down
11 changes: 11 additions & 0 deletions core/object/class_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class ClassDB {
HashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list;
HashMap<StringName, PropertyInfo> property_map;

#ifdef DEBUG_ENABLED
List<StringName> constant_order;
List<StringName> method_order;
Expand All @@ -127,6 +128,11 @@ class ClassDB {
HashMap<StringName, Vector<Error>> method_error_values;
HashMap<StringName, List<StringName>> linked_properties;
#endif // DEBUG_ENABLED

#ifdef TOOLS_ENABLED
List<StringName> dependency_list;
#endif

HashMap<StringName, PropertySetGet> property_setget;
HashMap<StringName, Vector<uint32_t>> virtual_methods_compat;

Expand Down Expand Up @@ -499,6 +505,11 @@ class ClassDB {
static bool is_class_reloadable(const StringName &p_class);
static bool is_class_runtime(const StringName &p_class);

#ifdef TOOLS_ENABLED
static void add_class_dependency(const StringName &p_class, const StringName &p_dependency);
static void get_class_dependencies(const StringName &p_class, List<StringName> *r_rependencies);
#endif

static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class);
static void get_resource_base_extensions(List<String> *p_extensions);
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
Expand Down
7 changes: 6 additions & 1 deletion core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ enum PropertyUsageFlags {
#define ADD_SUBGROUP_INDENT(m_name, m_prefix, m_depth) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix, m_depth)
#define ADD_LINKED_PROPERTY(m_property, m_linked_property) ::ClassDB::add_linked_property(get_class_static(), m_property, m_linked_property)

#ifdef TOOLS_ENABLED
#define ADD_CLASS_DEPENDENCY(m_class) ::ClassDB::add_class_dependency(get_class_static(), m_class)
#else
#define ADD_CLASS_DEPENDENCY(m_class)
#endif

#define ADD_ARRAY_COUNT(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, StringName(m_count_property_setter), StringName(m_count_property_getter), m_prefix)
#define ADD_ARRAY_COUNT_WITH_USAGE_FLAGS(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix, m_property_usage_flags) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, StringName(m_count_property_setter), StringName(m_count_property_getter), m_prefix, m_property_usage_flags)
#define ADD_ARRAY(m_array_path, m_prefix) ClassDB::add_property_array(get_class_static(), m_array_path, m_prefix)
Expand Down Expand Up @@ -979,7 +985,6 @@ class Object {
bool editor_is_section_unfolded(const String &p_section);
const HashSet<String> &editor_get_section_folding() const { return editor_section_folding; }
void editor_clear_section_folding() { editor_section_folding.clear(); }

#endif

// Used by script languages to store binding data.
Expand Down
19 changes: 19 additions & 0 deletions doc/classes/ResourceImporter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@
<tutorials>
<link title="Import plugins">$DOCS_URL/tutorials/plugins/editor/import_plugins.html</link>
</tutorials>
<methods>
<method name="_get_build_dependencies" qualifiers="virtual const">
<return type="PackedStringArray" />
<param index="0" name="path" type="String" />
<description>
Called when the engine compilation profile editor wants to check what build options an imported resource needs. For example, [ResourceImporterDynamicFont] has a property called [member ResourceImporterDynamicFont.multichannel_signed_distance_field], that depends on the engine to be build with the "msdfgen" module. If that resource happened to be a custom one, it would be handled like this:
[codeblock]
func _get_build_dependencies(path):
var resource = load(path)
var dependencies = PackedStringArray()

if resource.multichannel_signed_distance_field:
dependencies.push_back("module_msdfgen_enabled")

return dependencies
[/codeblock]
</description>
</method>
</methods>
<constants>
<constant name="IMPORT_ORDER_DEFAULT" value="0" enum="ImportOrder">
The default import order.
Expand Down
Loading