summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml15
-rw-r--r--modules/gdscript/gdscript_parser.cpp24
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_enum.gd15
-rw-r--r--modules/gdscript/tests/scripts/parser/features/export_enum.out7
4 files changed, 57 insertions, 4 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 5bed1b9da3..7f9d4ae253 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -316,12 +316,21 @@
<return type="void" />
<param index="0" name="names" type="String" />
<description>
- Export a [String] or integer property as an enumerated list of options. If the property is an integer field, then the index of the value is stored, in the same order the values are provided. You can add specific identifiers for allowed values using a colon.
+ Export an [int] or [String] property as an enumerated list of options. If the property is an [int], then the index of the value is stored, in the same order the values are provided. You can add specific identifiers for allowed values using a colon. If the property is a [String], then the value is stored.
See also [constant PROPERTY_HINT_ENUM].
[codeblock]
- @export_enum("Rebecca", "Mary", "Leah") var character_name: String
@export_enum("Warrior", "Magician", "Thief") var character_class: int
@export_enum("Slow:30", "Average:60", "Very Fast:200") var character_speed: int
+ @export_enum("Rebecca", "Mary", "Leah") var character_name: String
+ [/codeblock]
+ If you want to set an initial value, you must specify it explicitly:
+ [codeblock]
+ @export_enum("Rebecca", "Mary", "Leah") var character_name: String = "Rebecca"
+ [/codeblock]
+ If you want to use named GDScript enums, then use [annotation @export] instead:
+ [codeblock]
+ enum CharacterName {REBECCA, MARY, LEAH}
+ @export var character_name: CharacterName
[/codeblock]
</description>
</annotation>
@@ -507,7 +516,7 @@
<param index="2" name="step" type="float" default="1.0" />
<param index="3" name="extra_hints" type="String" default="&quot;&quot;" />
<description>
- Export a numeric property as a range value. The range must be defined by [param min] and [param max], as well as an optional [param step] and a variety of extra hints. The [param step] defaults to [code]1[/code] for integer properties. For floating-point numbers this value depends on your [code]EditorSettings.interface/inspector/default_float_step[/code] setting.
+ Export an [int] or [float] property as a range value. The range must be defined by [param min] and [param max], as well as an optional [param step] and a variety of extra hints. The [param step] defaults to [code]1[/code] for integer properties. For floating-point numbers this value depends on your [code]EditorSettings.interface/inspector/default_float_step[/code] setting.
If hints [code]"or_greater"[/code] and [code]"or_less"[/code] are provided, the editor widget will not cap the value at range boundaries. The [code]"exp"[/code] hint will make the edited values on range to change exponentially. The [code]"hide_slider"[/code] hint will hide the slider element of the editor widget.
Hints also allow to indicate the units for the edited value. Using [code]"radians"[/code] you can specify that the actual value is in radians, but should be displayed in degrees in the Inspector dock. [code]"degrees"[/code] allows to add a degree sign as a unit suffix. Finally, a custom suffix can be provided using [code]"suffix:unit"[/code], where "unit" can be any string.
See also [constant PROPERTY_HINT_RANGE].
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 74d7f94d7c..c7c7150c14 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -122,7 +122,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation);
// Export annotations.
register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>);
- register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::INT>, varray(), true);
+ register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::NIL>, varray(), true);
register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, varray(""), true);
register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>);
register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_FILE, Variant::STRING>, varray(""), true);
@@ -3657,6 +3657,10 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
String hint_string;
for (int i = 0; i < p_annotation->resolved_arguments.size(); i++) {
+ if (p_annotation->name != SNAME("@export_placeholder") && String(p_annotation->resolved_arguments[i]).contains(",")) {
+ push_error(vformat(R"(Argument %d of annotation "%s" contains a comma. Use separate arguments instead.)", i + 1, p_annotation->name), p_annotation->arguments[i]);
+ return false;
+ }
if (i > 0) {
hint_string += ",";
}
@@ -3801,6 +3805,24 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
variable->export_info.hint_string = hint_prefix + ":" + variable->export_info.hint_string;
variable->export_info.type = Variant::ARRAY;
}
+ } else if (p_annotation->name == SNAME("@export_enum")) {
+ Variant::Type enum_type = Variant::INT;
+
+ if (export_type.kind == DataType::BUILTIN && export_type.builtin_type == Variant::STRING) {
+ enum_type = Variant::STRING;
+ } else if (export_type.is_variant() && variable->initializer != nullptr) {
+ DataType initializer_type = variable->initializer->get_datatype();
+ if (initializer_type.kind == DataType::BUILTIN && initializer_type.builtin_type == Variant::STRING) {
+ enum_type = Variant::STRING;
+ }
+ }
+
+ variable->export_info.type = enum_type;
+
+ if (!export_type.is_variant() && (export_type.kind != DataType::BUILTIN || export_type.builtin_type != enum_type)) {
+ push_error(vformat(R"("@export_enum" annotation requires a variable of type "int" or "String" but type "%s" was given instead.)", export_type.to_string()), variable);
+ return false;
+ }
} else {
// Validate variable type with export.
if (!export_type.is_variant() && (export_type.kind != DataType::BUILTIN || export_type.builtin_type != t_type)) {
diff --git a/modules/gdscript/tests/scripts/parser/features/export_enum.gd b/modules/gdscript/tests/scripts/parser/features/export_enum.gd
new file mode 100644
index 0000000000..9b2c22dea1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/export_enum.gd
@@ -0,0 +1,15 @@
+@export_enum("Red", "Green", "Blue") var untyped
+
+@export_enum("Red", "Green", "Blue") var weak_int = 0
+@export_enum("Red", "Green", "Blue") var weak_string = ""
+
+@export_enum("Red", "Green", "Blue") var hard_int: int
+@export_enum("Red", "Green", "Blue") var hard_string: String
+
+@export_enum("Red:10", "Green:20", "Blue:30") var with_values
+
+func test():
+ for property in get_property_list():
+ if property.name in ["untyped", "weak_int", "weak_string", "hard_int",
+ "hard_string", "with_values"]:
+ prints(property.name, property.type, property.hint_string)
diff --git a/modules/gdscript/tests/scripts/parser/features/export_enum.out b/modules/gdscript/tests/scripts/parser/features/export_enum.out
new file mode 100644
index 0000000000..330b7eaf01
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/export_enum.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+untyped 2 Red,Green,Blue
+weak_int 2 Red,Green,Blue
+weak_string 4 Red,Green,Blue
+hard_int 2 Red,Green,Blue
+hard_string 4 Red,Green,Blue
+with_values 2 Red:10,Green:20,Blue:30