Skip to content

Commit 034b415

Browse files
committed
Implement typed dictionaries
1 parent ff6f579 commit 034b415

File tree

10 files changed

+1960
-2
lines changed

10 files changed

+1960
-2
lines changed

binding_generator.py

Lines changed: 71 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,8 @@ 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("\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);")
709+
result.append("\tvoid _ref(const Dictionary &p_from) const;")
706710

707711
result.append("};")
708712

@@ -1084,6 +1088,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
10841088
fully_used_classes.add(array_type_name)
10851089
else:
10861090
used_classes.add(array_type_name)
1091+
elif type_name.startswith("typeddictionary::"):
1092+
fully_used_classes.add("TypedDictionary")
1093+
dict_type_name = type_name.replace("typeddictionary::", "")
1094+
if dict_type_name.startswith("const "):
1095+
dict_type_name = dict_type_name[6:]
1096+
dict_type_names = dict_type_name.split(",")
1097+
dict_type_name = dict_type_names[0]
1098+
if dict_type_name.endswith("*"):
1099+
dict_type_name = dict_type_name[:-1]
1100+
if is_included(dict_type_name, class_name):
1101+
if is_enum(dict_type_name):
1102+
fully_used_classes.add(get_enum_class(dict_type_name))
1103+
elif "default_value" in argument:
1104+
fully_used_classes.add(dict_type_name)
1105+
else:
1106+
used_classes.add(dict_type_name)
1107+
dict_type_name = dict_type_names[2]
1108+
if dict_type_name.endswith("*"):
1109+
dict_type_name = dict_type_name[:-1]
1110+
if is_included(dict_type_name, class_name):
1111+
if is_enum(dict_type_name):
1112+
fully_used_classes.add(get_enum_class(dict_type_name))
1113+
elif "default_value" in argument:
1114+
fully_used_classes.add(dict_type_name)
1115+
else:
1116+
used_classes.add(dict_type_name)
10871117
elif is_enum(type_name):
10881118
fully_used_classes.add(get_enum_class(type_name))
10891119
elif "default_value" in argument:
@@ -1113,6 +1143,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
11131143
fully_used_classes.add(array_type_name)
11141144
else:
11151145
used_classes.add(array_type_name)
1146+
elif type_name.startswith("typeddictionary::"):
1147+
fully_used_classes.add("TypedDictionary")
1148+
dict_type_name = type_name.replace("typeddictionary::", "")
1149+
if dict_type_name.startswith("const "):
1150+
dict_type_name = dict_type_name[6:]
1151+
dict_type_names = dict_type_name.split(",")
1152+
dict_type_name = dict_type_names[0]
1153+
if dict_type_name.endswith("*"):
1154+
dict_type_name = dict_type_name[:-1]
1155+
if is_included(dict_type_name, class_name):
1156+
if is_enum(dict_type_name):
1157+
fully_used_classes.add(get_enum_class(dict_type_name))
1158+
elif is_variant(dict_type_name):
1159+
fully_used_classes.add(dict_type_name)
1160+
else:
1161+
used_classes.add(dict_type_name)
1162+
dict_type_name = dict_type_names[2]
1163+
if dict_type_name.endswith("*"):
1164+
dict_type_name = dict_type_name[:-1]
1165+
if is_included(dict_type_name, class_name):
1166+
if is_enum(dict_type_name):
1167+
fully_used_classes.add(get_enum_class(dict_type_name))
1168+
elif is_variant(dict_type_name):
1169+
fully_used_classes.add(dict_type_name)
1170+
else:
1171+
used_classes.add(dict_type_name)
11161172
elif is_enum(type_name):
11171173
fully_used_classes.add(get_enum_class(type_name))
11181174
elif is_variant(type_name):
@@ -1233,6 +1289,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
12331289
for included in fully_used_classes:
12341290
if included == "TypedArray":
12351291
result.append("#include <godot_cpp/variant/typed_array.hpp>")
1292+
elif included == "TypedDictionary":
1293+
result.append("#include <godot_cpp/variant/typed_dictionary.hpp>")
12361294
else:
12371295
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
12381296

@@ -2157,6 +2215,7 @@ def is_variant(type_name):
21572215
or type_name in builtin_classes
21582216
or type_name == "Nil"
21592217
or type_name.startswith("typedarray::")
2218+
or type_name.startswith("typeddictionary::")
21602219
)
21612220

21622221

@@ -2182,6 +2241,8 @@ def is_included(type_name, current_type):
21822241
"""
21832242
if type_name.startswith("typedarray::"):
21842243
return True
2244+
if type_name.startswith("typeddictionary::"):
2245+
return True
21852246
to_include = get_enum_class(type_name) if is_enum(type_name) else type_name
21862247
if to_include == current_type or is_pod_type(to_include):
21872248
return False
@@ -2215,6 +2276,12 @@ def correct_typed_array(type_name):
22152276
return type_name
22162277

22172278

2279+
def correct_typed_dictionary(type_name):
2280+
if type_name.startswith("typeddictionary::"):
2281+
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(",", ", ") + ">"
2282+
return type_name
2283+
2284+
22182285
def correct_type(type_name, meta=None):
22192286
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
22202287
if meta != None:
@@ -2228,6 +2295,8 @@ def correct_type(type_name, meta=None):
22282295
return type_conversion[type_name]
22292296
if type_name.startswith("typedarray::"):
22302297
return type_name.replace("typedarray::", "TypedArray<") + ">"
2298+
if type_name.startswith("typeddictionary::"):
2299+
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(",", ", ") + ">"
22312300
if is_enum(type_name):
22322301
if is_bitfield(type_name):
22332302
base_class = get_enum_class(type_name)
@@ -2331,6 +2400,8 @@ def get_default_value_for_type(type_name):
23312400
return "false"
23322401
if type_name.startswith("typedarray::"):
23332402
return f"{correct_type(type_name)}()"
2403+
if type_name.startswith("typeddictionary::"):
2404+
return f"{correct_type(type_name)}()"
23342405
if is_enum(type_name):
23352406
return f"{correct_type(type_name)}(0)"
23362407
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)