@axpecter/lync 2.2.1 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -143
- package/package.json +1 -1
- package/src/Types.luau +22 -16
- package/src/api/Group.luau +40 -33
- package/src/api/Packet.luau +68 -54
- package/src/api/Query.luau +103 -65
- package/src/api/Scope.luau +26 -10
- package/src/api/Signal.luau +43 -52
- package/src/codec/Base.luau +21 -14
- package/src/codec/composite/Array.luau +56 -134
- package/src/codec/composite/Map.luau +103 -72
- package/src/codec/composite/Optional.luau +6 -2
- package/src/codec/composite/Shared.luau +160 -69
- package/src/codec/composite/Struct.luau +283 -42
- package/src/codec/composite/Tagged.luau +13 -16
- package/src/codec/composite/Tuple.luau +21 -15
- package/src/codec/datatype/Buffer.luau +6 -4
- package/src/codec/datatype/CFrame.luau +56 -44
- package/src/codec/datatype/Color.luau +10 -10
- package/src/codec/datatype/Instance.luau +15 -12
- package/src/codec/datatype/IntVector.luau +2 -2
- package/src/codec/datatype/NumberRange.luau +15 -8
- package/src/codec/datatype/Ray.luau +13 -14
- package/src/codec/datatype/Rect.luau +12 -12
- package/src/codec/datatype/Region.luau +13 -14
- package/src/codec/datatype/Sequence.luau +87 -65
- package/src/codec/datatype/String.luau +17 -10
- package/src/codec/datatype/UDim.luau +10 -8
- package/src/codec/datatype/Vector.luau +20 -59
- package/src/codec/meta/Auto.luau +94 -126
- package/src/codec/meta/Bitfield.luau +12 -14
- package/src/codec/meta/Custom.luau +3 -1
- package/src/codec/meta/Enum.luau +9 -9
- package/src/codec/meta/Float.luau +6 -28
- package/src/codec/meta/Nothing.luau +1 -1
- package/src/codec/meta/Unknown.luau +10 -7
- package/src/codec/primitive/Bool.luau +6 -4
- package/src/codec/primitive/Float16.luau +5 -2
- package/src/codec/primitive/Int.luau +5 -6
- package/src/codec/primitive/Number.luau +6 -4
- package/src/codec/primitive/Signed.luau +2 -2
- package/src/codec/primitive/Varint.luau +69 -38
- package/src/index.d.ts +161 -53
- package/src/init.luau +109 -103
- package/src/internal/Baseline.luau +9 -1
- package/src/internal/Channel.luau +153 -154
- package/src/internal/Middleware.luau +22 -6
- package/src/internal/Pool.luau +12 -4
- package/src/internal/Registry.luau +25 -16
- package/src/internal/Transport.luau +1 -1
- package/src/transport/Bridge.luau +47 -33
- package/src/transport/Client.luau +25 -21
- package/src/transport/Gate.luau +227 -172
- package/src/transport/Reader.luau +162 -105
- package/src/transport/Server.luau +46 -57
- package/src/util/Array.luau +18 -0
- package/src/util/Buffer.luau +92 -0
- package/src/util/Constants.luau +30 -0
- package/src/util/Log.luau +68 -0
- package/src/util/Player.luau +14 -0
- package/src/util/Quantize.luau +60 -0
- package/src/internal/Util.luau +0 -26
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
2
|
+
--!native
|
|
3
3
|
-- NumberSequence (12B/keypoint) and ColorSequence (7B/keypoint) codecs.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
|
+
local Constants = require(script.Parent.Parent.Parent.util.Constants)
|
|
7
|
+
local Log = require(script.Parent.Parent.Parent.util.Log)
|
|
6
8
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
9
|
local Varint = require(script.Parent.Parent.primitive.Varint)
|
|
8
10
|
|
|
@@ -14,34 +16,88 @@ local MAX_KEYPOINTS = 20
|
|
|
14
16
|
|
|
15
17
|
-- Private ----------------------------------------------------------------
|
|
16
18
|
|
|
19
|
+
local U8_MAX = Constants.U8_MAX
|
|
17
20
|
local alloc = Base.alloc
|
|
21
|
+
local writef32 = buffer.writef32
|
|
22
|
+
local readf32 = buffer.readf32
|
|
23
|
+
local writeu8 = buffer.writeu8
|
|
24
|
+
local readu8 = buffer.readu8
|
|
18
25
|
local round = math.round
|
|
19
26
|
local clamp = math.clamp
|
|
20
|
-
|
|
21
|
-
local
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
local varintRead = Varint.read
|
|
28
|
+
local varintWrite = Varint.write
|
|
29
|
+
|
|
30
|
+
--[[
|
|
31
|
+
Common write prelude: count cap check, varint count, payload alloc.
|
|
32
|
+
Returns (cursor, b) for the per-keypoint writer; (nil, nil) when count
|
|
33
|
+
is 0 so callers short-circuit.
|
|
34
|
+
]]
|
|
35
|
+
local function beginSeqWrite(
|
|
36
|
+
ch: Types.ChannelState,
|
|
37
|
+
label: string,
|
|
38
|
+
count: number,
|
|
39
|
+
kpBytes: number
|
|
40
|
+
): (number?, buffer?)
|
|
41
|
+
if count > MAX_KEYPOINTS then
|
|
42
|
+
Log.error(`{label}.write: keypoint count {count} exceeds Roblox limit {MAX_KEYPOINTS}`)
|
|
43
|
+
end
|
|
44
|
+
varintWrite(ch, count)
|
|
25
45
|
if count == 0 then
|
|
26
|
-
return
|
|
46
|
+
return nil, nil
|
|
27
47
|
end
|
|
28
48
|
|
|
29
|
-
local bytes = count *
|
|
49
|
+
local bytes = count * kpBytes
|
|
30
50
|
local cursor = ch.cursor
|
|
31
51
|
if cursor + bytes > ch.size then
|
|
32
52
|
alloc(ch, bytes)
|
|
33
53
|
end
|
|
34
|
-
|
|
54
|
+
ch.cursor = cursor + bytes
|
|
55
|
+
return cursor, ch.buff
|
|
56
|
+
end
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
--[[
|
|
59
|
+
Common read prelude: varint count, cap check, bounds check. Returns
|
|
60
|
+
(count, dataStart, lenBytes) for the per-keypoint reader; (0, _, lenBytes)
|
|
61
|
+
when payload is empty.
|
|
62
|
+
]]
|
|
63
|
+
local function beginSeqRead(
|
|
64
|
+
src: buffer,
|
|
65
|
+
pos: number,
|
|
66
|
+
label: string,
|
|
67
|
+
kpBytes: number
|
|
68
|
+
): (number, number, number)
|
|
69
|
+
local count, lenBytes = varintRead(src, pos)
|
|
70
|
+
if count == 0 then
|
|
71
|
+
return 0, pos + lenBytes, lenBytes
|
|
72
|
+
end
|
|
73
|
+
if count > MAX_KEYPOINTS then
|
|
74
|
+
Log.error(`{label}.read: keypoint count {count} exceeds Roblox limit {MAX_KEYPOINTS}`)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
local bytes = count * kpBytes
|
|
78
|
+
local dataStart = pos + lenBytes
|
|
79
|
+
if dataStart + bytes > buffer.len(src) then
|
|
80
|
+
Log.error(`{label}.read: payload {bytes}B exceeds remaining buffer`)
|
|
81
|
+
end
|
|
82
|
+
return count, dataStart, lenBytes
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
local function writeNumberSequence(ch: Types.ChannelState, value: NumberSequence): ()
|
|
86
|
+
local keypoints = value.Keypoints
|
|
87
|
+
local count = #keypoints
|
|
88
|
+
local cursor, b = beginSeqWrite(ch, "NumberSequence", count, NUMSEQ_KP_BYTES)
|
|
89
|
+
if not cursor then
|
|
90
|
+
return
|
|
91
|
+
end
|
|
92
|
+
local off = cursor :: number
|
|
93
|
+
local buf = b :: buffer
|
|
37
94
|
for i = 1, count do
|
|
38
95
|
local kp = keypoints[i]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
96
|
+
writef32(buf, off, kp.Time)
|
|
97
|
+
writef32(buf, off + 4, kp.Value)
|
|
98
|
+
writef32(buf, off + 8, kp.Envelope)
|
|
42
99
|
off += NUMSEQ_KP_BYTES
|
|
43
100
|
end
|
|
44
|
-
ch.cursor = cursor + bytes
|
|
45
101
|
end
|
|
46
102
|
|
|
47
103
|
local function readNumberSequence(
|
|
@@ -49,61 +105,42 @@ local function readNumberSequence(
|
|
|
49
105
|
pos: number,
|
|
50
106
|
_refs: { Instance }?
|
|
51
107
|
): (NumberSequence, number)
|
|
52
|
-
local count, lenBytes =
|
|
108
|
+
local count, dataStart, lenBytes = beginSeqRead(src, pos, "NumberSequence", NUMSEQ_KP_BYTES)
|
|
53
109
|
if count == 0 then
|
|
54
110
|
return NumberSequence.new(0), lenBytes
|
|
55
111
|
end
|
|
56
|
-
if count > MAX_KEYPOINTS then
|
|
57
|
-
error(
|
|
58
|
-
`[Lync] NumberSequence.read: keypoint count {count} exceeds Roblox limit {MAX_KEYPOINTS}`
|
|
59
|
-
)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
local bytes = count * NUMSEQ_KP_BYTES
|
|
63
|
-
local dataStart = pos + lenBytes
|
|
64
|
-
if dataStart + bytes > buffer.len(src) then
|
|
65
|
-
error("[Lync] NumberSequence.read: data exceeds buffer")
|
|
66
|
-
end
|
|
67
112
|
|
|
68
113
|
local keypoints = table.create(count)
|
|
69
114
|
local off = dataStart
|
|
70
115
|
for i = 1, count do
|
|
71
116
|
keypoints[i] = NumberSequenceKeypoint.new(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
117
|
+
readf32(src, off),
|
|
118
|
+
readf32(src, off + 4),
|
|
119
|
+
readf32(src, off + 8)
|
|
75
120
|
)
|
|
76
121
|
off += NUMSEQ_KP_BYTES
|
|
77
122
|
end
|
|
78
|
-
return NumberSequence.new(keypoints), lenBytes +
|
|
123
|
+
return NumberSequence.new(keypoints), lenBytes + count * NUMSEQ_KP_BYTES
|
|
79
124
|
end
|
|
80
125
|
|
|
81
126
|
local function writeColorSequence(ch: Types.ChannelState, value: ColorSequence): ()
|
|
82
127
|
local keypoints = value.Keypoints
|
|
83
128
|
local count = #keypoints
|
|
84
|
-
|
|
85
|
-
if
|
|
129
|
+
local cursor, b = beginSeqWrite(ch, "ColorSequence", count, COLSEQ_KP_BYTES)
|
|
130
|
+
if not cursor then
|
|
86
131
|
return
|
|
87
132
|
end
|
|
88
|
-
|
|
89
|
-
local
|
|
90
|
-
local cursor = ch.cursor
|
|
91
|
-
if cursor + bytes > ch.size then
|
|
92
|
-
alloc(ch, bytes)
|
|
93
|
-
end
|
|
94
|
-
local b = ch.buff
|
|
95
|
-
|
|
96
|
-
local off = cursor
|
|
133
|
+
local off = cursor :: number
|
|
134
|
+
local buf = b :: buffer
|
|
97
135
|
for i = 1, count do
|
|
98
136
|
local kp = keypoints[i]
|
|
99
137
|
local c = kp.Value
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
138
|
+
writef32(buf, off, kp.Time)
|
|
139
|
+
writeu8(buf, off + 4, round(clamp(c.R, 0, 1) * U8_MAX))
|
|
140
|
+
writeu8(buf, off + 5, round(clamp(c.G, 0, 1) * U8_MAX))
|
|
141
|
+
writeu8(buf, off + 6, round(clamp(c.B, 0, 1) * U8_MAX))
|
|
104
142
|
off += COLSEQ_KP_BYTES
|
|
105
143
|
end
|
|
106
|
-
ch.cursor = cursor + bytes
|
|
107
144
|
end
|
|
108
145
|
|
|
109
146
|
local function readColorSequence(
|
|
@@ -111,36 +148,21 @@ local function readColorSequence(
|
|
|
111
148
|
pos: number,
|
|
112
149
|
_refs: { Instance }?
|
|
113
150
|
): (ColorSequence, number)
|
|
114
|
-
local count, lenBytes =
|
|
151
|
+
local count, dataStart, lenBytes = beginSeqRead(src, pos, "ColorSequence", COLSEQ_KP_BYTES)
|
|
115
152
|
if count == 0 then
|
|
116
153
|
return ColorSequence.new(Color3.new()), lenBytes
|
|
117
154
|
end
|
|
118
|
-
if count > MAX_KEYPOINTS then
|
|
119
|
-
error(
|
|
120
|
-
`[Lync] ColorSequence.read: keypoint count {count} exceeds Roblox limit {MAX_KEYPOINTS}`
|
|
121
|
-
)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
local bytes = count * COLSEQ_KP_BYTES
|
|
125
|
-
local dataStart = pos + lenBytes
|
|
126
|
-
if dataStart + bytes > buffer.len(src) then
|
|
127
|
-
error("[Lync] ColorSequence.read: data exceeds buffer")
|
|
128
|
-
end
|
|
129
155
|
|
|
130
156
|
local keypoints = table.create(count)
|
|
131
157
|
local off = dataStart
|
|
132
158
|
for i = 1, count do
|
|
133
159
|
keypoints[i] = ColorSequenceKeypoint.new(
|
|
134
|
-
|
|
135
|
-
Color3.fromRGB(
|
|
136
|
-
buffer.readu8(src, off + 4),
|
|
137
|
-
buffer.readu8(src, off + 5),
|
|
138
|
-
buffer.readu8(src, off + 6)
|
|
139
|
-
)
|
|
160
|
+
readf32(src, off),
|
|
161
|
+
Color3.fromRGB(readu8(src, off + 4), readu8(src, off + 5), readu8(src, off + 6))
|
|
140
162
|
)
|
|
141
163
|
off += COLSEQ_KP_BYTES
|
|
142
164
|
end
|
|
143
|
-
return ColorSequence.new(keypoints), lenBytes +
|
|
165
|
+
return ColorSequence.new(keypoints), lenBytes + count * COLSEQ_KP_BYTES
|
|
144
166
|
end
|
|
145
167
|
|
|
146
168
|
-- Public -----------------------------------------------------------------
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!native
|
|
3
|
-
--
|
|
3
|
+
-- UTF-8 string codec. __call yields a length-bounded variant.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
|
+
local Log = require(script.Parent.Parent.Parent.util.Log)
|
|
6
7
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
8
|
local Varint = require(script.Parent.Parent.primitive.Varint)
|
|
8
9
|
|
|
9
10
|
-- Private ----------------------------------------------------------------
|
|
10
11
|
|
|
11
12
|
local alloc = Base.alloc
|
|
12
|
-
local
|
|
13
|
+
local INLINE_MAX = Varint.INLINE_MAX
|
|
13
14
|
|
|
14
15
|
local function writeString(ch: Types.ChannelState, value: string): ()
|
|
15
16
|
local len = #value
|
|
16
17
|
local cursor = ch.cursor
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
-- Single-byte length fast path skips the full varint encode.
|
|
20
|
+
if len <= INLINE_MAX then
|
|
19
21
|
if cursor + 1 + len > ch.size then
|
|
20
22
|
alloc(ch, 1 + len)
|
|
21
23
|
end
|
|
@@ -47,23 +49,28 @@ local function readString(src: buffer, pos: number, _refs: { Instance }?): (stri
|
|
|
47
49
|
|
|
48
50
|
local dataStart = pos + lenBytes
|
|
49
51
|
if dataStart + len > buffer.len(src) then
|
|
50
|
-
error(
|
|
52
|
+
Log.error(`length {len}B exceeds remaining buffer`)
|
|
51
53
|
end
|
|
52
54
|
return buffer.readstring(src, dataStart, len), lenBytes + len
|
|
53
55
|
end
|
|
54
56
|
|
|
57
|
+
-- _maxStringLength lets Gate.validate reject oversized values send-side.
|
|
55
58
|
local function boundedFactory(_self, maxLength: number): Types.InternalCodec<string>
|
|
56
|
-
|
|
57
|
-
error("[Lync] Lync.string: maxLength must be positive")
|
|
58
|
-
end
|
|
59
|
+
Log.assert(maxLength > 0, "maxLength must be positive")
|
|
59
60
|
|
|
60
61
|
return table.freeze({
|
|
61
62
|
_typeCheck = "string",
|
|
62
|
-
|
|
63
|
+
_maxStringLength = maxLength,
|
|
64
|
+
write = function(ch: Types.ChannelState, value: string): ()
|
|
65
|
+
if #value > maxLength then
|
|
66
|
+
Log.error(`length {#value} exceeds max {maxLength}`)
|
|
67
|
+
end
|
|
68
|
+
writeString(ch, value)
|
|
69
|
+
end,
|
|
63
70
|
read = function(src: buffer, pos: number, _refs: { Instance }?): (string, number)
|
|
64
71
|
local len, lenBytes = readLengthPrefix(src, pos)
|
|
65
72
|
if len > maxLength then
|
|
66
|
-
error(`
|
|
73
|
+
Log.error(`length {len} exceeds max {maxLength}`)
|
|
67
74
|
end
|
|
68
75
|
if len == 0 then
|
|
69
76
|
return "", lenBytes
|
|
@@ -71,7 +78,7 @@ local function boundedFactory(_self, maxLength: number): Types.InternalCodec<str
|
|
|
71
78
|
|
|
72
79
|
local dataStart = pos + lenBytes
|
|
73
80
|
if dataStart + len > buffer.len(src) then
|
|
74
|
-
error(
|
|
81
|
+
Log.error(`length {len}B exceeds remaining buffer`)
|
|
75
82
|
end
|
|
76
83
|
return buffer.readstring(src, dataStart, len), lenBytes + len
|
|
77
84
|
end,
|
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- UDim (
|
|
2
|
+
--!native
|
|
3
|
+
-- UDim (8B) and UDim2 (16B) codecs. Scale = f32, Offset = i32.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
local Signed = require(script.Parent.Parent.primitive.Signed)
|
|
7
7
|
|
|
8
8
|
-- Private ----------------------------------------------------------------
|
|
9
9
|
|
|
10
|
+
local writef32 = buffer.writef32
|
|
11
|
+
local readf32 = buffer.readf32
|
|
10
12
|
local writeI32 = Signed.writeI32
|
|
11
13
|
local readi32 = buffer.readi32
|
|
12
14
|
|
|
13
15
|
local function writeUDim(b: buffer, off: number, value: UDim): ()
|
|
14
|
-
|
|
16
|
+
writef32(b, off, value.Scale)
|
|
15
17
|
writeI32(b, off + 4, value.Offset)
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
local function readUDim(b: buffer, off: number): UDim
|
|
19
|
-
return UDim.new(
|
|
21
|
+
return UDim.new(readf32(b, off), readi32(b, off + 4))
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
local function writeUDim2(b: buffer, off: number, value: UDim2): ()
|
|
23
25
|
local x, y = value.X, value.Y
|
|
24
|
-
|
|
26
|
+
writef32(b, off, x.Scale)
|
|
25
27
|
writeI32(b, off + 4, x.Offset)
|
|
26
|
-
|
|
28
|
+
writef32(b, off + 8, y.Scale)
|
|
27
29
|
writeI32(b, off + 12, y.Offset)
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
local function readUDim2(b: buffer, off: number): UDim2
|
|
31
33
|
return UDim2.new(
|
|
32
|
-
UDim.new(
|
|
33
|
-
UDim.new(
|
|
34
|
+
UDim.new(readf32(b, off), readi32(b, off + 4)),
|
|
35
|
+
UDim.new(readf32(b, off + 8), readi32(b, off + 12))
|
|
34
36
|
)
|
|
35
37
|
end
|
|
36
38
|
|
|
@@ -1,75 +1,36 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- Vector2
|
|
2
|
+
--!native
|
|
3
|
+
-- Vector2 / Vector3 codecs. __call yields a quantized variant.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
|
+
local Quantize = require(script.Parent.Parent.Parent.util.Quantize)
|
|
6
7
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
8
|
|
|
8
9
|
-- Private ----------------------------------------------------------------
|
|
9
10
|
|
|
10
11
|
local alloc = Base.alloc
|
|
11
|
-
local
|
|
12
|
+
local writef32 = buffer.writef32
|
|
13
|
+
local readf32 = buffer.readf32
|
|
12
14
|
local clamp = math.clamp
|
|
13
15
|
local round = math.round
|
|
14
|
-
local maxN = math.max
|
|
15
|
-
local minN = math.min
|
|
16
|
-
|
|
17
|
-
--[[
|
|
18
|
-
Pick the narrowest u8/u16/u32 wire form for a quantized component
|
|
19
|
-
range. Returns (compBytes, writeFn, readFn, scale, invScale).
|
|
20
|
-
]]
|
|
21
|
-
local function quantizeSetup(
|
|
22
|
-
apiName: string,
|
|
23
|
-
rangeMin: number,
|
|
24
|
-
rangeMax: number,
|
|
25
|
-
precision: number
|
|
26
|
-
): (
|
|
27
|
-
number,
|
|
28
|
-
(buffer, number, number) -> (),
|
|
29
|
-
(buffer, number) -> number,
|
|
30
|
-
number,
|
|
31
|
-
number
|
|
32
|
-
)
|
|
33
|
-
if rangeMin > rangeMax then
|
|
34
|
-
error(`[Lync] {apiName}: min must be <= max`)
|
|
35
|
-
end
|
|
36
|
-
if precision <= 0 then
|
|
37
|
-
error(`[Lync] {apiName}: precision must be positive`)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
local delta = rangeMax - rangeMin
|
|
41
|
-
local maxInt = minN(0xFFFFFFFF, maxN(1, ceil(delta / precision)))
|
|
42
|
-
|
|
43
|
-
if maxInt <= 0xFF then
|
|
44
|
-
return 1, buffer.writeu8, buffer.readu8, maxInt / delta, delta / maxInt
|
|
45
|
-
end
|
|
46
|
-
if maxInt <= 0xFFFF then
|
|
47
|
-
return 2, buffer.writeu16, buffer.readu16, maxInt / delta, delta / maxInt
|
|
48
|
-
end
|
|
49
|
-
return 4, buffer.writeu32, buffer.readu32, maxInt / delta, delta / maxInt
|
|
50
|
-
end
|
|
51
16
|
|
|
52
17
|
local function writeVec2(b: buffer, off: number, value: Vector2): ()
|
|
53
|
-
|
|
54
|
-
|
|
18
|
+
writef32(b, off, value.X)
|
|
19
|
+
writef32(b, off + 4, value.Y)
|
|
55
20
|
end
|
|
56
21
|
|
|
57
22
|
local function readVec2(b: buffer, off: number): Vector2
|
|
58
|
-
return Vector2.new(
|
|
23
|
+
return Vector2.new(readf32(b, off), readf32(b, off + 4))
|
|
59
24
|
end
|
|
60
25
|
|
|
61
26
|
local function writeVec3(b: buffer, off: number, value: Vector3): ()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
27
|
+
writef32(b, off, value.X)
|
|
28
|
+
writef32(b, off + 4, value.Y)
|
|
29
|
+
writef32(b, off + 8, value.Z)
|
|
65
30
|
end
|
|
66
31
|
|
|
67
32
|
local function readVec3(b: buffer, off: number): Vector3
|
|
68
|
-
return Vector3.new(
|
|
69
|
-
buffer.readf32(b, off),
|
|
70
|
-
buffer.readf32(b, off + 4),
|
|
71
|
-
buffer.readf32(b, off + 8)
|
|
72
|
-
)
|
|
33
|
+
return Vector3.new(readf32(b, off), readf32(b, off + 4), readf32(b, off + 8))
|
|
73
34
|
end
|
|
74
35
|
|
|
75
36
|
local function quantizeVec2(
|
|
@@ -78,14 +39,14 @@ local function quantizeVec2(
|
|
|
78
39
|
rangeMax: number,
|
|
79
40
|
precision: number
|
|
80
41
|
): Types.InternalCodec<Vector2>
|
|
42
|
+
-- Degenerate range: emit nothing, decode to the constant.
|
|
81
43
|
if rangeMax - rangeMin == 0 then
|
|
82
44
|
return Base.constant(Vector2.new(rangeMin, rangeMin))
|
|
83
45
|
end
|
|
84
46
|
|
|
85
|
-
local compBytes, wfn, rfn, scale, invScale =
|
|
86
|
-
|
|
47
|
+
local compBytes, wfn, rfn, scale, invScale, delta =
|
|
48
|
+
Quantize.setup("Lync.vec2", rangeMin, rangeMax, precision)
|
|
87
49
|
local totalSize = compBytes * 2
|
|
88
|
-
local delta = rangeMax - rangeMin
|
|
89
50
|
|
|
90
51
|
return Base.define(totalSize, function(b: buffer, off: number, value: Vector2): ()
|
|
91
52
|
wfn(b, off, round(clamp(value.X - rangeMin, 0, delta) * scale))
|
|
@@ -108,20 +69,20 @@ local function quantizeVec3(
|
|
|
108
69
|
return Base.constant(Vector3.new(rangeMin, rangeMin, rangeMin))
|
|
109
70
|
end
|
|
110
71
|
|
|
111
|
-
local compBytes, wfn, rfn, scale, invScale =
|
|
112
|
-
|
|
72
|
+
local compBytes, wfn, rfn, scale, invScale, delta =
|
|
73
|
+
Quantize.setup("Lync.vec3", rangeMin, rangeMax, precision)
|
|
113
74
|
local totalSize = compBytes * 3
|
|
114
|
-
local
|
|
75
|
+
local off2 = compBytes * 2
|
|
115
76
|
|
|
116
77
|
return Base.define(totalSize, function(b: buffer, off: number, value: Vector3): ()
|
|
117
78
|
wfn(b, off, round(clamp(value.X - rangeMin, 0, delta) * scale))
|
|
118
79
|
wfn(b, off + compBytes, round(clamp(value.Y - rangeMin, 0, delta) * scale))
|
|
119
|
-
wfn(b, off +
|
|
80
|
+
wfn(b, off + off2, round(clamp(value.Z - rangeMin, 0, delta) * scale))
|
|
120
81
|
end, function(b: buffer, off: number): Vector3
|
|
121
82
|
return Vector3.new(
|
|
122
83
|
rfn(b, off) * invScale + rangeMin,
|
|
123
84
|
rfn(b, off + compBytes) * invScale + rangeMin,
|
|
124
|
-
rfn(b, off +
|
|
85
|
+
rfn(b, off + off2) * invScale + rangeMin
|
|
125
86
|
)
|
|
126
87
|
end, { _typeCheck = "Vector3", _min = rangeMin, _max = rangeMax })
|
|
127
88
|
end
|