Selaa lähdekoodia

Improve and document PackedDataContainer

kobewi 2 vuotta sitten
vanhempi
commit
c08e96ef0d

+ 5 - 6
core/io/packed_data_container.cpp

@@ -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 {

+ 0 - 1
core/io/packed_data_container.h

@@ -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;

+ 25 - 4
doc/classes/PackedDataContainer.xml

@@ -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>

+ 24 - 1
doc/classes/PackedDataContainerRef.xml

@@ -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>