-
-
Notifications
You must be signed in to change notification settings - Fork 249
/
voxel_block_serializer_gd.cpp
122 lines (103 loc) · 3.97 KB
/
voxel_block_serializer_gd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "voxel_block_serializer_gd.h"
#include "../util/godot/classes/stream_peer.h"
#include "../util/godot/core/packed_arrays.h"
#include "voxel_block_serializer.h"
using namespace zylann::godot;
namespace zylann::voxel::godot {
int VoxelBlockSerializer::serialize_to_stream_peer(Ref<StreamPeer> peer, Ref<VoxelBuffer> voxel_buffer, bool compress) {
ERR_FAIL_COND_V(voxel_buffer.is_null(), 0);
ERR_FAIL_COND_V(peer.is_null(), 0);
if (compress) {
BlockSerializer::SerializeResult res = BlockSerializer::serialize_and_compress(voxel_buffer->get_buffer());
ERR_FAIL_COND_V(!res.success, -1);
stream_peer_put_data(**peer, to_span(res.data));
return res.data.size();
} else {
BlockSerializer::SerializeResult res = BlockSerializer::serialize(voxel_buffer->get_buffer());
ERR_FAIL_COND_V(!res.success, -1);
stream_peer_put_data(**peer, to_span(res.data));
return res.data.size();
}
}
void VoxelBlockSerializer::deserialize_from_stream_peer(
Ref<StreamPeer> peer,
Ref<VoxelBuffer> voxel_buffer,
int size,
bool decompress
) {
ERR_FAIL_COND(voxel_buffer.is_null());
ERR_FAIL_COND(peer.is_null());
ERR_FAIL_COND(size <= 0);
if (decompress) {
StdVector<uint8_t> &compressed_data = BlockSerializer::get_tls_compressed_data();
compressed_data.resize(size);
const Error err = stream_peer_get_data(**peer, to_span(compressed_data));
ERR_FAIL_COND(err != OK);
const bool success =
BlockSerializer::decompress_and_deserialize(to_span(compressed_data), voxel_buffer->get_buffer());
ERR_FAIL_COND(!success);
} else {
StdVector<uint8_t> &data = BlockSerializer::get_tls_data();
data.resize(size);
const Error err = stream_peer_get_data(**peer, to_span(data));
ERR_FAIL_COND(err != OK);
BlockSerializer::deserialize(to_span(data), voxel_buffer->get_buffer());
}
}
PackedByteArray VoxelBlockSerializer::serialize_to_byte_array(Ref<VoxelBuffer> voxel_buffer, bool compress) {
ERR_FAIL_COND_V(voxel_buffer.is_null(), PackedByteArray());
PackedByteArray bytes;
if (compress) {
BlockSerializer::SerializeResult res = BlockSerializer::serialize_and_compress(voxel_buffer->get_buffer());
ERR_FAIL_COND_V(!res.success, PackedByteArray());
copy_to(bytes, to_span(res.data));
} else {
BlockSerializer::SerializeResult res = BlockSerializer::serialize(voxel_buffer->get_buffer());
ERR_FAIL_COND_V(!res.success, PackedByteArray());
copy_to(bytes, to_span(res.data));
}
return bytes;
}
void VoxelBlockSerializer::deserialize_from_byte_array(
PackedByteArray bytes,
Ref<VoxelBuffer> voxel_buffer,
bool decompress
) {
ERR_FAIL_COND(voxel_buffer.is_null());
ERR_FAIL_COND(bytes.size() == 0);
Span<const uint8_t> bytes_span = Span<const uint8_t>(bytes.ptr(), bytes.size());
if (decompress) {
const bool success = BlockSerializer::decompress_and_deserialize(bytes_span, voxel_buffer->get_buffer());
ERR_FAIL_COND(!success);
} else {
BlockSerializer::deserialize(bytes_span, voxel_buffer->get_buffer());
}
}
void VoxelBlockSerializer::_bind_methods() {
auto cname = VoxelBlockSerializer::get_class_static();
// Reasons for using methods with StreamPeer:
// - Convenience, if you do write to a peer already
// - Avoiding an allocation. When serializing to a PackedByteArray, the Godot API incurs allocating that
// temporary array every time.
ClassDB::bind_static_method(
cname,
D_METHOD("serialize_to_stream_peer", "peer", "voxel_buffer", "compress"),
&VoxelBlockSerializer::serialize_to_stream_peer
);
ClassDB::bind_static_method(
cname,
D_METHOD("deserialize_from_stream_peer", "peer", "voxel_buffer", "size", "decompress"),
&VoxelBlockSerializer::deserialize_from_stream_peer
);
ClassDB::bind_static_method(
cname,
D_METHOD("serialize_to_byte_array", "voxel_buffer", "compress"),
&VoxelBlockSerializer::serialize_to_byte_array
);
ClassDB::bind_static_method(
cname,
D_METHOD("deserialize_from_byte_array", "bytes", "voxel_buffer", "decompress"),
&VoxelBlockSerializer::deserialize_from_byte_array
);
}
} // namespace zylann::voxel::godot