@axpecter/lync 1.5.2 → 2.1.0
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 +499 -357
- package/package.json +2 -2
- package/src/Types.luau +69 -27
- package/src/api/Group.luau +101 -106
- package/src/api/Packet.luau +191 -157
- package/src/api/Query.luau +223 -282
- package/src/api/Scope.luau +46 -57
- package/src/api/Signal.luau +104 -137
- package/src/codec/Base.luau +69 -20
- package/src/codec/composite/Array.luau +189 -201
- package/src/codec/composite/Map.luau +97 -341
- package/src/codec/composite/Optional.luau +27 -23
- package/src/codec/composite/Shared.luau +96 -65
- package/src/codec/composite/Struct.luau +201 -339
- package/src/codec/composite/Tagged.luau +64 -178
- package/src/codec/composite/Tuple.luau +81 -95
- package/src/codec/datatype/Buffer.luau +49 -21
- package/src/codec/datatype/CFrame.luau +207 -30
- package/src/codec/datatype/Color.luau +21 -11
- package/src/codec/datatype/Instance.luau +29 -19
- package/src/codec/datatype/IntVector.luau +33 -21
- package/src/codec/datatype/NumberRange.luau +19 -10
- package/src/codec/datatype/Ray.luau +26 -22
- package/src/codec/datatype/Rect.luau +20 -16
- package/src/codec/datatype/Region.luau +51 -45
- package/src/codec/datatype/Sequence.luau +64 -56
- package/src/codec/datatype/String.luau +89 -56
- package/src/codec/datatype/UDim.luau +40 -22
- package/src/codec/datatype/Vector.luau +181 -17
- package/src/codec/meta/Auto.luau +295 -253
- package/src/codec/meta/Bitfield.luau +104 -148
- package/src/codec/meta/Custom.luau +8 -4
- package/src/codec/meta/Enum.luau +29 -57
- package/src/codec/meta/Float.luau +64 -0
- package/src/codec/meta/Nothing.luau +9 -5
- package/src/codec/meta/Unknown.luau +44 -35
- package/src/codec/primitive/Bool.luau +16 -26
- package/src/codec/primitive/Float16.luau +58 -64
- package/src/codec/primitive/Int.luau +68 -0
- package/src/codec/primitive/Number.luau +21 -43
- package/src/codec/primitive/Varint.luau +67 -46
- package/src/index.d.ts +249 -306
- package/src/init.luau +332 -173
- package/src/internal/Baseline.luau +29 -24
- package/src/internal/Channel.luau +346 -161
- package/src/internal/Middleware.luau +60 -85
- package/src/internal/Pool.luau +19 -30
- package/src/internal/Registry.luau +61 -101
- package/src/transport/Bridge.luau +64 -43
- package/src/transport/Client.luau +60 -117
- package/src/transport/Gate.luau +282 -133
- package/src/transport/Reader.luau +159 -100
- package/src/transport/Server.luau +147 -292
- package/src/api/Namespace.luau +0 -251
- package/src/codec/meta/Quantized.luau +0 -174
|
@@ -1,192 +1,148 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!native
|
|
3
|
-
--
|
|
3
|
+
-- Sub-byte packing. 1 to 32 bits across bool/uint/int fields.
|
|
4
4
|
|
|
5
|
-
local
|
|
6
|
-
local Types = require(script.Parent.Parent.Parent.Types)
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
type Codec<T> = Types.Codec<T>
|
|
10
|
-
|
|
11
|
-
local alloc = Channel.alloc
|
|
12
|
-
|
|
13
|
-
-- Constants -----------------------------------------------------------
|
|
7
|
+
-- Private -------------------------------------------------------------
|
|
14
8
|
|
|
15
9
|
local band = bit32.band
|
|
16
10
|
local bor = bit32.bor
|
|
17
11
|
local lshift = bit32.lshift
|
|
18
12
|
local rshift = bit32.rshift
|
|
19
13
|
|
|
20
|
-
--
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
width: number?,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
local function selectIO(bytes: number): ((b: buffer, offset: number, v: number) -> (), (
|
|
28
|
-
b: buffer,
|
|
29
|
-
offset: number
|
|
30
|
-
) -> number)
|
|
31
|
-
if bytes == 1 then
|
|
32
|
-
return buffer.writeu8, buffer.readu8
|
|
33
|
-
end
|
|
34
|
-
if bytes == 2 then
|
|
35
|
-
return buffer.writeu16, buffer.readu16
|
|
36
|
-
end
|
|
37
|
-
return buffer.writeu32, buffer.readu32
|
|
38
|
-
end
|
|
14
|
+
-- Field type constants
|
|
15
|
+
local TYPE_BOOL = 0
|
|
16
|
+
local TYPE_UINT = 1
|
|
17
|
+
local TYPE_INT = 2
|
|
39
18
|
|
|
40
19
|
-- Public --------------------------------------------------------------
|
|
41
20
|
|
|
42
21
|
local Bitfield = {}
|
|
43
22
|
|
|
44
|
-
function Bitfield.define(schema: { [string]:
|
|
45
|
-
|
|
46
|
-
|
|
23
|
+
function Bitfield.define(schema: { [string]: { type: string, width: number? } }): any
|
|
24
|
+
-- Collect and sort keys alphabetically
|
|
25
|
+
local keys = {}
|
|
47
26
|
for key in schema do
|
|
48
|
-
table.insert(
|
|
27
|
+
table.insert(keys, key)
|
|
49
28
|
end
|
|
29
|
+
table.sort(keys)
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
local count = #sortedKeys
|
|
54
|
-
if count == 0 then
|
|
55
|
-
error("[Lync] Bitfield requires at least one field")
|
|
31
|
+
if #keys == 0 then
|
|
32
|
+
error("[Lync] Lync.bitfield: requires at least one field")
|
|
56
33
|
end
|
|
57
34
|
|
|
58
|
-
local
|
|
59
|
-
local
|
|
60
|
-
local
|
|
61
|
-
local
|
|
62
|
-
|
|
63
|
-
local
|
|
64
|
-
local
|
|
65
|
-
local signExtends = nil :: { number }?
|
|
66
|
-
|
|
35
|
+
local fieldCount = #keys
|
|
36
|
+
local fieldKeys = table.create(fieldCount)
|
|
37
|
+
local fieldTypes = table.create(fieldCount)
|
|
38
|
+
local fieldOffsets = table.create(fieldCount)
|
|
39
|
+
local fieldMasks = table.create(fieldCount)
|
|
40
|
+
local fieldSignBit = table.create(fieldCount)
|
|
41
|
+
local fieldSignExt = table.create(fieldCount)
|
|
67
42
|
local totalBits = 0
|
|
68
|
-
for i = 1, count do
|
|
69
|
-
local key = sortedKeys[i]
|
|
70
|
-
local spec = schema[key]
|
|
71
|
-
local specIsBool = spec.type == "bool"
|
|
72
|
-
local specIsSigned = spec.type == "int"
|
|
73
|
-
local width: number
|
|
74
43
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
44
|
+
for i = 1, fieldCount do
|
|
45
|
+
local key = keys[i]
|
|
46
|
+
local spec = schema[key]
|
|
47
|
+
fieldKeys[i] = key
|
|
48
|
+
fieldOffsets[i] = totalBits
|
|
49
|
+
|
|
50
|
+
if spec.type == "bool" then
|
|
51
|
+
fieldTypes[i] = TYPE_BOOL
|
|
52
|
+
fieldMasks[i] = 1
|
|
53
|
+
fieldSignBit[i] = 0
|
|
54
|
+
fieldSignExt[i] = 0
|
|
55
|
+
totalBits += 1
|
|
56
|
+
elseif spec.type == "uint" then
|
|
57
|
+
local width = spec.width
|
|
58
|
+
if not width or width < 1 or width > 32 then
|
|
59
|
+
error(`[Lync] Lync.bitfield: field "{key}" uint width must be 1-32`)
|
|
80
60
|
end
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
61
|
+
fieldTypes[i] = TYPE_UINT
|
|
62
|
+
fieldMasks[i] = lshift(1, width) - 1
|
|
63
|
+
fieldSignBit[i] = 0
|
|
64
|
+
fieldSignExt[i] = 0
|
|
65
|
+
totalBits += width
|
|
66
|
+
elseif spec.type == "int" then
|
|
67
|
+
local width = spec.width
|
|
68
|
+
if not width or width < 2 or width > 32 then
|
|
69
|
+
error(`[Lync] Lync.bitfield: field "{key}" int width must be 2-32`)
|
|
84
70
|
end
|
|
71
|
+
fieldTypes[i] = TYPE_INT
|
|
72
|
+
fieldMasks[i] = lshift(1, width) - 1
|
|
73
|
+
fieldSignBit[i] = lshift(1, width - 1)
|
|
74
|
+
fieldSignExt[i] = lshift(1, width)
|
|
75
|
+
totalBits += width
|
|
76
|
+
else
|
|
77
|
+
error(`[Lync] Lync.bitfield: unknown field type "{spec.type}"`)
|
|
85
78
|
end
|
|
86
|
-
|
|
87
|
-
if specIsSigned then
|
|
88
|
-
hasSigned = true
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
keys[i] = key
|
|
92
|
-
isBool[i] = specIsBool
|
|
93
|
-
offsets[i] = totalBits
|
|
94
|
-
masks[i] = lshift(1, width) - 1
|
|
95
|
-
totalBits += width
|
|
96
79
|
end
|
|
97
80
|
|
|
98
81
|
if totalBits > 32 then
|
|
99
|
-
error(`[Lync]
|
|
82
|
+
error(`[Lync] Lync.bitfield: total exceeds 32 bits ({totalBits})`)
|
|
100
83
|
end
|
|
101
84
|
|
|
102
|
-
--
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
table.freeze(signExtends :: { number })
|
|
85
|
+
-- Determine wire size
|
|
86
|
+
local wireBytes: number
|
|
87
|
+
local wfn: (buffer, number, number) -> ()
|
|
88
|
+
local rfn: (buffer, number) -> number
|
|
89
|
+
|
|
90
|
+
if totalBits <= 8 then
|
|
91
|
+
wireBytes = 1
|
|
92
|
+
wfn = buffer.writeu8
|
|
93
|
+
rfn = buffer.readu8
|
|
94
|
+
elseif totalBits <= 16 then
|
|
95
|
+
wireBytes = 2
|
|
96
|
+
wfn = buffer.writeu16
|
|
97
|
+
rfn = buffer.readu16
|
|
98
|
+
else
|
|
99
|
+
wireBytes = 4
|
|
100
|
+
wfn = buffer.writeu32
|
|
101
|
+
rfn = buffer.readu32
|
|
120
102
|
end
|
|
121
103
|
|
|
122
|
-
|
|
123
|
-
table.freeze(
|
|
124
|
-
table.freeze(
|
|
125
|
-
table.freeze(
|
|
104
|
+
-- Freeze all descriptor arrays
|
|
105
|
+
table.freeze(fieldKeys)
|
|
106
|
+
table.freeze(fieldTypes)
|
|
107
|
+
table.freeze(fieldOffsets)
|
|
108
|
+
table.freeze(fieldMasks)
|
|
109
|
+
table.freeze(fieldSignBit)
|
|
110
|
+
table.freeze(fieldSignExt)
|
|
126
111
|
|
|
127
|
-
|
|
128
|
-
local wfn, rfn = selectIO(bytes)
|
|
129
|
-
|
|
130
|
-
-- Shared pack logic
|
|
131
|
-
local function packValue(value: any): number
|
|
112
|
+
return Base.define(wireBytes, function(b: buffer, off: number, value: any): ()
|
|
132
113
|
local packed = 0
|
|
133
|
-
for i = 1,
|
|
134
|
-
local
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
114
|
+
for i = 1, fieldCount do
|
|
115
|
+
local v = value[fieldKeys[i]]
|
|
116
|
+
if fieldTypes[i] == TYPE_BOOL then
|
|
117
|
+
if v then
|
|
118
|
+
packed = bor(packed, lshift(1, fieldOffsets[i]))
|
|
119
|
+
end
|
|
120
|
+
else
|
|
121
|
+
packed = bor(packed, lshift(band(v, fieldMasks[i]), fieldOffsets[i]))
|
|
122
|
+
end
|
|
138
123
|
end
|
|
139
|
-
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
local raw = band(rshift(packed, offsets[i]), masks[i])
|
|
152
|
-
if isBool[i] then
|
|
153
|
-
result[keys[i]] = raw ~= 0
|
|
154
|
-
elseif sb[i] > 0 and raw >= sb[i] then
|
|
155
|
-
result[keys[i]] = raw - se[i]
|
|
124
|
+
wfn(b, off, packed)
|
|
125
|
+
end, function(b: buffer, off: number): any
|
|
126
|
+
local packed = rfn(b, off)
|
|
127
|
+
local result: { [string]: any } = {}
|
|
128
|
+
|
|
129
|
+
for i = 1, fieldCount do
|
|
130
|
+
local raw = band(rshift(packed, fieldOffsets[i]), fieldMasks[i])
|
|
131
|
+
if fieldTypes[i] == TYPE_BOOL then
|
|
132
|
+
result[fieldKeys[i]] = raw ~= 0
|
|
133
|
+
elseif fieldTypes[i] == TYPE_INT then
|
|
134
|
+
if raw >= fieldSignBit[i] then
|
|
135
|
+
result[fieldKeys[i]] = raw - fieldSignExt[i]
|
|
156
136
|
else
|
|
157
|
-
result[
|
|
137
|
+
result[fieldKeys[i]] = raw
|
|
158
138
|
end
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
for i = 1, count do
|
|
162
|
-
local raw = band(rshift(packed, offsets[i]), masks[i])
|
|
163
|
-
result[keys[i]] = if isBool[i] then raw ~= 0 else raw
|
|
139
|
+
else
|
|
140
|
+
result[fieldKeys[i]] = raw
|
|
164
141
|
end
|
|
165
142
|
end
|
|
166
143
|
|
|
167
144
|
return result
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
return table.freeze({
|
|
171
|
-
_size = bytes,
|
|
172
|
-
_directWrite = function(b: buffer, offset: number, value: any): ()
|
|
173
|
-
wfn(b, offset, packValue(value))
|
|
174
|
-
end,
|
|
175
|
-
_directRead = function(b: buffer, offset: number): any
|
|
176
|
-
return unpackValue(rfn(b, offset))
|
|
177
|
-
end,
|
|
178
|
-
write = function(ch: ChannelState, value: any): ()
|
|
179
|
-
local c = ch.cursor
|
|
180
|
-
if c + bytes > ch.size then
|
|
181
|
-
alloc(ch, bytes)
|
|
182
|
-
end
|
|
183
|
-
wfn(ch.buff, c, packValue(value))
|
|
184
|
-
ch.cursor = c + bytes
|
|
185
|
-
end,
|
|
186
|
-
read = function(src: buffer, pos: number, _refs: { Instance }?): (any, number)
|
|
187
|
-
return unpackValue(rfn(src, pos)), bytes
|
|
188
|
-
end,
|
|
189
|
-
})
|
|
145
|
+
end)
|
|
190
146
|
end
|
|
191
147
|
|
|
192
148
|
return table.freeze(Bitfield)
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- User-defined fixed-size codec
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- User-defined fixed-size codec.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
|
|
7
|
+
-- Private -------------------------------------------------------------
|
|
8
|
+
|
|
7
9
|
local floor = math.floor
|
|
8
10
|
|
|
11
|
+
-- Public --------------------------------------------------------------
|
|
12
|
+
|
|
9
13
|
local Custom = {}
|
|
10
14
|
|
|
11
15
|
function Custom.define(
|
|
@@ -13,8 +17,8 @@ function Custom.define(
|
|
|
13
17
|
writeFn: (b: buffer, offset: number, value: any) -> (),
|
|
14
18
|
readFn: (b: buffer, offset: number) -> any
|
|
15
19
|
): any
|
|
16
|
-
if size
|
|
17
|
-
error(
|
|
20
|
+
if type(size) ~= "number" or size < 0 or floor(size) ~= size then
|
|
21
|
+
error("[Lync] Lync.custom: size must be a non-negative integer")
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
if size == 0 then
|
package/src/codec/meta/Enum.luau
CHANGED
|
@@ -1,81 +1,53 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- String enum codec. Maps values to u8 indices at
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- String enum codec. Maps values to u8 indices at define time.
|
|
4
4
|
|
|
5
|
-
local
|
|
6
|
-
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
|
-
|
|
8
|
-
type ChannelState = Types.ChannelState
|
|
9
|
-
type Codec<T> = Types.Codec<T>
|
|
10
|
-
|
|
11
|
-
local alloc = Channel.alloc
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
12
6
|
|
|
13
7
|
-- Public --------------------------------------------------------------
|
|
14
8
|
|
|
15
9
|
local EnumCodec = {}
|
|
16
10
|
|
|
17
|
-
function EnumCodec.define(...: string):
|
|
11
|
+
function EnumCodec.define(...: string): any
|
|
18
12
|
local values = { ... }
|
|
19
13
|
local count = #values
|
|
20
14
|
if count == 0 then
|
|
21
|
-
error("[Lync]
|
|
15
|
+
error("[Lync] Lync.enum: requires at least one value")
|
|
22
16
|
end
|
|
23
17
|
if count > 256 then
|
|
24
|
-
error(
|
|
18
|
+
error("[Lync] Lync.enum: exceeds 256 variants")
|
|
25
19
|
end
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
local
|
|
21
|
+
-- Build lookup tables
|
|
22
|
+
local toIndex: { [string]: number } = {}
|
|
23
|
+
local toValue = table.create(count)
|
|
29
24
|
|
|
30
|
-
for i
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
for i = 1, count do
|
|
26
|
+
local val = values[i]
|
|
27
|
+
if toIndex[val] then
|
|
28
|
+
error(`[Lync] Lync.enum: duplicate value "{val}"`)
|
|
33
29
|
end
|
|
34
|
-
toIndex[
|
|
35
|
-
toValue[i] =
|
|
30
|
+
toIndex[val] = i - 1
|
|
31
|
+
toValue[i] = val
|
|
36
32
|
end
|
|
37
33
|
|
|
38
34
|
table.freeze(toIndex)
|
|
39
35
|
table.freeze(toValue)
|
|
40
36
|
|
|
41
|
-
return
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
end
|
|
56
|
-
return value
|
|
57
|
-
end,
|
|
58
|
-
write = function(ch: ChannelState, value: string): ()
|
|
59
|
-
local idx = toIndex[value]
|
|
60
|
-
if idx == nil then
|
|
61
|
-
error(`[Lync] Invalid enum value: "{value}"`)
|
|
62
|
-
end
|
|
63
|
-
local c = ch.cursor
|
|
64
|
-
if c + 1 > ch.size then
|
|
65
|
-
alloc(ch, 1)
|
|
66
|
-
end
|
|
67
|
-
buffer.writeu8(ch.buff, c, idx)
|
|
68
|
-
ch.cursor = c + 1
|
|
69
|
-
end,
|
|
70
|
-
read = function(src: buffer, pos: number, _refs: { Instance }?): (string, number)
|
|
71
|
-
local idx = buffer.readu8(src, pos)
|
|
72
|
-
local value = toValue[idx + 1]
|
|
73
|
-
if value == nil then
|
|
74
|
-
error(`[Lync] Invalid enum index: {idx}`)
|
|
75
|
-
end
|
|
76
|
-
return value, 1
|
|
77
|
-
end,
|
|
78
|
-
})
|
|
37
|
+
return Base.define(1, function(b: buffer, off: number, value: string): ()
|
|
38
|
+
local idx = toIndex[value]
|
|
39
|
+
if idx == nil then
|
|
40
|
+
error(`[Lync] Enum: invalid value "{value}"`)
|
|
41
|
+
end
|
|
42
|
+
buffer.writeu8(b, off, idx)
|
|
43
|
+
end, function(b: buffer, off: number): string
|
|
44
|
+
local idx = buffer.readu8(b, off)
|
|
45
|
+
local val = toValue[idx + 1]
|
|
46
|
+
if val == nil then
|
|
47
|
+
error(`[Lync] Enum: invalid index {idx}`)
|
|
48
|
+
end
|
|
49
|
+
return val
|
|
50
|
+
end, { _typeCheck = "string" })
|
|
79
51
|
end
|
|
80
52
|
|
|
81
53
|
return table.freeze(EnumCodec)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!native
|
|
3
|
+
-- Fixed-point quantization codec. Maps float ranges to integer ranges.
|
|
4
|
+
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
6
|
+
|
|
7
|
+
-- Private -------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
local ceil = math.ceil
|
|
10
|
+
local clamp = math.clamp
|
|
11
|
+
local round = math.round
|
|
12
|
+
local max = math.max
|
|
13
|
+
local min = math.min
|
|
14
|
+
|
|
15
|
+
-- Public --------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
local Float = {}
|
|
18
|
+
|
|
19
|
+
function Float.float(rangeMin: number, rangeMax: number, precision: number): any
|
|
20
|
+
if rangeMin > rangeMax then
|
|
21
|
+
error(`[Lync] Lync.float: min ({rangeMin}) must be <= max ({rangeMax})`)
|
|
22
|
+
end
|
|
23
|
+
if precision <= 0 then
|
|
24
|
+
error("[Lync] Lync.float: precision must be positive")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
local delta = rangeMax - rangeMin
|
|
28
|
+
|
|
29
|
+
-- Constant value: zero bytes
|
|
30
|
+
if delta == 0 then
|
|
31
|
+
return Base.zero()
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
local maxInt = min(0xFFFFFFFF, max(1, ceil(delta / precision)))
|
|
35
|
+
|
|
36
|
+
local compBytes: number
|
|
37
|
+
local wfn: (buffer, number, number) -> ()
|
|
38
|
+
local rfn: (buffer, number) -> number
|
|
39
|
+
|
|
40
|
+
if maxInt <= 0xFF then
|
|
41
|
+
compBytes = 1
|
|
42
|
+
wfn = buffer.writeu8
|
|
43
|
+
rfn = buffer.readu8
|
|
44
|
+
elseif maxInt <= 0xFFFF then
|
|
45
|
+
compBytes = 2
|
|
46
|
+
wfn = buffer.writeu16
|
|
47
|
+
rfn = buffer.readu16
|
|
48
|
+
else
|
|
49
|
+
compBytes = 4
|
|
50
|
+
wfn = buffer.writeu32
|
|
51
|
+
rfn = buffer.readu32
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
local scale = maxInt / delta
|
|
55
|
+
local invScale = delta / maxInt
|
|
56
|
+
|
|
57
|
+
return Base.define(compBytes, function(b: buffer, off: number, value: number): ()
|
|
58
|
+
wfn(b, off, round(clamp(value - rangeMin, 0, delta) * scale))
|
|
59
|
+
end, function(b: buffer, off: number): number
|
|
60
|
+
return rfn(b, off) * invScale + rangeMin
|
|
61
|
+
end, { _min = rangeMin, _max = rangeMax, _typeCheck = "number" })
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return table.freeze(Float)
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- Zero-byte codec. Reads nil.
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- Zero-byte codec. Reads nil. For fire-and-forget signals.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
-- Public --------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
local Nothing = {}
|
|
10
|
+
|
|
11
|
+
Nothing.nothing = Base.zero()
|
|
12
|
+
|
|
13
|
+
return table.freeze(Nothing)
|
|
@@ -1,39 +1,48 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
--
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- Bypasses buffer serialization. Uses Roblox remote sidecar refs.
|
|
4
4
|
|
|
5
|
-
local
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
local alloc =
|
|
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
|
-
|
|
8
|
+
-- Private -------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
local alloc = Base.alloc
|
|
11
|
+
local writeu16 = buffer.writeu16
|
|
12
|
+
local readu16 = buffer.readu16
|
|
13
|
+
|
|
14
|
+
-- Public --------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
local Unknown = {}
|
|
17
|
+
|
|
18
|
+
Unknown.unknown = table.freeze({
|
|
19
|
+
_hasUnknown = true,
|
|
20
|
+
|
|
21
|
+
write = function(ch: Types.ChannelState, value: any): ()
|
|
22
|
+
local idx = ch.refCount + 1
|
|
23
|
+
if idx > 0xFFFF then
|
|
24
|
+
error("[Lync] Unknown: ref overflow (>65535)")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
ch.refs[idx] = value :: any
|
|
28
|
+
ch.refCount = idx
|
|
29
|
+
|
|
30
|
+
local cursor = ch.cursor
|
|
31
|
+
if cursor + 2 > ch.size then
|
|
32
|
+
alloc(ch, 2)
|
|
33
|
+
end
|
|
34
|
+
writeu16(ch.buff, cursor, idx)
|
|
35
|
+
ch.cursor = cursor + 2
|
|
36
|
+
end,
|
|
37
|
+
|
|
38
|
+
read = function(src: buffer, pos: number, refs: { Instance }?): (any, number)
|
|
39
|
+
if not refs then
|
|
40
|
+
error("[Lync] Unknown: read requires refs array")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
local idx = readu16(src, pos)
|
|
44
|
+
return (refs :: any)[idx], 2
|
|
45
|
+
end,
|
|
46
|
+
} :: any)
|
|
47
|
+
|
|
48
|
+
return table.freeze(Unknown)
|
|
@@ -1,30 +1,20 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- Boolean codec
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- Boolean codec with bitpacking flag for struct and array codecs.
|
|
4
4
|
|
|
5
|
-
local
|
|
6
|
-
local alloc = Channel.alloc
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
local c = ch.cursor
|
|
20
|
-
if c + 1 > ch.size then
|
|
21
|
-
alloc(ch, 1)
|
|
22
|
-
end
|
|
23
|
-
buffer.writeu8(ch.buff, c, if value then 1 else 0)
|
|
24
|
-
ch.cursor = c + 1
|
|
25
|
-
end,
|
|
26
|
-
read = function(src: buffer, pos: number, _refs: { Instance }?): (boolean, number)
|
|
27
|
-
return buffer.readu8(src, pos) ~= 0, 1
|
|
28
|
-
end,
|
|
29
|
-
}),
|
|
7
|
+
-- Public --------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
local Bool = {}
|
|
10
|
+
|
|
11
|
+
Bool.bool = Base.define(1, function(b: buffer, off: number, value: boolean): ()
|
|
12
|
+
buffer.writeu8(b, off, if value then 1 else 0)
|
|
13
|
+
end, function(b: buffer, off: number): boolean
|
|
14
|
+
return buffer.readu8(b, off) ~= 0
|
|
15
|
+
end, {
|
|
16
|
+
_isBool = true,
|
|
17
|
+
_typeCheck = "boolean",
|
|
30
18
|
})
|
|
19
|
+
|
|
20
|
+
return table.freeze(Bool)
|