Skip to content

Commit 191037d

Browse files
committed
Implement typed dictionaries
1 parent ff6f579 commit 191037d

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
@@ -382,6 +382,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
382382
for include in fully_used_classes:
383383
if include == "TypedArray":
384384
result.append("#include <godot_cpp/variant/typed_array.hpp>")
385+
elif include == "TypedDictionary":
386+
result.append("#include <godot_cpp/variant/typed_dictionary.hpp>")
385387
else:
386388
result.append(f"#include <godot_cpp/{get_include_path(include)}>")
387389

@@ -703,6 +705,10 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
703705
if class_name == "Dictionary":
704706
result.append("\tconst Variant &operator[](const Variant &p_key) const;")
705707
result.append("\tVariant &operator[](const Variant &p_key);")
708+
result.append(
709+
"\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);"
710+
)
711+
result.append("\tvoid _ref(const Dictionary &p_from) const;")
706712

707713
result.append("};")
708714

@@ -1084,6 +1090,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
10841090
fully_used_classes.add(array_type_name)
10851091
else:
10861092
used_classes.add(array_type_name)
1093+
elif type_name.startswith("typeddictionary::"):
1094+
fully_used_classes.add("TypedDictionary")
1095+
dict_type_name = type_name.replace("typeddictionary::", "")
1096+
if dict_type_name.startswith("const "):
1097+
dict_type_name = dict_type_name[6:]
1098+
dict_type_names = dict_type_name.split(",")
1099+
dict_type_name = dict_type_names[0]
1100+
if dict_type_name.endswith("*"):
1101+
dict_type_name = dict_type_name[:-1]
1102+
if is_included(dict_type_name, class_name):
1103+
if is_enum(dict_type_name):
1104+
fully_used_classes.add(get_enum_class(dict_type_name))
1105+
elif "default_value" in argument:
1106+
fully_used_classes.add(dict_type_name)
1107+
else:
1108+
used_classes.add(dict_type_name)
1109+
dict_type_name = dict_type_names[2]
1110+
if dict_type_name.endswith("*"):
1111+
dict_type_name = dict_type_name[:-1]
1112+
if is_included(dict_type_name, class_name):
1113+
if is_enum(dict_type_name):
1114+
fully_used_classes.add(get_enum_class(dict_type_name))
1115+
elif "default_value" in argument:
1116+
fully_used_classes.add(dict_type_name)
1117+
else:
1118+
used_classes.add(dict_type_name)
10871119
elif is_enum(type_name):
10881120
fully_used_classes.add(get_enum_class(type_name))
10891121
elif "default_value" in argument:
@@ -1113,6 +1145,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
11131145
fully_used_classes.add(array_type_name)
11141146
else:
11151147
used_classes.add(array_type_name)
1148+
elif type_name.startswith("typeddictionary::"):
1149+
fully_used_classes.add("TypedDictionary")
1150+
dict_type_name = type_name.replace("typeddictionary::", "")
1151+
if dict_type_name.startswith("const "):
1152+
dict_type_name = dict_type_name[6:]
1153+
dict_type_names = dict_type_name.split(",")
1154+
dict_type_name = dict_type_names[0]
1155+
if dict_type_name.endswith("*"):
1156+
dict_type_name = dict_type_name[:-1]
1157+
if is_included(dict_type_name, class_name):
1158+
if is_enum(dict_type_name):
1159+
fully_used_classes.add(get_enum_class(dict_type_name))
1160+
elif is_variant(dict_type_name):
1161+
fully_used_classes.add(dict_type_name)
1162+
else:
1163+
used_classes.add(dict_type_name)
1164+
dict_type_name = dict_type_names[2]
1165+
if dict_type_name.endswith("*"):
1166+
dict_type_name = dict_type_name[:-1]
1167+
if is_included(dict_type_name, class_name):
1168+
if is_enum(dict_type_name):
1169+
fully_used_classes.add(get_enum_class(dict_type_name))
1170+
elif is_variant(dict_type_name):
1171+
fully_used_classes.add(dict_type_name)
1172+
else:
1173+
used_classes.add(dict_type_name)
11161174
elif is_enum(type_name):
11171175
fully_used_classes.add(get_enum_class(type_name))
11181176
elif is_variant(type_name):
@@ -1233,6 +1291,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
12331291
for included in fully_used_classes:
12341292
if included == "TypedArray":
12351293
result.append("#include <godot_cpp/variant/typed_array.hpp>")
1294+
elif included == "TypedDictionary":
1295+
result.append("#include <godot_cpp/variant/typed_dictionary.hpp>")
12361296
else:
12371297
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
12381298

