Skip to content

Commit 33df712

Browse files
committed
Merge pull request #109999 from aaronfranke/shader-cleanup
Clean up some things in shader editor code
2 parents 08db7dd + e26e96d commit 33df712

File tree

5 files changed

+56
-33
lines changed

5 files changed

+56
-33
lines changed

editor/shader/shader_create_dialog.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,36 +67,45 @@ void ShaderCreateDialog::_notification(int p_what) {
6767
} break;
6868

6969
case NOTIFICATION_THEME_CHANGED: {
70-
static const char *shader_types[3] = { "Shader", "VisualShader", "TextFile" };
71-
for (int i = 0; i < 3; i++) {
72-
Ref<Texture2D> icon = get_editor_theme_icon(shader_types[i]);
73-
if (icon.is_valid()) {
74-
type_menu->set_item_icon(i, icon);
75-
}
76-
}
77-
70+
_refresh_type_icons();
7871
path_button->set_button_icon(get_editor_theme_icon(SNAME("Folder")));
7972
} break;
8073
}
8174
}
8275

76+
void ShaderCreateDialog::_refresh_type_icons() {
77+
for (int i = 0; i < type_menu->get_item_count(); i++) {
78+
const String item_name = type_menu->get_item_text(i);
79+
Ref<Texture2D> icon = get_editor_theme_icon(item_name);
80+
if (icon.is_valid()) {
81+
type_menu->set_item_icon(i, icon);
82+
} else {
83+
icon = get_editor_theme_icon("TextFile");
84+
if (icon.is_valid()) {
85+
type_menu->set_item_icon(i, icon);
86+
}
87+
}
88+
}
89+
}
90+
8391
void ShaderCreateDialog::_update_language_info() {
8492
type_data.clear();
8593

8694
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
8795
ShaderTypeData shader_type_data;
8896
if (i == int(SHADER_TYPE_TEXT)) {
8997
shader_type_data.use_templates = true;
90-
shader_type_data.extensions.push_back("gdshader");
9198
shader_type_data.default_extension = "gdshader";
9299
} else if (i == int(SHADER_TYPE_INC)) {
93-
shader_type_data.extensions.push_back("gdshaderinc");
94100
shader_type_data.default_extension = "gdshaderinc";
95101
} else {
96102
shader_type_data.default_extension = "tres";
97103
}
104+
shader_type_data.extensions.push_back(shader_type_data.default_extension);
105+
if (shader_type_data.default_extension != "tres") {
106+
shader_type_data.extensions.push_back("tres");
107+
}
98108
shader_type_data.extensions.push_back("res");
99-
shader_type_data.extensions.push_back("tres");
100109
type_data.push_back(shader_type_data);
101110
}
102111
}
@@ -432,31 +441,33 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl
432441
}
433442

