diff options
author | George Marques <george@gmarqu.es> | 2023-02-08 16:15:48 -0300 |
---|---|---|
committer | George Marques <george@gmarqu.es> | 2024-03-07 10:55:21 -0300 |
commit | 8e520454ef92965a3e9c14240db0305405f5fead (patch) | |
tree | 71361e8da83c5979f888bde96ad81b7ff42c2744 | |
parent | 24f775089efd1c3e7419a523dd74dc24924b517c (diff) | |
download | redot-engine-8e520454ef92965a3e9c14240db0305405f5fead.tar.gz |
GDScript: Add @export_custom annotation
Allows setting any arbitrary hint, hint string, and usage flags.
Useful for more complex hints or potential future hints not
available as a dedicated annotation.
-rw-r--r-- | modules/gdscript/doc_classes/@GDScript.xml | 12 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 25 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 1 |
3 files changed, 38 insertions, 0 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index ddf506216e..a68d65e8d3 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -341,6 +341,18 @@ [/codeblock] </description> </annotation> + <annotation name="@export_custom"> + <return type="void" /> + <param index="0" name="hint" type="int" enum="PropertyHint" /> + <param index="1" name="hint_string" type="String" /> + <param index="2" name="usage" type="int" enum="PropertyUsageFlags" is_bitfield="true" default="6" /> + <description> + Allows you to set a custom hint, hint string, and usage flags for the exported property. Note that there's no validation done in GDScript, it will just pass the hint along to the editor. + [codeblock] + @export_custom(PROPERTY_HINT_NONE, "suffix:m") var suffix: Vector3 + [/codeblock] + </description> + </annotation> <annotation name="@export_dir"> <return type="void" /> <description> diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e27ff05721..aae45274e0 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -121,6 +121,7 @@ GDScriptParser::GDScriptParser() { register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_AVOIDANCE, Variant::INT>); + 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)); // Export grouping annotations. register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>); register_annotation(MethodInfo("@export_group", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_GROUP>, varray("")); @@ -4328,6 +4329,30 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node return true; } +bool GDScriptParser::export_custom_annotation(const AnnotationNode *p_annotation, Node *p_node, ClassNode *p_class) { + ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE, false, vformat(R"("%s" annotation can only be applied to variables.)", p_annotation->name)); + ERR_FAIL_COND_V_MSG(p_annotation->resolved_arguments.size() < 2, false, R"(Annotation "@export_custom" requires 2 arguments.)"); + + VariableNode *variable = static_cast<VariableNode *>(p_node); + if (variable->exported) { + push_error(vformat(R"(Annotation "%s" cannot be used with another "@export" annotation.)", p_annotation->name), p_annotation); + return false; + } + + variable->exported = true; + + DataType export_type = variable->get_datatype(); + + variable->export_info.type = export_type.builtin_type; + variable->export_info.hint = static_cast<PropertyHint>(p_annotation->resolved_arguments[0].operator int64_t()); + variable->export_info.hint_string = p_annotation->resolved_arguments[1]; + + if (p_annotation->resolved_arguments.size() >= 3) { + variable->export_info.usage = p_annotation->resolved_arguments[2].operator int64_t(); + } + return true; +} + template <PropertyUsageFlags t_usage> bool GDScriptParser::export_group_annotations(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) { AnnotationNode *annotation = const_cast<AnnotationNode *>(p_annotation); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 6664e6df04..45ab3f3e38 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1482,6 +1482,7 @@ private: bool onready_annotation(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); template <PropertyHint t_hint, Variant::Type t_type> bool export_annotations(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); + bool export_custom_annotation(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); template <PropertyUsageFlags t_usage> bool export_group_annotations(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); bool warning_annotations(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); |