@@ -2157,6 +2217,7 @@ def is_variant(type_name):
21572217
or type_name in builtin_classes
21582218
or type_name == "Nil"
21592219
or type_name.startswith("typedarray::")
2220+
or type_name.startswith("typeddictionary::")
21602221
)
21612222

21622223

@@ -2182,6 +2243,8 @@ def is_included(type_name, current_type):
21822243
"""
21832244
if type_name.startswith("typedarray::"):
21842245
return True
2246+
if type_name.startswith("typeddictionary::"):
2247+
return True
21852248
to_include = get_enum_class(type_name) if is_enum(type_name) else type_name
21862249
if to_include == current_type or is_pod_type(to_include):
21872250
return False
@@ -2215,6 +2278,12 @@ def correct_typed_array(type_name):
22152278
return type_name
22162279

22172280

2281+
def correct_typed_dictionary(type_name):
2282+
if type_name.startswith("typeddictionary::"):
2283+
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(",", ", ") + ">"
2284+
return type_name
2285+
2286+
22182287
def correct_type(type_name, meta=None):
22192288
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
22202289
if meta != None:
@@ -2228,6 +2297,8 @@ def correct_type(type_name, meta=None):
22282297
return type_conversion[type_name]
22292298
if type_name.startswith("typedarray::"):
22302299
return type_name.replace("typedarray::", "TypedArray<") + ">"
2300+
if type_name.startswith("typeddictionary::"):
2301+
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(",", ", ") + ">"
22312302
if is_enum(type_name):
22322303
if is_bitfield(type_name):
22332304
base_class = get_enum_class(type_name)
@@ -2331,6 +2402,8 @@ def get_default_value_for_type(type_name):
23312402
return "false"
23322403
if type_name.startswith("typedarray::"):
23332404
return f"{correct_type(type_name)}()"
2405+
if type_name.startswith("typeddictionary::"):
2406+
return f"{correct_type(type_name)}()"
23342407
if is_enum(type_name):
23352408
return f"{correct_type(type_name)}(0)"
23362409
if is_variant(type_name):

gdextension/gdextension_interface.h

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

1928+
/**
1929+
* @name dictionary_ref
1930+
* @since 4.2
1931+
*
1932+
* Sets a Dictionary to be a reference to another Dictionary object.
1933+
*
1934+
* @param p_self A pointer to the Dictionary object to update.
1935+
* @param p_from A pointer to the Dictionary object to reference.
1936+
*/
1937+
typedef void (*GDExtensionInterfaceDictionaryRef)(GDExtensionTypePtr p_self, GDExtensionConstTypePtr p_from);
1938+
1939+
/**
1940+
* @name dictionary_set_typed
1941+
* @since 4.2
1942+
*
1943+
* Makes a Dictionary into a typed Dictionary.
1944+
*
1945+
* @param p_self A pointer to the Dictionary.
1946+
* @param p_key_type The type of Variant the Dictionary key will store.
1947+
* @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).
1948+
* @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).
1949+
* @param p_value_type The type of Variant the Dictionary value will store.
1950+
* @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).
1951+
* @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).
1952+
*/
1953+
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);
1954+
19281955
/* INTERFACE: Object */
19291956

19301957
/**

0 commit comments

Comments
 (0)