Merge pull request #76561 from KoBeWi/most_obscure_class_that_has_ever_existed

Improve and document PackedDataContainer
This commit is contained in:
Rémi Verschelde 2023-05-08 12:20:33 +02:00
commit e85f6871ba
No known key found for this signature in database
GPG key ID: C3336907360768E1
4 changed files with 54 additions and 12 deletions

View file

@ -320,6 +320,8 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
}
Error PackedDataContainer::pack(const Variant &p_data) {
ERR_FAIL_COND_V_MSG(p_data.get_type() != Variant::ARRAY && p_data.get_type() != Variant::DICTIONARY, ERR_INVALID_DATA, "PackedDataContainer can pack only Array and Dictionary type.");
Vector<uint8_t> tmpdata;
HashMap<String, uint32_t> string_cache;
_pack(p_data, tmpdata, string_cache);
@ -361,7 +363,9 @@ void PackedDataContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("pack", "value"), &PackedDataContainer::pack);
ClassDB::bind_method(D_METHOD("size"), &PackedDataContainer::size);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "__data__"), "_set_data", "_get_data");
BIND_METHOD_ERR_RETURN_DOC("pack", ERR_INVALID_DATA);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "__data__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
//////////////////
@ -378,16 +382,11 @@ Variant PackedDataContainerRef::_iter_get(const Variant &p_iter) {
return from->_iter_get_ofs(p_iter, offset);
}
bool PackedDataContainerRef::_is_dictionary() const {
return from->_type_at_ofs(offset) == PackedDataContainer::TYPE_DICT;
}
void PackedDataContainerRef::_bind_methods() {
ClassDB::bind_method(D_METHOD("size"), &PackedDataContainerRef::size);
ClassDB::bind_method(D_METHOD("_iter_init"), &PackedDataContainerRef::_iter_init);
ClassDB::bind_method(D_METHOD("_iter_get"), &PackedDataContainerRef::_iter_get);
ClassDB::bind_method(D_METHOD("_iter_next"), &PackedDataContainerRef::_iter_next);
ClassDB::bind_method(D_METHOD("_is_dictionary"), &PackedDataContainerRef::_is_dictionary);
}
Variant PackedDataContainerRef::getvar(const Variant &p_key, bool *r_valid) const {

View file

@ -94,7 +94,6 @@ public:
Variant _iter_init(const Array &p_iter);
Variant _iter_next(const Array &p_iter);
Variant _iter_get(const Variant &p_iter);
bool _is_dictionary() const;
int size() const;
virtual Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const override;

View file

@ -1,26 +1,47 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PackedDataContainer" inherits="Resource" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Efficiently packs and serializes [Array] or [Dictionary].
</brief_description>
<description>
[PackedDataContainer] can be used to efficiently store data from untyped containers. The data is packed into raw bytes and can be saved to file. Only [Array] and [Dictionary] can be stored this way.
You can retrieve the data by iterating on the container, which will work as if iterating on the packed data itself. If the packed container is a [Dictionary], the data can be retrieved by key names ([String]/[StringName] only).
[codeblock]
var data = { "key": "value", "another_key": 123, "lock": Vector2() }
var packed = PackedDataContainer.new()
packed.pack(data)
ResourceSaver.save(packed, "packed_data.res")
[/codeblock]
[codeblock]
var container = load("packed_data.res")
for key in container:
prints(key, container[key])
# Prints:
# key value
# lock (0, 0)
# another_key 123
[/codeblock]
Nested containers will be packed recursively. While iterating, they will be returned as [PackedDataContainerRef].
</description>
<tutorials>
</tutorials>
<methods>
<method name="pack">
<return type="int" enum="Error" />
<returns_error number="0"/>
<returns_error number="30"/>
<param index="0" name="value" type="Variant" />
<description>
Packs the given container into a binary representation. The [param value] must be either [Array] or [Dictionary], any other type will result in invalid data error.
[b]Note:[/b] Subsequent calls to this method will overwrite the existing data.
</description>
</method>
<method name="size" qualifiers="const">
<return type="int" />
<description>
Returns the size of the packed container (see [method Array.size] and [method Dictionary.size]).
</description>
</method>
</methods>
<members>
<member name="__data__" type="PackedByteArray" setter="_set_data" getter="_get_data" default="PackedByteArray()">
</member>
</members>
</class>

View file

@ -1,9 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PackedDataContainerRef" inherits="RefCounted" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Reference-counted version of [PackedDataContainer].
Internal class used by [PackedDataContainer].
</brief_description>
<description>
When packing nested containers using [PackedDataContainer], they are recursively packed into [PackedDataContainerRef] (only applies to [Array] and [Dictionary]). Their data can be retrieved the same way as from [PackedDataContainer].
[codeblock]
var packed = PackedDataContainer.new()
packed.pack([1, 2, 3, ["abc", "def"], 4, 5, 6])
for element in packed:
if element is PackedDataContainerRef:
for subelement in element:
print("::", subelement)
else:
print(element)
# Prints:
# 1
# 2
# 3
# ::abc
# ::def
# 4
# 5
# 6
[/codeblock]
</description>
<tutorials>
</tutorials>
@ -11,6 +33,7 @@
<method name="size" qualifiers="const">
<return type="int" />
<description>
Returns the size of the packed container (see [method Array.size] and [method Dictionary.size]).
</description>
</method>
</methods>