Skip to content

Commit 65f0881

Browse files
committed
Implement typed dictionaries
1 parent bf2f9e2 commit 65f0881

File tree

10 files changed

+1962
-2
lines changed

10 files changed

+1962
-2
lines changed

binding_generator.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
421421
for include in fully_used_classes:
422422
if include == "TypedArray":
423423
result.append("#include <godot_cpp/variant/typed_array.hpp>")
424+
elif include == "TypedDictionary":
425+
result.append("#include <godot_cpp/variant/typed_dictionary.hpp>")
424426
else:
425427
result.append(f"#include <godot_cpp/{get_include_path(include)}>")
426428

@@ -743,6 +745,10 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
743745
if class_name == "Dictionary":
744746
result.append("\tconst Variant &operator[](const Variant &p_key) const;")
745747
result.append("\tVariant &operator[](const Variant &p_key);")
748+
result.append(
749+
"\tvoid set_typed(uint32_t p_key_type, const StringName &p_key_class_name, const Variant &p_key_script, uint32_t p_value_type, const StringName &p_value_class_name, const Variant &p_value_script);"
750+
)
751+
result.append("\tvoid _ref(const Dictionary &p_from) const;")
746752

747753
result.append("};")
748754

@@ -1126,6 +1132,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
11261132
fully_used_classes.add(array_type_name)
11271133
else:
11281134
used_classes.add(array_type_name)
1135+
elif type_name.startswith("typeddictionary::"):
1136+
fully_used_classes.add("TypedDictionary")
1137+
dict_type_name = type_name.replace("typeddictionary::", "")
1138+
if dict_type_name.startswith("const "):
1139+
dict_type_name = dict_type_name[6:]
1140+
dict_type_names = dict_type_name.split(",")
1141+
dict_type_name = dict_type_names[0]
1142+
if dict_type_name.endswith("*"):
1143+
dict_type_name = dict_type_name[:-1]
1144+
if is_included(dict_type_name, class_name):
1145+
if is_enum(dict_type_name):
1146+
fully_used_classes.add(get_enum_class(dict_type_name))
1147+
elif "default_value" in argument:
1148+
fully_used_classes.add(dict_type_name)
1149+
else:
1150+
used_classes.add(dict_type_name)
1151+
dict_type_name = dict_type_names[2]
1152+
if dict_type_name.endswith("*"):
1153+
dict_type_name = dict_type_name[:-1]
1154+
if is_included(dict_type_name, class_name):
1155+
if is_enum(dict_type_name):
1156+
fully_used_classes.add(get_enum_class(dict_type_name))
1157+
elif "default_value" in argument:
1158+
fully_used_classes.add(dict_type_name)
1159+
else:
1160+
used_classes.add(dict_type_name)
11291161
elif is_enum(type_name):
11301162
fully_used_classes.add(get_enum_class(type_name))
11311163
elif "default_value" in argument:
@@ -1155,6 +1187,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
11551187
fully_used_classes.add(array_type_name)
11561188
else:
11571189
used_classes.add(array_type_name)
1190+
elif type_name.startswith("typeddictionary::"):
1191+
fully_used_classes.add("TypedDictionary")
1192+
dict_type_name = type_name.replace("typeddictionary::", "")
1193+
if dict_type_name.startswith("const "):
1194+
dict_type_name = dict_type_name[6:]
1195+
dict_type_names = dict_type_name.split(",")
1196+
dict_type_name = dict_type_names[0]
1197+
if dict_type_name.endswith("*"):
1198+
dict_type_name = dict_type_name[:-1]
1199+
if is_included(dict_type_name, class_name):
1200+
if is_enum(dict_type_name):
1201+
fully_used_classes.add(get_enum_class(dict_type_name))
1202+
elif is_variant(dict_type_name):
1203+
fully_used_classes.add(dict_type_name)
1204+
else:
1205+
used_classes.add(dict_type_name)
1206+
dict_type_name = dict_type_names[2]
1207+
if dict_type_name.endswith("*"):
1208+
dict_type_name = dict_type_name[:-1]
1209+
if is_included(dict_type_name, class_name):
1210+
if is_enum(dict_type_name):
1211+
fully_used_classes.add(get_enum_class(dict_type_name))
1212+
elif is_variant(dict_type_name):
1213+
fully_used_classes.add(dict_type_name)
1214+
else:
1215+
used_classes.add(dict_type_name)
11581216
elif is_enum(type_name):
11591217
fully_used_classes.add(get_enum_class(type_name))
11601218
elif is_variant(type_name):
@@ -1281,6 +1339,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
12811339
for included in fully_used_classes:
12821340
if included == "TypedArray":
12831341
result.append("#include <godot_cpp/variant/typed_array.hpp>")
1342+
elif included == "TypedDictionary":
1343+
result.append("#include <godot_cpp/variant/typed_dictionary.hpp>")
12841344
else:
12851345
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
12861346

