diff --git a/.changeset/forty-dancers-obey.md b/.changeset/forty-dancers-obey.md new file mode 100644 index 00000000..7d4ae14b --- /dev/null +++ b/.changeset/forty-dancers-obey.md @@ -0,0 +1,5 @@ +--- +"@godot-js/editor": minor +--- + +feat: Add ability to filter files for generating resources dts and scene dts. diff --git a/internal/jsb_settings.cpp b/internal/jsb_settings.cpp index 11e64850..bfe4aa34 100644 --- a/internal/jsb_settings.cpp +++ b/internal/jsb_settings.cpp @@ -38,6 +38,11 @@ namespace jsb::internal static constexpr char kRtPackagingIncludeDirectories[] = JSB_MODULE_NAME_STRING "/editor/packaging/include_directories"; static constexpr char kRtPackagingReferencedNodeModules[] = JSB_MODULE_NAME_STRING "/editor/packaging/referenced_node_modules"; + static constexpr char kRtResourceDTSIncludePathWildcards[] = JSB_MODULE_NAME_STRING "/codegen/resource_dts/include_path_wildcards"; + static constexpr char kRtResourceDTSExcludePathWildcards[] = JSB_MODULE_NAME_STRING "/codegen/resource_dts/exclude_path_wildcards"; + static constexpr char kRtSceneDTSIncludePathWildcards[] = JSB_MODULE_NAME_STRING "/codegen/scene_dts/include_path_wildcards"; + static constexpr char kRtSceneDTSExcludePathWildcards[] = JSB_MODULE_NAME_STRING "/codegen/scene_dts/exclude_path_wildcards"; + #ifdef TOOLS_ENABLED bool init_editor_settings() { @@ -124,6 +129,42 @@ namespace jsb::internal } _GLOBAL_DEF(kRtPackagingReferencedNodeModules, true, false); + + { + PropertyInfo ResourceDTSIncludePathWildcards; + ResourceDTSIncludePathWildcards.type = Variant::PACKED_STRING_ARRAY; + ResourceDTSIncludePathWildcards.name = kRtResourceDTSIncludePathWildcards; + ResourceDTSIncludePathWildcards.hint = PROPERTY_HINT_ARRAY_TYPE; + ResourceDTSIncludePathWildcards.hint_string = vformat("%s/%s:", Variant::STRING, PROPERTY_HINT_DIR); + _GLOBAL_DEF(ResourceDTSIncludePathWildcards, PackedStringArray{"res://"}, false, JSB_SET_IGNORE_DOCS(false), JSB_SET_BASIC(true), JSB_SET_INTERNAL(false)); + } + + { + PropertyInfo ResourceDTSExcludePathWildcards; + ResourceDTSExcludePathWildcards.type = Variant::PACKED_STRING_ARRAY; + ResourceDTSExcludePathWildcards.name = kRtResourceDTSExcludePathWildcards; + ResourceDTSExcludePathWildcards.hint = PROPERTY_HINT_ARRAY_TYPE; + ResourceDTSExcludePathWildcards.hint_string = vformat("%s/%s:", Variant::STRING, PROPERTY_HINT_DIR); + _GLOBAL_DEF(ResourceDTSExcludePathWildcards, PackedStringArray(), false, JSB_SET_IGNORE_DOCS(false), JSB_SET_BASIC(true), JSB_SET_INTERNAL(false)); + } + + { + PropertyInfo SceneDTSIncludePathWildcards; + SceneDTSIncludePathWildcards.type = Variant::PACKED_STRING_ARRAY; + SceneDTSIncludePathWildcards.name = kRtSceneDTSIncludePathWildcards; + SceneDTSIncludePathWildcards.hint = PROPERTY_HINT_ARRAY_TYPE; + SceneDTSIncludePathWildcards.hint_string = vformat("%s/%s:", Variant::STRING, PROPERTY_HINT_DIR); + _GLOBAL_DEF(SceneDTSIncludePathWildcards, PackedStringArray{"res://"}, false, JSB_SET_IGNORE_DOCS(false), JSB_SET_BASIC(true), JSB_SET_INTERNAL(false)); + } + + { + PropertyInfo SceneDTSExcludePathWildcards; + SceneDTSExcludePathWildcards.type = Variant::PACKED_STRING_ARRAY; + SceneDTSExcludePathWildcards.name = kRtSceneDTSExcludePathWildcards; + SceneDTSExcludePathWildcards.hint = PROPERTY_HINT_ARRAY_TYPE; + SceneDTSExcludePathWildcards.hint_string = vformat("%s/%s:", Variant::STRING, PROPERTY_HINT_DIR); + _GLOBAL_DEF(SceneDTSExcludePathWildcards, PackedStringArray(), false, JSB_SET_IGNORE_DOCS(false), JSB_SET_BASIC(true), JSB_SET_INTERNAL(false)); + } } } @@ -202,6 +243,30 @@ namespace jsb::internal return GLOBAL_GET(kRtPackagingReferencedNodeModules); } + PackedStringArray Settings::get_resource_dts_include_path_wildcards() + { + init_settings(); + return (PackedStringArray) GLOBAL_GET(kRtResourceDTSIncludePathWildcards); + } + + PackedStringArray Settings::get_resource_dts_exclude_path_wildcards() + { + init_settings(); + return (PackedStringArray) GLOBAL_GET(kRtResourceDTSExcludePathWildcards); + } + + PackedStringArray Settings::get_scene_dts_include_path_wildcards() + { + init_settings(); + return (PackedStringArray) GLOBAL_GET(kRtSceneDTSIncludePathWildcards); + } + + PackedStringArray Settings::get_scene_dts_exclude_path_wildcards() + { + init_settings(); + return (PackedStringArray) GLOBAL_GET(kRtSceneDTSExcludePathWildcards); + } + uint16_t Settings::get_debugger_port() { #ifdef TOOLS_ENABLED diff --git a/internal/jsb_settings.h b/internal/jsb_settings.h index bb84f4f6..050713a2 100644 --- a/internal/jsb_settings.h +++ b/internal/jsb_settings.h @@ -47,6 +47,11 @@ namespace jsb::internal static bool is_packaging_referenced_node_modules(); + static PackedStringArray get_resource_dts_include_path_wildcards(); + static PackedStringArray get_resource_dts_exclude_path_wildcards(); + static PackedStringArray get_scene_dts_include_path_wildcards(); + static PackedStringArray get_scene_dts_exclude_path_wildcards(); + #ifdef TOOLS_ENABLED // [EDITOR ONLY] static bool editor_settings_available(); diff --git a/weaver-editor/jsb_editor_plugin.cpp b/weaver-editor/jsb_editor_plugin.cpp index 4453b891..1c5ad4e4 100644 --- a/weaver-editor/jsb_editor_plugin.cpp +++ b/weaver-editor/jsb_editor_plugin.cpp @@ -492,6 +492,62 @@ void GodotJSEditorPlugin::_generate_imported_resource_dts(const Vector& generate_resource_types(p_resource); } +bool GodotJSEditorPlugin::_is_path_matchn(const PackedStringArray& p_wildcards, const String& p_path) +{ + for (const String& wildcard: p_wildcards) + { + if ((wildcard.contains_char('*') || wildcard.contains_char('?')) && p_path.match(wildcard)) + { + return true; + } + else + { + const String& lower_case_path = p_path.to_lower(); + String lower_case_wildcard = wildcard.to_lower(); + if (lower_case_path == lower_case_wildcard){ + return true; // Exact match file. + } + else + { + if (!lower_case_wildcard.ends_with("/")) + { + // Cheat as directory. + lower_case_wildcard += "/"; + } + + if (lower_case_path.begins_with(lower_case_wildcard)) + { + return true; // Match directory. + } + } + } + } + + return false; +} + +Vector GodotJSEditorPlugin::_filter_resource_paths(const PackedStringArray& p_exclude_wildcards, const PackedStringArray& p_include_wildcards, const Vector& p_paths) +{ + Vector filtered_paths; + if (!p_include_wildcards.is_empty()) + { + for (const String& path: p_paths) + { + if (!p_exclude_wildcards.is_empty() && _is_path_matchn(p_exclude_wildcards, path)) + { + continue; + } + + if (_is_path_matchn(p_include_wildcards, path)) + { + filtered_paths.push_back(path); + } + } + } + + return filtered_paths; +} + void GodotJSEditorPlugin::generate_godot_dts() { if (GodotJSEditorPlugin* editor_plugin = GodotJSEditorPlugin::get_singleton()) @@ -568,6 +624,14 @@ void GodotJSEditorPlugin::generate_scene_nodes_types(const Vector& p_pat return; } + PackedStringArray exclude_wildcards = jsb::internal::Settings::get_scene_dts_exclude_path_wildcards(); + PackedStringArray include_wildcards = jsb::internal::Settings::get_scene_dts_include_path_wildcards(); + Vector filtered_paths = _filter_resource_paths(exclude_wildcards, include_wildcards, p_paths); + if (filtered_paths.is_empty()) + { + return; + } + GodotJSScriptLanguage* lang = GodotJSScriptLanguage::get_singleton(); jsb_check(lang); Error err; @@ -575,7 +639,7 @@ void GodotJSEditorPlugin::generate_scene_nodes_types(const Vector& p_pat const String code = jsb_format( R"--((function(){const mod = require("jsb.editor.codegen"); (new mod.SceneTSDCodeGen("%s", ["%s"])).emit();})())--", "./" + jsb::internal::Settings::get_autogen_path(), - String("\", \"").join(p_paths) + String("\", \"").join(filtered_paths) ); lang->eval_source(code, err).ignore(); ERR_FAIL_COND_MSG(err != OK, "failed to evaluate jsb.editor.codegen"); @@ -591,6 +655,14 @@ void GodotJSEditorPlugin::generate_resource_types(const Vector& p_paths) return; } + PackedStringArray exclude_wildcards = jsb::internal::Settings::get_resource_dts_exclude_path_wildcards(); + PackedStringArray include_wildcards = jsb::internal::Settings::get_resource_dts_include_path_wildcards(); + Vector filtered_paths = _filter_resource_paths(exclude_wildcards, include_wildcards, p_paths); + if (filtered_paths.is_empty()) + { + return; + } + GodotJSScriptLanguage* lang = GodotJSScriptLanguage::get_singleton(); jsb_check(lang); Error err; @@ -598,7 +670,7 @@ void GodotJSEditorPlugin::generate_resource_types(const Vector& p_paths) const String code = jsb_format( R"--((function(){const mod = require("jsb.editor.codegen"); (new mod.ResourceTSDCodeGen("%s", ["%s"])).emit();})())--", "./" + jsb::internal::Settings::get_autogen_path(), - String("\", \"").join(p_paths) + String("\", \"").join(filtered_paths) ); lang->eval_source(code, err).ignore(); ERR_FAIL_COND_MSG(err != OK, "failed to evaluate jsb.editor.codegen"); diff --git a/weaver-editor/jsb_editor_plugin.h b/weaver-editor/jsb_editor_plugin.h index 836d44c5..0d98ba63 100644 --- a/weaver-editor/jsb_editor_plugin.h +++ b/weaver-editor/jsb_editor_plugin.h @@ -57,6 +57,9 @@ class GodotJSEditorPlugin : public EditorPlugin void _on_resource_saved(const Ref& p_resource); void _generate_imported_resource_dts(const Vector& p_resources); + static bool _is_path_matchn(const PackedStringArray& p_wildcards, const String& p_path); + static Vector _filter_resource_paths(const PackedStringArray& p_exclude_wildcards, const PackedStringArray& p_include_wildcards, const Vector& p_paths); + protected: static void _bind_methods();