Merge pull request #53296 from lawnjelly/project_settings_dirty_flag
This commit is contained in:
commit
43dfafdfc9
8 changed files with 132 additions and 36 deletions
|
@ -165,9 +165,26 @@ String ProjectSettings::globalize_path(const String &p_path) const {
|
||||||
return p_path;
|
return p_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectSettings::update() {
|
||||||
|
if (_dirty_this_frame) {
|
||||||
|
// A signal is sent a single time at the end of the frame when project settings
|
||||||
|
// are changed. This allows objects to respond.
|
||||||
|
// Alternatively objects outside the signal system can query ProjectSettings::has_changes()
|
||||||
|
if (_dirty_this_frame == 2) {
|
||||||
|
emit_signal("project_settings_changed");
|
||||||
|
}
|
||||||
|
|
||||||
|
_dirty_this_frame--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
|
bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
// marking the project settings as dirty allows them only to be
|
||||||
|
// checked when dirty.
|
||||||
|
_dirty_this_frame = 2;
|
||||||
|
|
||||||
if (p_value.get_type() == Variant::NIL) {
|
if (p_value.get_type() == Variant::NIL) {
|
||||||
props.erase(p_name);
|
props.erase(p_name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1022,6 +1039,8 @@ void ProjectSettings::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert);
|
ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);
|
ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);
|
||||||
|
|
||||||
|
ADD_SIGNAL(MethodInfo("project_settings_changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectSettings::ProjectSettings() {
|
ProjectSettings::ProjectSettings() {
|
||||||
|
|
|
@ -35,10 +35,37 @@
|
||||||
#include "core/os/thread_safe.h"
|
#include "core/os/thread_safe.h"
|
||||||
#include "core/set.h"
|
#include "core/set.h"
|
||||||
|
|
||||||
|
// Querying ProjectSettings is usually done at startup.
|
||||||
|
// Additionally, in order to keep track of changes to ProjectSettings,
|
||||||
|
// instead of Querying all the strings every frame just in case of changes,
|
||||||
|
// there is a signal "project_settings_changed" which objects can subscribe to.
|
||||||
|
|
||||||
|
// E.g. (from another Godot object)
|
||||||
|
// // Call your user written object function to Query the project settings once at creation,
|
||||||
|
// perhaps in an ENTER_TREE notification:
|
||||||
|
// _project_settings_changed()
|
||||||
|
// // Then connect your function to the signal so it is called every time something changes in future:
|
||||||
|
// ProjectSettings::get_singleton()->connect("project_settings_changed", this, "_project_settings_changed");
|
||||||
|
|
||||||
|
// Where for example your function may take the form:
|
||||||
|
// void _project_settings_changed() {
|
||||||
|
// _shadowmap_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// You may want to also disconnect from the signal in EXIT_TREE notification, if your object may be deleted
|
||||||
|
// before ProjectSettings:
|
||||||
|
// ProjectSettings::get_singleton()->disconnect("project_settings_changed", this, "_project_settings_changed");
|
||||||
|
|
||||||
|
// Additionally, for objects that are not regular Godot objects capable of subscribing to signals (e.g. Rasterizers),
|
||||||
|
// you can also query the function "has_changes()" each frame,
|
||||||
|
// and update your local settings whenever this is set.
|
||||||
|
|
||||||
class ProjectSettings : public Object {
|
class ProjectSettings : public Object {
|
||||||
GDCLASS(ProjectSettings, Object);
|
GDCLASS(ProjectSettings, Object);
|
||||||
_THREAD_SAFE_CLASS_
|
_THREAD_SAFE_CLASS_
|
||||||
|
|
||||||
|
int _dirty_this_frame = 2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Map<String, Variant> CustomMap;
|
typedef Map<String, Variant> CustomMap;
|
||||||
static const String PROJECT_DATA_DIR_NAME_SUFFIX;
|
static const String PROJECT_DATA_DIR_NAME_SUFFIX;
|
||||||
|
@ -168,6 +195,14 @@ public:
|
||||||
|
|
||||||
bool has_custom_feature(const String &p_feature) const;
|
bool has_custom_feature(const String &p_feature) const;
|
||||||
|
|
||||||
|
// Either use the signal `project_settings_changed` or query this function.
|
||||||
|
// N.B. _dirty_this_frame is set initially to 2.
|
||||||
|
// This is to cope with the situation where a project setting is changed in the iteration AFTER it is read.
|
||||||
|
// There is therefore the potential for a change to be missed. Persisting the counter
|
||||||
|
// for two frames avoids this, at the cost of a frame delay.
|
||||||
|
bool has_changes() const { return _dirty_this_frame == 1; }
|
||||||
|
void update();
|
||||||
|
|
||||||
ProjectSettings();
|
ProjectSettings();
|
||||||
~ProjectSettings();
|
~ProjectSettings();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1569,6 +1569,13 @@
|
||||||
Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses (in pixels).
|
Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses (in pixels).
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
|
<signals>
|
||||||
|
<signal name="project_settings_changed">
|
||||||
|
<description>
|
||||||
|
Objects can use this signal to restrict reading of settings only to situations where a change has been made.
|
||||||
|
</description>
|
||||||
|
</signal>
|
||||||
|
</signals>
|
||||||
<constants>
|
<constants>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -99,8 +99,8 @@ void ImportDefaultsEditor::_save() {
|
||||||
} else {
|
} else {
|
||||||
ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), Variant());
|
ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), Variant());
|
||||||
}
|
}
|
||||||
|
// Calling ProjectSettings::set() causes the signal "project_settings_changed" to be sent to ProjectSettings.
|
||||||
emit_signal("project_settings_changed");
|
// ProjectSettingsEditor subscribes to this and can reads the settings updated here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2462,6 +2462,49 @@ void SpatialEditorPlugin::edited_scene_changed() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpatialEditorViewport::_project_settings_changed() {
|
||||||
|
if (viewport) {
|
||||||
|
_project_settings_change_pending = false;
|
||||||
|
|
||||||
|
//update shadow atlas if changed
|
||||||
|
int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size");
|
||||||
|
int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
|
||||||
|
int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
|
||||||
|
int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
|
||||||
|
int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
|
||||||
|
|
||||||
|
viewport->set_shadow_atlas_size(shadowmap_size);
|
||||||
|
viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
|
||||||
|
viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
|
||||||
|
viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
|
||||||
|
viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
|
||||||
|
|
||||||
|
// Update MSAA, FXAA, debanding and HDR if changed.
|
||||||
|
int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/filters/msaa");
|
||||||
|
viewport->set_msaa(Viewport::MSAA(msaa_mode));
|
||||||
|
|
||||||
|
bool use_fxaa = ProjectSettings::get_singleton()->get("rendering/quality/filters/use_fxaa");
|
||||||
|
viewport->set_use_fxaa(use_fxaa);
|
||||||
|
|
||||||
|
bool use_debanding = ProjectSettings::get_singleton()->get("rendering/quality/filters/use_debanding");
|
||||||
|
viewport->set_use_debanding(use_debanding);
|
||||||
|
|
||||||
|
float sharpen_intensity = ProjectSettings::get_singleton()->get("rendering/quality/filters/sharpen_intensity");
|
||||||
|
viewport->set_sharpen_intensity(sharpen_intensity);
|
||||||
|
|
||||||
|
bool hdr = ProjectSettings::get_singleton()->get("rendering/quality/depth/hdr");
|
||||||
|
viewport->set_hdr(hdr);
|
||||||
|
|
||||||
|
const bool use_32_bpc_depth = ProjectSettings::get_singleton()->get("rendering/quality/depth/use_32_bpc_depth");
|
||||||
|
viewport->set_use_32_bpc_depth(use_32_bpc_depth);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Could not update immediately, set a pending update.
|
||||||
|
// This may never happen, but is included for safety
|
||||||
|
_project_settings_change_pending = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SpatialEditorViewport::_notification(int p_what) {
|
void SpatialEditorViewport::_notification(int p_what) {
|
||||||
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||||
bool visible = is_visible_in_tree();
|
bool visible = is_visible_in_tree();
|
||||||
|
@ -2583,19 +2626,9 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//update shadow atlas if changed
|
if (_project_settings_change_pending) {
|
||||||
|
_project_settings_changed();
|
||||||
int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size");
|
}
|
||||||
int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
|
|
||||||
int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
|
|
||||||
int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
|
|
||||||
int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
|
|
||||||
|
|
||||||
viewport->set_shadow_atlas_size(shadowmap_size);
|
|
||||||
viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
|
|
||||||
viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
|
|
||||||
viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
|
|
||||||
viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
|
|
||||||
|
|
||||||
bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION));
|
bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION));
|
||||||
|
|
||||||
|
@ -2603,26 +2636,6 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
viewport_container->set_stretch_shrink(shrink ? 2 : 1);
|
viewport_container->set_stretch_shrink(shrink ? 2 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update MSAA, FXAA, debanding and HDR if changed.
|
|
||||||
|
|
||||||
int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/filters/msaa");
|
|
||||||
viewport->set_msaa(Viewport::MSAA(msaa_mode));
|
|
||||||
|
|
||||||
bool use_fxaa = ProjectSettings::get_singleton()->get("rendering/quality/filters/use_fxaa");
|
|
||||||
viewport->set_use_fxaa(use_fxaa);
|
|
||||||
|
|
||||||
bool use_debanding = ProjectSettings::get_singleton()->get("rendering/quality/filters/use_debanding");
|
|
||||||
viewport->set_use_debanding(use_debanding);
|
|
||||||
|
|
||||||
float sharpen_intensity = ProjectSettings::get_singleton()->get("rendering/quality/filters/sharpen_intensity");
|
|
||||||
viewport->set_sharpen_intensity(sharpen_intensity);
|
|
||||||
|
|
||||||
const bool hdr = ProjectSettings::get_singleton()->get("rendering/quality/depth/hdr");
|
|
||||||
viewport->set_hdr(hdr);
|
|
||||||
|
|
||||||
const bool use_32_bpc_depth = ProjectSettings::get_singleton()->get("rendering/quality/depth/use_32_bpc_depth");
|
|
||||||
viewport->set_use_32_bpc_depth(use_32_bpc_depth);
|
|
||||||
|
|
||||||
bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
|
bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
|
||||||
info_label->set_visible(show_info);
|
info_label->set_visible(show_info);
|
||||||
|
|
||||||
|
@ -2689,10 +2702,17 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||||
surface->connect("focus_entered", this, "_surface_focus_enter");
|
surface->connect("focus_entered", this, "_surface_focus_enter");
|
||||||
surface->connect("focus_exited", this, "_surface_focus_exit");
|
surface->connect("focus_exited", this, "_surface_focus_exit");
|
||||||
|
|
||||||
|
// Ensure we are up to date with project settings
|
||||||
|
_project_settings_changed();
|
||||||
|
|
||||||
|
// Any further changes to project settings get a signal
|
||||||
|
ProjectSettings::get_singleton()->connect("project_settings_changed", this, "_project_settings_changed");
|
||||||
|
|
||||||
_init_gizmo_instance(index);
|
_init_gizmo_instance(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||||
|
ProjectSettings::get_singleton()->disconnect("project_settings_changed", this, "_project_settings_changed");
|
||||||
_finish_gizmo_instances();
|
_finish_gizmo_instances();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3582,6 +3602,7 @@ void SpatialEditorViewport::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &SpatialEditorViewport::_selection_menu_hide);
|
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &SpatialEditorViewport::_selection_menu_hide);
|
||||||
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpatialEditorViewport::can_drop_data_fw);
|
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpatialEditorViewport::can_drop_data_fw);
|
||||||
ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw);
|
ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw);
|
||||||
|
ClassDB::bind_method(D_METHOD("_project_settings_changed"), &SpatialEditorViewport::_project_settings_changed);
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")));
|
ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")));
|
||||||
ADD_SIGNAL(MethodInfo("clicked", PropertyInfo(Variant::OBJECT, "viewport")));
|
ADD_SIGNAL(MethodInfo("clicked", PropertyInfo(Variant::OBJECT, "viewport")));
|
||||||
|
@ -4104,6 +4125,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
||||||
gizmo_scale = 1.0;
|
gizmo_scale = 1.0;
|
||||||
|
|
||||||
preview_node = nullptr;
|
preview_node = nullptr;
|
||||||
|
_project_settings_change_pending = false;
|
||||||
|
|
||||||
info_label = memnew(Label);
|
info_label = memnew(Label);
|
||||||
info_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE);
|
info_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE);
|
||||||
|
|
|
@ -243,6 +243,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int index;
|
int index;
|
||||||
|
bool _project_settings_change_pending;
|
||||||
ViewType view_type;
|
ViewType view_type;
|
||||||
void _menu_option(int p_option);
|
void _menu_option(int p_option);
|
||||||
void _set_auto_orthogonal();
|
void _set_auto_orthogonal();
|
||||||
|
@ -458,6 +459,8 @@ private:
|
||||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||||
|
|
||||||
|
void _project_settings_changed();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
|
@ -143,7 +143,16 @@ void ProjectSettingsEditor::_notification(int p_what) {
|
||||||
restart_icon->set_texture(get_icon("StatusWarning", "EditorIcons"));
|
restart_icon->set_texture(get_icon("StatusWarning", "EditorIcons"));
|
||||||
restart_label->add_color_override("font_color", get_color("warning_color", "Editor"));
|
restart_label->add_color_override("font_color", get_color("warning_color", "Editor"));
|
||||||
|
|
||||||
|
// The ImportDefaultsEditor changes settings which must be read by this object when changed
|
||||||
|
ProjectSettings::get_singleton()->connect("project_settings_changed", this, "_settings_changed");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
if (ProjectSettings::get_singleton()) {
|
||||||
|
ProjectSettings::get_singleton()->disconnect("project_settings_changed", this, "_settings_changed");
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_POPUP_HIDE: {
|
case NOTIFICATION_POPUP_HIDE: {
|
||||||
EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "project_settings", get_rect());
|
EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "project_settings", get_rect());
|
||||||
set_process_unhandled_input(false);
|
set_process_unhandled_input(false);
|
||||||
|
@ -2141,7 +2150,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
|
||||||
import_defaults_editor = memnew(ImportDefaultsEditor);
|
import_defaults_editor = memnew(ImportDefaultsEditor);
|
||||||
import_defaults_editor->set_name(TTR("Import Defaults"));
|
import_defaults_editor->set_name(TTR("Import Defaults"));
|
||||||
tab_container->add_child(import_defaults_editor);
|
tab_container->add_child(import_defaults_editor);
|
||||||
import_defaults_editor->connect("project_settings_changed", this, "_settings_changed");
|
|
||||||
|
|
||||||
timer = memnew(Timer);
|
timer = memnew(Timer);
|
||||||
timer->set_wait_time(1.5);
|
timer->set_wait_time(1.5);
|
||||||
|
|
|
@ -589,6 +589,8 @@ bool SceneTree::idle(float p_time) {
|
||||||
|
|
||||||
_call_idle_callbacks();
|
_call_idle_callbacks();
|
||||||
|
|
||||||
|
ProjectSettings::get_singleton()->update();
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
|
Loading…
Reference in a new issue