@@ -2322,6 +2382,7 @@ def is_variant(type_name):
23222382
or type_name in builtin_classes
23232383
or type_name == "Nil"
23242384
or type_name.startswith("typedarray::")
2385+
or type_name.startswith("typeddictionary::")
23252386
)
23262387

23272388

@@ -2347,6 +2408,8 @@ def is_included(type_name, current_type):
23472408
"""
23482409
if type_name.startswith("typedarray::"):
23492410
return True
2411+
if type_name.startswith("typeddictionary::"):
2412+
return True
23502413
to_include = get_enum_class(type_name) if is_enum(type_name) else type_name
23512414
if to_include == current_type or is_pod_type(to_include):
23522415
return False
@@ -2380,6 +2443,12 @@ def correct_typed_array(type_name):
23802443
return type_name
23812444

23822445

2446+
def correct_typed_dictionary(type_name):
2447+
if type_name.startswith("typeddictionary::"):
2448+
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(",", ", ") + ">"
2449+
return type_name
2450+
2451+
23832452
def correct_type(type_name, meta=None):
23842453
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
23852454
if meta != None:
@@ -2393,6 +2462,8 @@ def correct_type(type_name, meta=None):
23932462
return type_conversion[type_name]
23942463
if type_name.startswith("typedarray::"):
23952464
return type_name.replace("typedarray::", "TypedArray<") + ">"
2465+
if type_name.startswith("typeddictionary::"):
2466+
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(",", ", ") + ">"
23962467
if is_enum(type_name):
23972468
if is_bitfield(type_name):
23982469
base_class = get_enum_class(type_name)
@@ -2497,6 +2568,8 @@ def get_default_value_for_type(type_name):
24972568
return "false"
24982569
if type_name.startswith("typedarray::"):
24992570
return f"{correct_type(type_name)}()"
2571+
if type_name.startswith("typeddictionary::"):
2572+
return f"{correct_type(type_name)}()"
25002573
if is_enum(type_name):
25012574
return f"{correct_type(type_name)}(0)"
25022575
if is_variant(type_name):

gdextension/gdextension_interface.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,33 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndex)(GDE
20652065
*/
20662066
typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionConstVariantPtr p_key);
20672067

2068+
/**
2069+
* @name dictionary_ref
2070+
* @since 4.2
2071+
*
2072+
* Sets a Dictionary to be a reference to another Dictionary object.
2073+
*
2074+
* @param p_self A pointer to the Dictionary object to update.
2075+
* @param p_from A pointer to the Dictionary object to reference.
2076+
*/
2077+
typedef void (*GDExtensionInterfaceDictionaryRef)(GDExtensionTypePtr p_self, GDExtensionConstTypePtr p_from);
2078+
2079+
/**
2080+
* @name dictionary_set_typed
2081+
* @since 4.2
2082+
*
2083+
* Makes a Dictionary into a typed Dictionary.
2084+
*
2085+
* @param p_self A pointer to the Dictionary.
2086+
* @param p_key_type The type of Variant the Dictionary key will store.
2087+
* @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).
2088+
* @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).
2089+
* @param p_value_type The type of Variant the Dictionary value will store.
2090+
* @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).
2091+
* @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).
2092+
*/
2093+
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);
2094+
20682095
/* INTERFACE: Object */
20692096

20702097
/**

0 commit comments

Comments
 (0)