mirror of https://github.com/godotengine/godot
Implement @no_storage annotation.
This commit is contained in:
parent
bdf625bd54
commit
0d17aa0c72
|
|
@ -643,10 +643,12 @@
|
|||
<return type="void" />
|
||||
<description>
|
||||
Export a property with [constant PROPERTY_USAGE_STORAGE] flag. The property is not displayed in the editor, but it is serialized and stored in the scene or resource file. This can be useful for [annotation @tool] scripts. Also the property value is copied when [method Resource.duplicate] or [method Node.duplicate] is called, unlike non-exported variables.
|
||||
See also [annotation @no_storage].
|
||||
[codeblock]
|
||||
var a # Not stored in the file, not displayed in the editor.
|
||||
@export_storage var b # Stored in the file, not displayed in the editor.
|
||||
@export var c: int # Stored in the file, displayed in the editor.
|
||||
@export @no_storage var c: int # Not stored in the file, displayed in the editor.
|
||||
@export var d: int # Stored in the file, displayed in the editor.
|
||||
[/codeblock]
|
||||
</description>
|
||||
</annotation>
|
||||
|
|
@ -729,6 +731,24 @@
|
|||
[b]Note:[/b] Unlike most other annotations, the argument of the [annotation @icon] annotation must be a string literal (constant expressions are not supported).
|
||||
</description>
|
||||
</annotation>
|
||||
<annotation name="@no_storage">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Marks the exported property as editor-only (not saved to disk). Can be applied to a variable with a regular export annotation applied. The property value will also not be copied when [method Resource.duplicate] or [method Node.duplicate] is called, unlike serialized variables. This can be useful for [annotation @tool] scripts.
|
||||
See also [annotation @export_storage].
|
||||
[codeblock]
|
||||
@tool
|
||||
|
||||
@export var string = ""
|
||||
# This variable can be used to edit "string" in the Inspector.
|
||||
@export_range(0, 10) @no_storage var int_to_string: int:
|
||||
set(value):
|
||||
string = str(value)
|
||||
get:
|
||||
return string.to_int()
|
||||
[/codeblock]
|
||||
</description>
|
||||
</annotation>
|
||||
<annotation name="@onready">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ GDScriptParser::GDScriptParser() {
|
|||
register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_AVOIDANCE, Variant::INT>);
|
||||
register_annotation(MethodInfo("@export_storage"), AnnotationInfo::VARIABLE, &GDScriptParser::export_storage_annotation);
|
||||
register_annotation(MethodInfo("@export_custom", PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_ENUM, "PropertyHint"), PropertyInfo(Variant::STRING, "hint_string"), PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_BITFIELD, "PropertyUsageFlags")), AnnotationInfo::VARIABLE, &GDScriptParser::export_custom_annotation, varray(PROPERTY_USAGE_DEFAULT));
|
||||
register_annotation(MethodInfo("@no_storage"), AnnotationInfo::VARIABLE, &GDScriptParser::no_storage_annotation);
|
||||
register_annotation(MethodInfo("@export_tool_button", PropertyInfo(Variant::STRING, "text"), PropertyInfo(Variant::STRING, "icon")), AnnotationInfo::VARIABLE, &GDScriptParser::export_tool_button_annotation, varray(""));
|
||||
// Export grouping annotations.
|
||||
register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>);
|
||||
|
|
@ -4404,7 +4405,7 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
|
|||
return false;
|
||||
}
|
||||
if (variable->exported) {
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with another "@export" annotation.)", p_annotation->name), p_annotation);
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with another export annotation.)", p_annotation->name), p_annotation);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -4739,7 +4740,7 @@ bool GDScriptParser::export_storage_annotation(AnnotationNode *p_annotation, Nod
|
|||
return false;
|
||||
}
|
||||
if (variable->exported) {
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with another "@export" annotation.)", p_annotation->name), p_annotation);
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with another export annotation.)", p_annotation->name), p_annotation);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -4762,7 +4763,7 @@ bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node
|
|||
return false;
|
||||
}
|
||||
if (variable->exported) {
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with another "@export" annotation.)", p_annotation->name), p_annotation);
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with another export annotation.)", p_annotation->name), p_annotation);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -4780,6 +4781,31 @@ bool GDScriptParser::export_custom_annotation(AnnotationNode *p_annotation, Node
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GDScriptParser::no_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
|
||||
ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
|
||||
|
||||
VariableNode *variable = static_cast<VariableNode *>(p_target);
|
||||
for (const AnnotationNode *annotation_node : variable->annotations) {
|
||||
if (annotation_node->name == SNAME("@export_storage") || annotation_node->name == SNAME("@export_custom") || annotation_node->name == SNAME("@export_tool_button")) {
|
||||
push_error(vformat(R"(Annotation "%s" cannot be used with "%s".)", p_annotation->name, annotation_node->name), p_annotation);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!variable->exported) {
|
||||
push_error(vformat(R"(Annotation "%s" must be placed after an export annotation.)", p_annotation->name), p_annotation);
|
||||
return false;
|
||||
}
|
||||
if (variable->exported_no_storage) {
|
||||
push_error(vformat(R"(Annotation "%s" should only be used once.)", p_annotation->name), p_annotation);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set variable to only show in editor and keep the previous annotation's export_info changes.
|
||||
variable->export_info.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
variable->exported_no_storage = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GDScriptParser::export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
ERR_FAIL_COND_V_MSG(p_target->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name));
|
||||
|
|
|
|||
|
|
@ -1262,6 +1262,7 @@ public:
|
|||
};
|
||||
|
||||
bool exported = false;
|
||||
bool exported_no_storage = false;
|
||||
bool onready = false;
|
||||
PropertyInfo export_info;
|
||||
int assignments = 0;
|
||||
|
|
@ -1513,6 +1514,7 @@ private:
|
|||
bool export_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
|
||||
bool export_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
|
||||
bool export_custom_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
|
||||
bool no_storage_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
|
||||
bool export_tool_button_annotation(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
|
||||
template <PropertyUsageFlags t_usage>
|
||||
bool export_group_annotations(AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
@tool
|
||||
|
||||
@export_storage @no_storage var int_number = 0
|
||||
@export_custom(PROPERTY_HINT_NONE, "") @no_storage var float_number = 0.0
|
||||
@export_tool_button("") @no_storage var callable = test
|
||||
@no_storage var string = ""
|
||||
@no_storage @export var string_name = &""
|
||||
@export @no_storage @no_storage var bool_var = false
|
||||
|
||||
func test():
|
||||
pass
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
GDTEST_ANALYZER_ERROR
|
||||
>> ERROR at line 3: Annotation "@no_storage" cannot be used with "@export_storage".
|
||||
>> ERROR at line 4: Annotation "@no_storage" cannot be used with "@export_custom".
|
||||
>> ERROR at line 5: Annotation "@no_storage" cannot be used with "@export_tool_button".
|
||||
>> ERROR at line 6: Annotation "@no_storage" must be placed after an export annotation.
|
||||
>> ERROR at line 7: Annotation "@no_storage" must be placed after an export annotation.
|
||||
>> ERROR at line 8: Annotation "@no_storage" should only be used once.
|
||||
|
|
@ -48,6 +48,13 @@ const PreloadedUnnamedClass = preload("./export_variable_unnamed.notest.gd")
|
|||
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_weak_int = 5
|
||||
@export_custom(PROPERTY_HINT_ENUM, "A,B,C") var test_export_custom_hard_int: int = 6
|
||||
|
||||
# `@no_storage`.
|
||||
@export @no_storage var test_no_storage_int = 1
|
||||
@export_range(0, 10) @no_storage var test_no_storage_range = 1
|
||||
@export_enum("A", "B", "C") @no_storage var test_range_no_storage_enum = "A"
|
||||
@export @no_storage var test_no_storage_array = []
|
||||
@export @no_storage var test_no_storage_dictionary = {}
|
||||
|
||||
# `@export_tool_button`.
|
||||
@export_tool_button("Click me!") var test_tool_button_1: Callable
|
||||
@export_tool_button("Click me!", "ColorRect") var test_tool_button_2: Callable
|
||||
|
|
|
|||
|
|
@ -55,6 +55,16 @@ var test_export_custom_weak_int: int = 5
|
|||
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
|
||||
var test_export_custom_hard_int: int = 6
|
||||
hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE class_name=&""
|
||||
var test_no_storage_int: int = 1
|
||||
hint=NONE hint_string="" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
|
||||
var test_no_storage_range: int = 1
|
||||
hint=RANGE hint_string="0.0,10.0" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
|
||||
var test_range_no_storage_enum: String = "A"
|
||||
hint=ENUM hint_string="A,B,C" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
|
||||
var test_no_storage_array: Array = []
|
||||
hint=NONE hint_string="" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
|
||||
var test_no_storage_dictionary: Dictionary = {}
|
||||
hint=NONE hint_string="" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
|
||||
var test_tool_button_1: Callable = Callable()
|
||||
hint=TOOL_BUTTON hint_string="Click me!" usage=EDITOR|SCRIPT_VARIABLE class_name=&""
|
||||
var test_tool_button_2: Callable = Callable()
|
||||
|
|
|
|||
Loading…
Reference in New Issue