Skip to content

Commit

Permalink
Rework the Configuration Warning system
Browse files Browse the repository at this point in the history
- Introduces the new configuration info system.
- Supported on Node and Resource.
- Different severity levels, can be on properties.
- Show summary of config info at the top of the inspector.
- Backwards compatible API (configuration warnings API still works,
  although it is marked as deprecated).
  • Loading branch information
RedMser committed Sep 9, 2024
1 parent d0dc389 commit 5dd20e8
Show file tree
Hide file tree
Showing 35 changed files with 865 additions and 88 deletions.
35 changes: 28 additions & 7 deletions core/io/resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
#include "core/os/os.h"
#include "scene/main/node.h" //only so casting works

#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
#include "editor/editor_string_names.h"
#endif // TOOLS_ENABLED

#include <stdio.h>

void Resource::emit_changed() {
Expand Down Expand Up @@ -155,12 +160,6 @@ String Resource::get_name() const {
return name;
}

void Resource::update_configuration_warning() {
if (_update_configuration_warning) {
_update_configuration_warning();
}
}

bool Resource::editor_can_reload_from_file() {
return true; //by default yes
}
Expand Down Expand Up @@ -479,7 +478,6 @@ void Resource::reset_local_to_scene() {
}

Node *(*Resource::_get_local_scene_func)() = nullptr;
void (*Resource::_update_configuration_warning)() = nullptr;

void Resource::set_as_translation_remapped(bool p_remapped) {
if (remapped_list.in_list() == p_remapped) {
Expand Down Expand Up @@ -522,6 +520,27 @@ String Resource::get_id_for_path(const String &p_path) const {
}
#endif

#ifdef TOOLS_ENABLED
Array Resource::get_configuration_info() const {
Array ret;

Array info;
if (GDVIRTUAL_CALL(_get_configuration_info, info)) {
ret.append_array(info);
}

return ret;
}
#endif

void Resource::update_configuration_info() {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
EditorNode::get_singleton()->emit_signal(EditorStringName(configuration_info_changed), this);
}
#endif
}

void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path);
ClassDB::bind_method(D_METHOD("take_over_path", "path"), &Resource::_take_over_path);
Expand All @@ -537,6 +556,7 @@ void Resource::_bind_methods() {
ClassDB::bind_static_method("Resource", D_METHOD("generate_scene_unique_id"), &Resource::generate_scene_unique_id);
ClassDB::bind_method(D_METHOD("set_scene_unique_id", "id"), &Resource::set_scene_unique_id);
ClassDB::bind_method(D_METHOD("get_scene_unique_id"), &Resource::get_scene_unique_id);
ClassDB::bind_method(D_METHOD("update_configuration_info"), &Resource::update_configuration_info);

ClassDB::bind_method(D_METHOD("emit_changed"), &Resource::emit_changed);

Expand All @@ -552,6 +572,7 @@ void Resource::_bind_methods() {

GDVIRTUAL_BIND(_setup_local_to_scene);
GDVIRTUAL_BIND(_get_rid);
GDVIRTUAL_BIND(_get_configuration_info);
}

Resource::Resource() :
Expand Down
7 changes: 5 additions & 2 deletions core/io/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,13 @@ class Resource : public RefCounted {

virtual void reset_local_to_scene();
GDVIRTUAL0(_setup_local_to_scene);
GDVIRTUAL0RC(Array, _get_configuration_info);

GDVIRTUAL0RC(RID, _get_rid);

public:
static Node *(*_get_local_scene_func)(); //used by editor
static void (*_update_configuration_warning)(); //used by editor

void update_configuration_warning();
virtual bool editor_can_reload_from_file();
virtual void reset_state(); //for resources that use variable amount of properties, either via _validate_property or _get_property_list, this function needs to be implemented to correctly clear state
virtual Error copy_from(const Ref<Resource> &p_resource);
Expand Down Expand Up @@ -148,8 +147,12 @@ class Resource : public RefCounted {
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void set_id_for_path(const String &p_path, const String &p_id);
String get_id_for_path(const String &p_path) const;

virtual Array get_configuration_info() const;
#endif

void update_configuration_info();

Resource();
~Resource();
};
Expand Down
8 changes: 8 additions & 0 deletions core/string/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6096,3 +6096,11 @@ String RTRN(const String &p_text, const String &p_text_plural, int p_n, const St
}
return p_text_plural;
}

Dictionary _make_configuration_info(const String &p_message, const String &p_property_name, const String &p_severity) {
Dictionary config_info;
config_info["message"] = p_message;
config_info["property"] = p_property_name;
config_info["severity"] = p_severity;
return config_info;
}
11 changes: 11 additions & 0 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "core/templates/vector.h"
#include "core/typedefs.h"
#include "core/variant/array.h"
#include "core/variant/dictionary.h"

/*************************************************************************/
/* CharProxy */
Expand Down Expand Up @@ -623,6 +624,16 @@ _FORCE_INLINE_ String ETRN(const String &p_text, const String &p_text_plural, in
return p_text_plural;
}

// Internal function for configuration info macros.
Dictionary _make_configuration_info(const String &p_message, const String &p_property_name, const String &p_severity);

#define CONFIG_INFO(message) warnings.push_back(_make_configuration_info(message, "", "info"));
#define CONFIG_INFO_P(message, property_name) warnings.push_back(_make_configuration_info(message, property_name, "info"));
#define CONFIG_WARNING(message) warnings.push_back(_make_configuration_info(message, "", "warning"));
#define CONFIG_WARNING_P(message, property_name) warnings.push_back(_make_configuration_info(message, property_name, "warning"));
#define CONFIG_ERROR(message) warnings.push_back(_make_configuration_info(message, "", "error"));
#define CONFIG_ERROR_P(message, property_name) warnings.push_back(_make_configuration_info(message, property_name, "error"));

bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);

_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) {
Expand Down
1 change: 1 addition & 0 deletions core/variant/dictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "dictionary.h"

#include "core/string/ustring.h"
#include "core/templates/hash_map.h"
#include "core/templates/safe_refcount.h"
#include "core/variant/container_type_validate.h"
Expand Down
1 change: 0 additions & 1 deletion core/variant/dictionary.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H

#include "core/string/ustring.h"
#include "core/templates/list.h"
#include "core/variant/array.h"

Expand Down
3 changes: 3 additions & 0 deletions doc/classes/EditorProperty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
<member name="checked" type="bool" setter="set_checked" getter="is_checked" default="false">
Used by the inspector, set to [code]true[/code] when the property is checked.
</member>
<member name="config_info" type="Array" setter="set_config_info" getter="get_config_info" default="[]">
Used by the inspector, set to show a list of configuration info on the property.
</member>
<member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false">
Used by the inspector, set to [code]true[/code] when the property can be deleted by the user.
</member>
Expand Down
42 changes: 40 additions & 2 deletions doc/classes/Node.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,39 @@
Corresponds to the [constant NOTIFICATION_EXIT_TREE] notification in [method Object._notification] and signal [signal tree_exiting]. To get notified when the node has already left the active tree, connect to the [signal tree_exited].
</description>
</method>
<method name="_get_configuration_warnings" qualifiers="virtual const">
<method name="_get_configuration_info" qualifiers="virtual const">
<return type="Array" />
<description>
Override this method to inform the user about the configuration of this node.
Call [method update_configuration_info] when the messages need to be updated for this node.
The elements in the array returned from this method are displayed at the top of the Inspector dock, as well as an icon in the Scene dock. The script that overrides it must be a [code]tool[/code] script.
Each array element must either be a [String] or a [Dictionary].
A dictionary element must contain a key [code]message[/code] of type [String] which is shown in the user interface. Following optional keys are supported:
- [code]property[/code] of type [String], which adds an icon next to the property with the same name.
- [code]severity[/code] can be set to [code]"error"[/code], [code]"warning"[/code], or [code]"info"[/code] to change the icon and text color. Defaults to warning.
If a string is found in the returned array, it is treated as a warning message with no property set.
Returning an empty array produces no messages.
[codeblock]
@tool
extends Node

@export var energy = 0:
set(value):
energy = value
update_configuration_info()

func _get_configuration_info():
if energy &lt; 0:
return [{
"property": "energy",
"message": "Energy must be 0 or greater."
}]
else:
return []
[/codeblock]
</description>
</method>
<method name="_get_configuration_warnings" qualifiers="virtual const" deprecated="Use [method _get_configuration_info] instead.">
<return type="PackedStringArray" />
<description>
The elements in the array returned from this method are displayed as warnings in the Scene dock if the script that overrides it is a [code]tool[/code] script.
Expand Down Expand Up @@ -967,7 +999,13 @@
Similar to [method call_thread_safe], but for setting properties.
</description>
</method>
<method name="update_configuration_warnings">
<method name="update_configuration_info">
<return type="void" />
<description>
Refreshes the configuration information displayed for this node in the Scene dock and Inspector dock. Use [method _get_configuration_info] to customize the messages to display.
</description>
</method>
<method name="update_configuration_warnings" deprecated="Use [method update_configuration_info] instead.">
<return type="void" />
<description>
Refreshes the warnings displayed for this node in the Scene dock. Use [method _get_configuration_warnings] to customize the warning messages to display.
Expand Down
38 changes: 38 additions & 0 deletions doc/classes/Resource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,38 @@
<link title="When and how to avoid using nodes for everything">$DOCS_URL/tutorials/best_practices/node_alternatives.html</link>
</tutorials>
<methods>
<method name="_get_configuration_info" qualifiers="virtual const">
<return type="Array" />
<description>
Override this method to inform the user about the configuration of this resource.
Call [method update_configuration_info] when the messages need to be updated for this resource.
The elements in the array returned from this method are displayed at the top of the Inspector dock. The script that overrides it must be a [code]tool[/code] script.
Each array element must either be a [String] or a [Dictionary].
A dictionary element must contain a key [code]message[/code] of type [String] which is shown in the user interface. Following optional keys are supported:
- [code]property[/code] of type [String], which adds an icon next to the property with the same name.
- [code]severity[/code] can be set to [code]"error"[/code], [code]"warning"[/code], or [code]"info"[/code] to change the icon and text color. Defaults to warning.
If a string is found in the returned array, it is treated as a warning message with no property set.
Returning an empty array produces no messages.
[codeblock]
@tool
extends Resource

@export var energy = 0:
set(value):
energy = value
update_configuration_info()

func _get_configuration_info():
if energy &lt; 0:
return [{
"property": "energy",
"message": "Energy must be 0 or greater."
}]
else:
return []
[/codeblock]
</description>
</method>
<method name="_get_rid" qualifiers="virtual const">
<return type="RID" />
<description>
Expand Down Expand Up @@ -93,6 +125,12 @@
Sets the [member resource_path] to [param path], potentially overriding an existing cache entry for this path. Further attempts to load an overridden resource by path will instead return this resource.
</description>
</method>
<method name="update_configuration_info">
<return type="void" />
<description>
Refreshes the configuration information displayed for this resource in the Inspector dock. Use [method _get_configuration_info] to customize the messages to display.
</description>
</method>
</methods>
<members>
<member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" default="false">
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/SceneTree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@
Emitted when the [param node] enters this tree.
</description>
</signal>
<signal name="node_configuration_warning_changed">
<signal name="node_configuration_warning_changed" deprecated="This signal is no longer available. Call [code]update_configuration_info[/code] on a [Node] or [Resource] to notify the editor of configuration info changes.">
<param index="0" name="node" type="Node" />
<description>
Emitted when the [param node]'s [method Node.update_configuration_warnings] is called. Only emitted in the editor.
Expand Down
Loading

0 comments on commit 5dd20e8

Please sign in to comment.