434443
String ShaderCreateDialog::_validate_path(const String &p_path) {
435-
String p = p_path.strip_edges();
444+
ERR_FAIL_COND_V(current_type >= type_data.size(), TTR("Invalid shader type selected."));
445+
String stripped_file_path = p_path.strip_edges();
436446

437-
if (p.is_empty()) {
447+
if (stripped_file_path.is_empty()) {
438448
return TTR("Path is empty.");
439449
}
440-
if (p.get_file().get_basename().is_empty()) {
450+
if (stripped_file_path.get_file().get_basename().is_empty()) {
441451
return TTR("Filename is empty.");
442452
}
443453

444-
p = ProjectSettings::get_singleton()->localize_path(p);
445-
if (!p.begins_with("res://")) {
454+
stripped_file_path = ProjectSettings::get_singleton()->localize_path(stripped_file_path);
455+
if (!stripped_file_path.begins_with("res://")) {
446456
return TTR("Path is not local.");
447457
}
448458

449459
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
450-
if (d->change_dir(p.get_base_dir()) != OK) {
460+
if (d->change_dir(stripped_file_path.get_base_dir()) != OK) {
451461
return TTR("Invalid base path.");
452462
}
453463

454464
Ref<DirAccess> f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
455-
if (f->dir_exists(p)) {
465+
if (f->dir_exists(stripped_file_path)) {
456466
return TTR("A directory with the same name exists.");
457467
}
458468

459-
String extension = p.get_extension();
469+
const ShaderCreateDialog::ShaderTypeData &current_type_data = type_data.get(current_type);
470+
const String file_extension = stripped_file_path.get_extension();
460471
HashSet<String> extensions;
461472

462473
List<ShaderCreateDialog::ShaderTypeData>::ConstIterator itr = type_data.begin();
@@ -472,10 +483,10 @@ String ShaderCreateDialog::_validate_path(const String &p_path) {
472483
bool match = false;
473484

474485
for (const String &ext : extensions) {
475-
if (ext.nocasecmp_to(extension) == 0) {
486+
if (ext.nocasecmp_to(file_extension) == 0) {
476487
found = true;
477-
for (const String &type_ext : type_data.get(current_type).extensions) {
478-
if (type_ext.nocasecmp_to(extension) == 0) {
488+
for (const String &type_ext : current_type_data.extensions) {
489+
if (type_ext.nocasecmp_to(file_extension) == 0) {
479490
match = true;
480491
break;
481492
}

editor/shader/shader_create_dialog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class ShaderCreateDialog : public ConfirmationDialog {
9393
void _mode_changed(int p_mode = 0);
9494
void _browse_path();
9595
void _file_selected(const String &p_file);
96+
void _refresh_type_icons();
9697
String _validate_path(const String &p_path);
9798
virtual void ok_pressed() override;
9899
void _create_new();

editor/shader/shader_editor_plugin.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,33 +137,37 @@ void ShaderEditorPlugin::edit(Object *p_object) {
137137
if (!p_object) {
138138
return;
139139
}
140-
141140
EditedShader es;
142-
143-
ShaderInclude *si = Object::cast_to<ShaderInclude>(p_object);
144-
if (si != nullptr) {
141+
// First, check for ShaderInclude.
142+
ShaderInclude *shader_include = Object::cast_to<ShaderInclude>(p_object);
143+
if (shader_include != nullptr) {
144+
// Check if this shader include is already being edited.
145145
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
146-
if (edited_shaders[i].shader_inc.ptr() == si) {
146+
if (edited_shaders[i].shader_inc.ptr() == shader_include) {
147147
shader_tabs->set_current_tab(i);
148148
shader_list->select(i);
149149
_switch_to_editor(edited_shaders[i].shader_editor);
150150
return;
151151
}
152152
}
153-
es.shader_inc = Ref<ShaderInclude>(si);
153+
es.shader_inc = Ref<ShaderInclude>(shader_include);
154154
es.shader_editor = memnew(TextShaderEditor);
155-
es.shader_editor->edit_shader_include(si);
155+
es.shader_editor->edit_shader_include(shader_include);
156156
} else {
157-
Shader *s = Object::cast_to<Shader>(p_object);
157+
// If it's not a ShaderInclude, check for Shader.
158+
Shader *shader = Object::cast_to<Shader>(p_object);
159+
ERR_FAIL_NULL_MSG(shader, "ShaderEditorPlugin: Unable to edit object " + p_object->to_string() + " because it is not a Shader or ShaderInclude.");
160+
// Check if this shader is already being edited.
158161
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
159-
if (edited_shaders[i].shader.ptr() == s) {
162+
if (edited_shaders[i].shader.ptr() == shader) {
160163
shader_tabs->set_current_tab(i);
161164
shader_list->select(i);
162165
_switch_to_editor(edited_shaders[i].shader_editor);
163166
return;
164167
}
165168
}
166-
es.shader = Ref<Shader>(s);
169+
// If we did not return, the shader needs to be opened in a new shader editor.
170+
es.shader = Ref<Shader>(shader);
167171
Ref<VisualShader> vs = es.shader;
168172
if (vs.is_valid()) {
169173
es.shader_editor = memnew(VisualShaderEditor);
@@ -173,6 +177,7 @@ void ShaderEditorPlugin::edit(Object *p_object) {
173177
es.shader_editor->edit_shader(es.shader);
174178
}
175179

180+
// TextShaderEditor-specific setup code.
176181
TextShaderEditor *text_shader_editor = Object::cast_to<TextShaderEditor>(es.shader_editor);
177182
if (text_shader_editor) {
178183
text_shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list));
@@ -434,7 +439,7 @@ void ShaderEditorPlugin::_make_script_list_context_menu() {
434439
}
435440

436441
Control *control = shader_tabs->get_tab_control(selected);
437-
bool is_valid_editor_control = Object::cast_to<TextShaderEditor>(control) || Object::cast_to<VisualShaderEditor>(control);
442+
bool is_valid_editor_control = Object::cast_to<ShaderEditor>(control) != nullptr;
438443

439444
_setup_popup_menu(is_valid_editor_control ? CONTEXT_VALID_ITEM : CONTEXT, context_menu);
440445

@@ -774,6 +779,7 @@ void ShaderEditorPlugin::_update_shader_editor_zoom_factor(CodeTextEditor *p_sha
774779
}
775780

776781
void ShaderEditorPlugin::_switch_to_editor(ShaderEditor *p_editor) {
782+
ERR_FAIL_NULL(p_editor);
777783
if (file_menu->get_parent() != nullptr) {
778784
file_menu->get_parent()->remove_child(file_menu);
779785
}

scene/resources/shader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Shader : public Resource {
4141
OBJ_SAVE_TYPE(Shader);
4242

4343
public:
44+
// Must be kept in sync with the List<String> of shader types in `servers/rendering/shader_types.cpp`.
4445
enum Mode {
4546
MODE_SPATIAL,
4647
MODE_CANVAS_ITEM,

servers/rendering/shader_types.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
#include "shader_types.h"
3232

33+
#include "scene/resources/shader.h"
34+
3335
const HashMap<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) const {
3436
return shader_modes[p_mode].functions;
3537
}
@@ -516,11 +518,13 @@ ShaderTypes::ShaderTypes() {
516518
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3;
517519
shader_modes[RS::SHADER_FOG].functions["fog"].main_function = true;
518520

521+
// Must be kept in sync with the Shader::Mode enum.
519522
shader_types_list.push_back("spatial");
520523
shader_types_list.push_back("canvas_item");
521524
shader_types_list.push_back("particles");
522525
shader_types_list.push_back("sky");
523526
shader_types_list.push_back("fog");
527+
DEV_ASSERT(shader_types_list.size() == Shader::MODE_MAX);
524528

525529
for (const String &type : shader_types_list) {
526530
shader_types.insert(type);

0 commit comments

Comments
 (0)