Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement typed dictionaries #78656

Merged
merged 1 commit into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/core_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_OBJECTID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_POINTER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_DICTIONARY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LOCALE_ID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LOCALIZABLE_STRING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_TYPE);
Expand Down
6 changes: 6 additions & 0 deletions core/doc_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
String DocData::get_default_value_string(const Variant &p_value) {
if (p_value.get_type() == Variant::ARRAY) {
return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace("\n", " ");
} else if (p_value.get_type() == Variant::DICTIONARY) {
return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace("\n", " ");
} else {
return p_value.get_construct_string().replace("\n", " ");
}
Expand All @@ -57,6 +59,8 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
p_method.return_type = p_retinfo.class_name;
} else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
p_method.return_type = p_retinfo.hint_string + "[]";
} else if (p_retinfo.type == Variant::DICTIONARY && p_retinfo.hint == PROPERTY_HINT_DICTIONARY_TYPE) {
p_method.return_type = "Dictionary[" + p_retinfo.hint_string.replace(";", ", ") + "]";
} else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
p_method.return_type = p_retinfo.hint_string;
} else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
Expand Down Expand Up @@ -89,6 +93,8 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
p_argument.type = p_arginfo.class_name;
} else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
p_argument.type = p_arginfo.hint_string + "[]";
} else if (p_arginfo.type == Variant::DICTIONARY && p_arginfo.hint == PROPERTY_HINT_DICTIONARY_TYPE) {
p_argument.type = "Dictionary[" + p_arginfo.hint_string.replace(";", ", ") + "]";
} else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
p_argument.type = p_arginfo.hint_string;
} else if (p_arginfo.type == Variant::NIL) {
Expand Down
3 changes: 3 additions & 0 deletions core/extension/extension_api_dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ static String get_property_info_type_name(const PropertyInfo &p_info) {
if (p_info.type == Variant::ARRAY && (p_info.hint == PROPERTY_HINT_ARRAY_TYPE)) {
return String("typedarray::") + p_info.hint_string;
}
if (p_info.type == Variant::DICTIONARY && (p_info.hint == PROPERTY_HINT_DICTIONARY_TYPE)) {
return String("typeddictionary::") + p_info.hint_string;
}
if (p_info.type == Variant::INT && (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM))) {
return String("enum::") + String(p_info.class_name);
}
Expand Down
10 changes: 10 additions & 0 deletions core/extension/gdextension_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,15 @@ static GDExtensionVariantPtr gdextension_dictionary_operator_index_const(GDExten
return (GDExtensionVariantPtr)&self->operator[](*(const Variant *)p_key);
}

void gdextension_dictionary_set_typed(GDExtensionTypePtr p_self, GDExtensionVariantType p_key_type, GDExtensionConstStringNamePtr p_key_class_name, GDExtensionConstVariantPtr p_key_script, GDExtensionVariantType p_value_type, GDExtensionConstStringNamePtr p_value_class_name, GDExtensionConstVariantPtr p_value_script) {
Dictionary *self = reinterpret_cast<Dictionary *>(p_self);
const StringName *key_class_name = reinterpret_cast<const StringName *>(p_key_class_name);
const Variant *key_script = reinterpret_cast<const Variant *>(p_key_script);
const StringName *value_class_name = reinterpret_cast<const StringName *>(p_value_class_name);
const Variant *value_script = reinterpret_cast<const Variant *>(p_value_script);
self->set_typed((uint32_t)p_key_type, *key_class_name, *key_script, (uint32_t)p_value_type, *value_class_name, *value_script);
}

/* OBJECT API */

static void gdextension_object_method_bind_call(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error) {
Expand Down Expand Up @@ -1679,6 +1688,7 @@ void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(array_set_typed);
REGISTER_INTERFACE_FUNC(dictionary_operator_index);
REGISTER_INTERFACE_FUNC(dictionary_operator_index_const);
REGISTER_INTERFACE_FUNC(dictionary_set_typed);
REGISTER_INTERFACE_FUNC(object_method_bind_call);
REGISTER_INTERFACE_FUNC(object_method_bind_ptrcall);
REGISTER_INTERFACE_FUNC(object_destroy);
Expand Down
16 changes: 16 additions & 0 deletions core/extension/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -2372,6 +2372,22 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndex)(GDE
*/
typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionConstVariantPtr p_key);

/**
* @name dictionary_set_typed
* @since 4.4
*
* Makes a Dictionary into a typed Dictionary.
*
* @param p_self A pointer to the Dictionary.
* @param p_key_type The type of Variant the Dictionary key will store.
* @param p_key_class_name A pointer to a StringName with the name of the object (if p_key_type is GDEXTENSION_VARIANT_TYPE_OBJECT).
* @param p_key_script A pointer to a Script object (if p_key_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script).
* @param p_value_type The type of Variant the Dictionary value will store.
* @param p_value_class_name A pointer to a StringName with the name of the object (if p_value_type is GDEXTENSION_VARIANT_TYPE_OBJECT).
* @param p_value_script A pointer to a Script object (if p_value_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script).
*/
typedef void (*GDExtensionInterfaceDictionarySetTyped)(GDExtensionTypePtr p_self, GDExtensionVariantType p_key_type, GDExtensionConstStringNamePtr p_key_class_name, GDExtensionConstVariantPtr p_key_script, GDExtensionVariantType p_value_type, GDExtensionConstStringNamePtr p_value_class_name, GDExtensionConstVariantPtr p_value_script);

/* INTERFACE: Object */

/**
Expand Down
15 changes: 15 additions & 0 deletions core/io/resource_format_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,19 @@ Error ResourceLoaderBinary::load() {
}
}

if (value.get_type() == Variant::DICTIONARY) {
Dictionary set_dict = value;
bool is_get_valid = false;
Variant get_value = res->get(name, &is_get_valid);
if (is_get_valid && get_value.get_type() == Variant::DICTIONARY) {
Dictionary get_dict = get_value;
if (!set_dict.is_same_typed(get_dict)) {
value = Dictionary(set_dict, get_dict.get_typed_key_builtin(), get_dict.get_typed_key_class_name(), get_dict.get_typed_key_script(),
get_dict.get_typed_value_builtin(), get_dict.get_typed_value_class_name(), get_dict.get_typed_value_script());
}
}
}

if (set_valid) {
res->set(name, value);
}
Expand Down Expand Up @@ -2064,6 +2077,8 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant

case Variant::DICTIONARY: {
Dictionary d = p_variant;
_find_resources(d.get_typed_key_script());
_find_resources(d.get_typed_value_script());
List<Variant> keys;
d.get_key_list(&keys);
for (const Variant &E : keys) {
Expand Down
1 change: 1 addition & 0 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum PropertyHint {
PROPERTY_HINT_HIDE_QUATERNION_EDIT, /// Only Node3D::transform should hide the quaternion editor.
PROPERTY_HINT_PASSWORD,
PROPERTY_HINT_LAYERS_AVOIDANCE,
PROPERTY_HINT_DICTIONARY_TYPE,
PROPERTY_HINT_MAX,
};

Expand Down
Loading
Loading