@axpecter/lync 1.4.3 → 1.5.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 +41 -2
- package/package.json +1 -1
- package/src/Types.luau +13 -1
- package/src/api/Group.luau +35 -28
- package/src/api/Namespace.luau +107 -89
- package/src/api/Packet.luau +86 -55
- package/src/api/Query.luau +101 -95
- package/src/api/Scope.luau +32 -18
- package/src/api/Signal.luau +78 -56
- package/src/codec/Base.luau +17 -17
- package/src/codec/composite/Array.luau +74 -74
- package/src/codec/composite/Map.luau +80 -80
- package/src/codec/composite/Optional.luau +14 -14
- package/src/codec/composite/Shared.luau +35 -35
- package/src/codec/composite/Struct.luau +108 -108
- package/src/codec/composite/Tagged.luau +71 -71
- package/src/codec/composite/Tuple.luau +35 -35
- package/src/codec/datatype/Buffer.luau +18 -18
- package/src/codec/datatype/CFrame.luau +24 -24
- package/src/codec/datatype/Color.luau +8 -12
- package/src/codec/datatype/Instance.luau +13 -13
- package/src/codec/datatype/IntVector.luau +17 -17
- package/src/codec/datatype/NumberRange.luau +7 -7
- package/src/codec/datatype/Ray.luau +16 -16
- package/src/codec/datatype/Rect.luau +13 -13
- package/src/codec/datatype/Region.luau +32 -36
- package/src/codec/datatype/Sequence.luau +41 -41
- package/src/codec/datatype/String.luau +28 -28
- package/src/codec/datatype/UDim.luau +17 -17
- package/src/codec/datatype/Vector.luau +14 -18
- package/src/codec/meta/Auto.luau +75 -73
- package/src/codec/meta/Bitfield.luau +46 -46
- package/src/codec/meta/Custom.luau +7 -7
- package/src/codec/meta/Enum.luau +25 -25
- package/src/codec/meta/Nothing.luau +3 -3
- package/src/codec/meta/Quantized.luau +63 -60
- package/src/codec/meta/Unknown.luau +11 -11
- package/src/codec/primitive/Bool.luau +12 -12
- package/src/codec/primitive/Float16.luau +28 -28
- package/src/codec/primitive/Number.luau +41 -41
- package/src/codec/primitive/Varint.luau +19 -19
- package/src/index.d.ts +2 -2
- package/src/init.luau +81 -61
- package/src/internal/Baseline.luau +7 -7
- package/src/internal/Channel.luau +56 -56
- package/src/internal/Middleware.luau +29 -29
- package/src/internal/Pool.luau +15 -15
- package/src/internal/Registry.luau +19 -19
- package/src/transport/Bridge.luau +17 -17
- package/src/transport/Client.luau +46 -46
- package/src/transport/Gate.luau +56 -64
- package/src/transport/Reader.luau +34 -34
- package/src/transport/Server.luau +89 -89
package/src/codec/meta/Auto.luau
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!native
|
|
3
|
-
-- Auto
|
|
3
|
+
-- Auto(self-describing) codec. Writes a u8 type tag then the value.
|
|
4
4
|
|
|
5
|
-
local BoolCodec = require
|
|
6
|
-
local BufferCodec = require
|
|
7
|
-
local CFrameCodec = require
|
|
8
|
-
local Channel = require
|
|
9
|
-
local ColorCodec = require
|
|
10
|
-
local IntVectorCodec = require
|
|
11
|
-
local NumberCodec = require
|
|
12
|
-
local NumberRangeCodec = require
|
|
13
|
-
local RayCodec = require
|
|
14
|
-
local RectCodec = require
|
|
15
|
-
local RegionCodec = require
|
|
16
|
-
local SequenceCodec = require
|
|
17
|
-
local StringCodec = require
|
|
18
|
-
local Types = require
|
|
19
|
-
local UDimCodec = require
|
|
20
|
-
local Varint = require
|
|
21
|
-
local VectorCodec = require
|
|
5
|
+
local BoolCodec = require(script.Parent.Parent.primitive.Bool)
|
|
6
|
+
local BufferCodec = require(script.Parent.Parent.datatype.Buffer)
|
|
7
|
+
local CFrameCodec = require(script.Parent.Parent.datatype.CFrame)
|
|
8
|
+
local Channel = require(script.Parent.Parent.Parent.internal.Channel)
|
|
9
|
+
local ColorCodec = require(script.Parent.Parent.datatype.Color)
|
|
10
|
+
local IntVectorCodec = require(script.Parent.Parent.datatype.IntVector)
|
|
11
|
+
local NumberCodec = require(script.Parent.Parent.primitive.Number)
|
|
12
|
+
local NumberRangeCodec = require(script.Parent.Parent.datatype.NumberRange)
|
|
13
|
+
local RayCodec = require(script.Parent.Parent.datatype.Ray)
|
|
14
|
+
local RectCodec = require(script.Parent.Parent.datatype.Rect)
|
|
15
|
+
local RegionCodec = require(script.Parent.Parent.datatype.Region)
|
|
16
|
+
local SequenceCodec = require(script.Parent.Parent.datatype.Sequence)
|
|
17
|
+
local StringCodec = require(script.Parent.Parent.datatype.String)
|
|
18
|
+
local Types = require(script.Parent.Parent.Parent.Types)
|
|
19
|
+
local UDimCodec = require(script.Parent.Parent.datatype.UDim)
|
|
20
|
+
local Varint = require(script.Parent.Parent.primitive.Varint)
|
|
21
|
+
local VectorCodec = require(script.Parent.Parent.datatype.Vector)
|
|
22
22
|
|
|
23
23
|
type ChannelState = Types.ChannelState
|
|
24
24
|
type Codec<T> = Types.Codec<T>
|
|
@@ -27,7 +27,7 @@ type InternalCodec<T> = Types.InternalCodec<T>
|
|
|
27
27
|
local alloc = Channel.alloc
|
|
28
28
|
local floor = math.floor
|
|
29
29
|
|
|
30
|
-
-- Constants
|
|
30
|
+
-- Constants -----------------------------------------------------------
|
|
31
31
|
|
|
32
32
|
local TAG_NIL = 0
|
|
33
33
|
local TAG_BOOL = 1
|
|
@@ -57,7 +57,7 @@ local TAG_RAY = 24
|
|
|
57
57
|
local TAG_NUMBERSEQUENCE = 25
|
|
58
58
|
local TAG_COLORSEQUENCE = 26
|
|
59
59
|
|
|
60
|
-
local READ_DISPATCH = table.freeze
|
|
60
|
+
local READ_DISPATCH = table.freeze({
|
|
61
61
|
[TAG_BOOL] = BoolCodec.bool,
|
|
62
62
|
[TAG_U8] = NumberCodec.u8,
|
|
63
63
|
[TAG_U16] = NumberCodec.u16,
|
|
@@ -86,11 +86,11 @@ local READ_DISPATCH = table.freeze ({
|
|
|
86
86
|
[TAG_COLORSEQUENCE] = SequenceCodec.colorSequence,
|
|
87
87
|
})
|
|
88
88
|
|
|
89
|
-
local function extractDw
|
|
89
|
+
local function extractDw(codec: any): any
|
|
90
90
|
return (codec :: InternalCodec<any>)._directWrite
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
local TYPE_DISPATCH = table.freeze
|
|
93
|
+
local TYPE_DISPATCH = table.freeze({
|
|
94
94
|
boolean = { tag = TAG_BOOL, codec = BoolCodec.bool, size = 1, dw = nil },
|
|
95
95
|
string = { tag = TAG_STRING, codec = StringCodec.string, size = nil, dw = nil },
|
|
96
96
|
buffer = { tag = TAG_BUFFER, codec = BufferCodec.buff, size = nil, dw = nil },
|
|
@@ -98,79 +98,79 @@ local TYPE_DISPATCH = table.freeze ({
|
|
|
98
98
|
tag = TAG_VEC2,
|
|
99
99
|
codec = VectorCodec.vec2,
|
|
100
100
|
size = 8,
|
|
101
|
-
dw = extractDw
|
|
101
|
+
dw = extractDw(VectorCodec.vec2),
|
|
102
102
|
},
|
|
103
103
|
Vector3 = {
|
|
104
104
|
tag = TAG_VEC3,
|
|
105
105
|
codec = VectorCodec.vec3,
|
|
106
106
|
size = 12,
|
|
107
|
-
dw = extractDw
|
|
107
|
+
dw = extractDw(VectorCodec.vec3),
|
|
108
108
|
},
|
|
109
109
|
Color3 = {
|
|
110
110
|
tag = TAG_COLOR3,
|
|
111
111
|
codec = ColorCodec.color3,
|
|
112
112
|
size = 3,
|
|
113
|
-
dw = extractDw
|
|
113
|
+
dw = extractDw(ColorCodec.color3),
|
|
114
114
|
},
|
|
115
115
|
CFrame = {
|
|
116
116
|
tag = TAG_CFRAME,
|
|
117
117
|
codec = CFrameCodec.cframe,
|
|
118
118
|
size = 24,
|
|
119
|
-
dw = extractDw
|
|
119
|
+
dw = extractDw(CFrameCodec.cframe),
|
|
120
120
|
},
|
|
121
121
|
UDim = {
|
|
122
122
|
tag = TAG_UDIM,
|
|
123
123
|
codec = UDimCodec.udim,
|
|
124
124
|
size = 8,
|
|
125
|
-
dw = extractDw
|
|
125
|
+
dw = extractDw(UDimCodec.udim),
|
|
126
126
|
},
|
|
127
127
|
UDim2 = {
|
|
128
128
|
tag = TAG_UDIM2,
|
|
129
129
|
codec = UDimCodec.udim2,
|
|
130
130
|
size = 16,
|
|
131
|
-
dw = extractDw
|
|
131
|
+
dw = extractDw(UDimCodec.udim2),
|
|
132
132
|
},
|
|
133
133
|
NumberRange = {
|
|
134
134
|
tag = TAG_NUMBERRANGE,
|
|
135
135
|
codec = NumberRangeCodec.numberRange,
|
|
136
136
|
size = 8,
|
|
137
|
-
dw = extractDw
|
|
137
|
+
dw = extractDw(NumberRangeCodec.numberRange),
|
|
138
138
|
},
|
|
139
139
|
Rect = {
|
|
140
140
|
tag = TAG_RECT,
|
|
141
141
|
codec = RectCodec.rect,
|
|
142
142
|
size = 16,
|
|
143
|
-
dw = extractDw
|
|
143
|
+
dw = extractDw(RectCodec.rect),
|
|
144
144
|
},
|
|
145
145
|
Vector2int16 = {
|
|
146
146
|
tag = TAG_VEC2INT16,
|
|
147
147
|
codec = IntVectorCodec.vec2int16,
|
|
148
148
|
size = 4,
|
|
149
|
-
dw = extractDw
|
|
149
|
+
dw = extractDw(IntVectorCodec.vec2int16),
|
|
150
150
|
},
|
|
151
151
|
Vector3int16 = {
|
|
152
152
|
tag = TAG_VEC3INT16,
|
|
153
153
|
codec = IntVectorCodec.vec3int16,
|
|
154
154
|
size = 6,
|
|
155
|
-
dw = extractDw
|
|
155
|
+
dw = extractDw(IntVectorCodec.vec3int16),
|
|
156
156
|
},
|
|
157
157
|
Region3 = {
|
|
158
158
|
tag = TAG_REGION3,
|
|
159
159
|
codec = RegionCodec.region3,
|
|
160
160
|
size = 24,
|
|
161
|
-
dw = extractDw
|
|
161
|
+
dw = extractDw(RegionCodec.region3),
|
|
162
162
|
},
|
|
163
163
|
Region3int16 = {
|
|
164
164
|
tag = TAG_REGION3INT16,
|
|
165
165
|
codec = RegionCodec.region3int16,
|
|
166
166
|
size = 12,
|
|
167
|
-
dw = extractDw
|
|
167
|
+
dw = extractDw(RegionCodec.region3int16),
|
|
168
168
|
},
|
|
169
169
|
Ray = {
|
|
170
170
|
tag = TAG_RAY,
|
|
171
171
|
codec = RayCodec.ray,
|
|
172
172
|
size = 24,
|
|
173
|
-
dw = extractDw
|
|
173
|
+
dw = extractDw(RayCodec.ray),
|
|
174
174
|
},
|
|
175
175
|
NumberSequence = {
|
|
176
176
|
tag = TAG_NUMBERSEQUENCE,
|
|
@@ -206,19 +206,19 @@ do
|
|
|
206
206
|
NUM_DWRITES[pair[1]] = (pair[2] :: InternalCodec<number>)._directWrite
|
|
207
207
|
end
|
|
208
208
|
|
|
209
|
-
table.freeze
|
|
210
|
-
table.freeze
|
|
209
|
+
table.freeze(NUM_SIZES)
|
|
210
|
+
table.freeze(NUM_DWRITES)
|
|
211
211
|
|
|
212
|
-
-- Private
|
|
212
|
+
-- Private -------------------------------------------------------------
|
|
213
213
|
|
|
214
|
-
local _f32Temp = buffer.create
|
|
214
|
+
local _f32Temp = buffer.create(4)
|
|
215
215
|
|
|
216
|
-
local function selectNumberTag
|
|
216
|
+
local function selectNumberTag(value: number): number
|
|
217
217
|
if value ~= value then
|
|
218
218
|
return TAG_F64
|
|
219
219
|
end
|
|
220
220
|
|
|
221
|
-
if value == floor
|
|
221
|
+
if value == floor(value) then
|
|
222
222
|
if value >= 0 then
|
|
223
223
|
if value <= 255 then
|
|
224
224
|
return TAG_U8
|
|
@@ -243,42 +243,42 @@ local function selectNumberTag (value: number): number
|
|
|
243
243
|
return TAG_F64
|
|
244
244
|
end
|
|
245
245
|
|
|
246
|
-
buffer.writef32
|
|
247
|
-
if buffer.readf32
|
|
246
|
+
buffer.writef32(_f32Temp, 0, value)
|
|
247
|
+
if buffer.readf32(_f32Temp, 0) == value then
|
|
248
248
|
return TAG_F32
|
|
249
249
|
end
|
|
250
250
|
|
|
251
251
|
return TAG_F64
|
|
252
252
|
end
|
|
253
253
|
|
|
254
|
-
-- Public
|
|
254
|
+
-- Public --------------------------------------------------------------
|
|
255
255
|
|
|
256
|
-
local auto = table.freeze
|
|
257
|
-
write = function
|
|
256
|
+
local auto = table.freeze({
|
|
257
|
+
write = function(ch: ChannelState, value: any): ()
|
|
258
258
|
if value == nil then
|
|
259
259
|
local c = ch.cursor
|
|
260
260
|
if c + 1 > ch.size then
|
|
261
|
-
alloc
|
|
261
|
+
alloc(ch, 1)
|
|
262
262
|
end
|
|
263
|
-
buffer.writeu8
|
|
263
|
+
buffer.writeu8(ch.buff, c, TAG_NIL)
|
|
264
264
|
ch.cursor = c + 1
|
|
265
265
|
return
|
|
266
266
|
end
|
|
267
267
|
|
|
268
|
-
local t = type
|
|
268
|
+
local t = type(value)
|
|
269
269
|
|
|
270
270
|
if t == "number" then
|
|
271
|
-
local tag = selectNumberTag
|
|
271
|
+
local tag = selectNumberTag(value)
|
|
272
272
|
local payloadSize = NUM_SIZES[tag]
|
|
273
273
|
local totalSize = 1 + payloadSize
|
|
274
274
|
|
|
275
275
|
local c = ch.cursor
|
|
276
276
|
if c + totalSize > ch.size then
|
|
277
|
-
alloc
|
|
277
|
+
alloc(ch, totalSize)
|
|
278
278
|
end
|
|
279
279
|
local b = ch.buff
|
|
280
|
-
buffer.writeu8
|
|
281
|
-
NUM_DWRITES[tag]
|
|
280
|
+
buffer.writeu8(b, c, tag)
|
|
281
|
+
NUM_DWRITES[tag](b, c + 1, value)
|
|
282
282
|
ch.cursor = c + totalSize
|
|
283
283
|
return
|
|
284
284
|
end
|
|
@@ -288,13 +288,13 @@ local auto = table.freeze ({
|
|
|
288
288
|
local total = 6 + len
|
|
289
289
|
local c = ch.cursor
|
|
290
290
|
if c + total > ch.size then
|
|
291
|
-
alloc
|
|
291
|
+
alloc(ch, total)
|
|
292
292
|
end
|
|
293
|
-
buffer.writeu8
|
|
293
|
+
buffer.writeu8(ch.buff, c, TAG_STRING)
|
|
294
294
|
ch.cursor = c + 1
|
|
295
|
-
Varint.write
|
|
295
|
+
Varint.write(ch, len)
|
|
296
296
|
local c2 = ch.cursor
|
|
297
|
-
buffer.writestring
|
|
297
|
+
buffer.writestring(ch.buff, c2, value)
|
|
298
298
|
ch.cursor = c2 + len
|
|
299
299
|
return
|
|
300
300
|
end
|
|
@@ -302,19 +302,19 @@ local auto = table.freeze ({
|
|
|
302
302
|
if t == "boolean" then
|
|
303
303
|
local c = ch.cursor
|
|
304
304
|
if c + 2 > ch.size then
|
|
305
|
-
alloc
|
|
305
|
+
alloc(ch, 2)
|
|
306
306
|
end
|
|
307
307
|
local b = ch.buff
|
|
308
|
-
buffer.writeu8
|
|
309
|
-
buffer.writeu8
|
|
308
|
+
buffer.writeu8(b, c, TAG_BOOL)
|
|
309
|
+
buffer.writeu8(b, c + 1, if value then 1 else 0)
|
|
310
310
|
ch.cursor = c + 2
|
|
311
311
|
return
|
|
312
312
|
end
|
|
313
313
|
|
|
314
|
-
local valueType = typeof
|
|
314
|
+
local valueType = typeof(value)
|
|
315
315
|
local entry = TYPE_DISPATCH[valueType]
|
|
316
316
|
if not entry then
|
|
317
|
-
error
|
|
317
|
+
error(`[Lync] Auto unsupported type: {valueType}`)
|
|
318
318
|
end
|
|
319
319
|
|
|
320
320
|
local entryDw = entry.dw
|
|
@@ -323,36 +323,38 @@ local auto = table.freeze ({
|
|
|
323
323
|
local totalSize = 1 + entrySize
|
|
324
324
|
local c = ch.cursor
|
|
325
325
|
if c + totalSize > ch.size then
|
|
326
|
-
alloc
|
|
326
|
+
alloc(ch, totalSize)
|
|
327
327
|
end
|
|
328
328
|
local b = ch.buff
|
|
329
|
-
buffer.writeu8
|
|
330
|
-
entryDw
|
|
329
|
+
buffer.writeu8(b, c, entry.tag)
|
|
330
|
+
entryDw(b, c + 1, value)
|
|
331
331
|
ch.cursor = c + totalSize
|
|
332
332
|
else
|
|
333
333
|
local c = ch.cursor
|
|
334
334
|
if c + 1 > ch.size then
|
|
335
|
-
alloc
|
|
335
|
+
alloc(ch, 1)
|
|
336
336
|
end
|
|
337
|
-
buffer.writeu8
|
|
337
|
+
buffer.writeu8(ch.buff, c, entry.tag)
|
|
338
338
|
ch.cursor = c + 1
|
|
339
|
-
entry.codec.write
|
|
339
|
+
entry.codec.write(ch, value)
|
|
340
340
|
end
|
|
341
341
|
end,
|
|
342
|
-
read = function
|
|
343
|
-
local tag = buffer.readu8
|
|
342
|
+
read = function(src: buffer, pos: number, refs: { Instance }?): (any, number)
|
|
343
|
+
local tag = buffer.readu8(src, pos)
|
|
344
344
|
if tag == TAG_NIL then
|
|
345
345
|
return nil, 1
|
|
346
346
|
end
|
|
347
347
|
|
|
348
348
|
local codec = READ_DISPATCH[tag]
|
|
349
349
|
if not codec then
|
|
350
|
-
error
|
|
350
|
+
error(`[Lync] Auto unknown tag: {tag}`)
|
|
351
351
|
end
|
|
352
352
|
|
|
353
|
-
local value, n = codec.read
|
|
353
|
+
local value, n = codec.read(src, pos + 1, refs)
|
|
354
354
|
return value, 1 + n
|
|
355
355
|
end,
|
|
356
356
|
})
|
|
357
357
|
|
|
358
|
-
|
|
358
|
+
local AutoModule = {}
|
|
359
|
+
AutoModule.auto = auto
|
|
360
|
+
return table.freeze(AutoModule)
|
|
@@ -2,29 +2,29 @@
|
|
|
2
2
|
--!native
|
|
3
3
|
-- Pack booleans, unsigned and signed integers at the bit level.
|
|
4
4
|
|
|
5
|
-
local Channel = require
|
|
6
|
-
local Types = require
|
|
5
|
+
local Channel = require(script.Parent.Parent.Parent.internal.Channel)
|
|
6
|
+
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
7
|
|
|
8
8
|
type ChannelState = Types.ChannelState
|
|
9
9
|
type Codec<T> = Types.Codec<T>
|
|
10
10
|
|
|
11
11
|
local alloc = Channel.alloc
|
|
12
12
|
|
|
13
|
-
-- Constants
|
|
13
|
+
-- Constants -----------------------------------------------------------
|
|
14
14
|
|
|
15
15
|
local band = bit32.band
|
|
16
16
|
local bor = bit32.bor
|
|
17
17
|
local lshift = bit32.lshift
|
|
18
18
|
local rshift = bit32.rshift
|
|
19
19
|
|
|
20
|
-
-- Private
|
|
20
|
+
-- Private -------------------------------------------------------------
|
|
21
21
|
|
|
22
22
|
type FieldSpec = {
|
|
23
23
|
type: "bool" | "uint" | "int",
|
|
24
24
|
width: number?,
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
local function selectIO
|
|
27
|
+
local function selectIO(bytes: number): ((b: buffer, offset: number, v: number) -> (), (
|
|
28
28
|
b: buffer,
|
|
29
29
|
offset: number
|
|
30
30
|
) -> number)
|
|
@@ -37,28 +37,28 @@ local function selectIO (bytes: number): ((b: buffer, offset: number, v: number)
|
|
|
37
37
|
return buffer.writeu32, buffer.readu32
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
-- Public
|
|
40
|
+
-- Public --------------------------------------------------------------
|
|
41
41
|
|
|
42
42
|
local Bitfield = {}
|
|
43
43
|
|
|
44
|
-
function Bitfield.define
|
|
44
|
+
function Bitfield.define(schema: { [string]: FieldSpec }): Codec<any>
|
|
45
45
|
local sortedKeys = {} :: { string }
|
|
46
46
|
|
|
47
47
|
for key in schema do
|
|
48
|
-
table.insert
|
|
48
|
+
table.insert(sortedKeys, key)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
table.sort
|
|
51
|
+
table.sort(sortedKeys)
|
|
52
52
|
|
|
53
53
|
local count = #sortedKeys
|
|
54
54
|
if count == 0 then
|
|
55
|
-
error
|
|
55
|
+
error("[Lync] Bitfield requires at least one field")
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
local keys = table.create
|
|
59
|
-
local isBool = table.create
|
|
60
|
-
local offsets = table.create
|
|
61
|
-
local masks = table.create
|
|
58
|
+
local keys = table.create(count) :: { string }
|
|
59
|
+
local isBool = table.create(count) :: { boolean }
|
|
60
|
+
local offsets = table.create(count) :: { number }
|
|
61
|
+
local masks = table.create(count) :: { number }
|
|
62
62
|
|
|
63
63
|
local hasSigned = false
|
|
64
64
|
local signBits = nil :: { number }?
|
|
@@ -76,11 +76,11 @@ function Bitfield.define (schema: { [string]: FieldSpec }): Codec<any>
|
|
|
76
76
|
width = 1
|
|
77
77
|
else
|
|
78
78
|
if not spec.width then
|
|
79
|
-
error
|
|
79
|
+
error(`[Lync] Bitfield field requires a width: "{key}"`)
|
|
80
80
|
end
|
|
81
81
|
width = spec.width
|
|
82
82
|
if width < 1 or width > 32 then
|
|
83
|
-
error
|
|
83
|
+
error(`[Lync] Bitfield width must be 1-32: "{key}" got {width}`)
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
@@ -91,56 +91,56 @@ function Bitfield.define (schema: { [string]: FieldSpec }): Codec<any>
|
|
|
91
91
|
keys[i] = key
|
|
92
92
|
isBool[i] = specIsBool
|
|
93
93
|
offsets[i] = totalBits
|
|
94
|
-
masks[i] = lshift
|
|
94
|
+
masks[i] = lshift(1, width) - 1
|
|
95
95
|
totalBits += width
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
if totalBits > 32 then
|
|
99
|
-
error
|
|
99
|
+
error(`[Lync] Bitfield exceeds 32 bits: {totalBits}`)
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
-- Only build sign tables when at least one field is signed
|
|
103
103
|
if hasSigned then
|
|
104
|
-
signBits = table.create
|
|
105
|
-
signExtends = table.create
|
|
104
|
+
signBits = table.create(count) :: { number }
|
|
105
|
+
signExtends = table.create(count) :: { number }
|
|
106
106
|
|
|
107
107
|
for i = 1, count do
|
|
108
108
|
local spec = schema[sortedKeys[i]]
|
|
109
109
|
if spec.type == "int" then
|
|
110
|
-
(signBits :: { number })[i] = lshift
|
|
111
|
-
(signExtends :: { number })[i] = lshift
|
|
110
|
+
(signBits :: { number })[i] = lshift(1, (spec.width :: number) - 1);
|
|
111
|
+
(signExtends :: { number })[i] = lshift(1, spec.width :: number)
|
|
112
112
|
else
|
|
113
113
|
(signBits :: { number })[i] = 0
|
|
114
114
|
(signExtends :: { number })[i] = 0
|
|
115
115
|
end
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
table.freeze
|
|
119
|
-
table.freeze
|
|
118
|
+
table.freeze(signBits :: { number })
|
|
119
|
+
table.freeze(signExtends :: { number })
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
table.freeze
|
|
123
|
-
table.freeze
|
|
124
|
-
table.freeze
|
|
125
|
-
table.freeze
|
|
122
|
+
table.freeze(keys)
|
|
123
|
+
table.freeze(isBool)
|
|
124
|
+
table.freeze(offsets)
|
|
125
|
+
table.freeze(masks)
|
|
126
126
|
|
|
127
127
|
local bytes = if totalBits <= 8 then 1 elseif totalBits <= 16 then 2 else 4
|
|
128
|
-
local wfn, rfn = selectIO
|
|
128
|
+
local wfn, rfn = selectIO(bytes)
|
|
129
129
|
|
|
130
130
|
-- Shared pack logic
|
|
131
|
-
local function packValue
|
|
131
|
+
local function packValue(value: any): number
|
|
132
132
|
local packed = 0
|
|
133
133
|
for i = 1, count do
|
|
134
134
|
local bits = if isBool[i]
|
|
135
135
|
then (if value[keys[i]] then 1 else 0)
|
|
136
|
-
else band
|
|
137
|
-
packed = bor
|
|
136
|
+
else band(value[keys[i]], masks[i])
|
|
137
|
+
packed = bor(packed, lshift(bits, offsets[i]))
|
|
138
138
|
end
|
|
139
139
|
return packed
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
-- Shared unpack logic
|
|
143
|
-
local function unpackValue
|
|
143
|
+
local function unpackValue(packed: number): any
|
|
144
144
|
local result = {}
|
|
145
145
|
|
|
146
146
|
if hasSigned then
|
|
@@ -148,7 +148,7 @@ function Bitfield.define (schema: { [string]: FieldSpec }): Codec<any>
|
|
|
148
148
|
local se = signExtends :: { number }
|
|
149
149
|
|
|
150
150
|
for i = 1, count do
|
|
151
|
-
local raw = band
|
|
151
|
+
local raw = band(rshift(packed, offsets[i]), masks[i])
|
|
152
152
|
if isBool[i] then
|
|
153
153
|
result[keys[i]] = raw ~= 0
|
|
154
154
|
elseif sb[i] > 0 and raw >= sb[i] then
|
|
@@ -159,7 +159,7 @@ function Bitfield.define (schema: { [string]: FieldSpec }): Codec<any>
|
|
|
159
159
|
end
|
|
160
160
|
else
|
|
161
161
|
for i = 1, count do
|
|
162
|
-
local raw = band
|
|
162
|
+
local raw = band(rshift(packed, offsets[i]), masks[i])
|
|
163
163
|
result[keys[i]] = if isBool[i] then raw ~= 0 else raw
|
|
164
164
|
end
|
|
165
165
|
end
|
|
@@ -167,26 +167,26 @@ function Bitfield.define (schema: { [string]: FieldSpec }): Codec<any>
|
|
|
167
167
|
return result
|
|
168
168
|
end
|
|
169
169
|
|
|
170
|
-
return table.freeze
|
|
170
|
+
return table.freeze({
|
|
171
171
|
_size = bytes,
|
|
172
|
-
_directWrite = function
|
|
173
|
-
wfn
|
|
172
|
+
_directWrite = function(b: buffer, offset: number, value: any): ()
|
|
173
|
+
wfn(b, offset, packValue(value))
|
|
174
174
|
end,
|
|
175
|
-
_directRead = function
|
|
176
|
-
return unpackValue
|
|
175
|
+
_directRead = function(b: buffer, offset: number): any
|
|
176
|
+
return unpackValue(rfn(b, offset))
|
|
177
177
|
end,
|
|
178
|
-
write = function
|
|
178
|
+
write = function(ch: ChannelState, value: any): ()
|
|
179
179
|
local c = ch.cursor
|
|
180
180
|
if c + bytes > ch.size then
|
|
181
|
-
alloc
|
|
181
|
+
alloc(ch, bytes)
|
|
182
182
|
end
|
|
183
|
-
wfn
|
|
183
|
+
wfn(ch.buff, c, packValue(value))
|
|
184
184
|
ch.cursor = c + bytes
|
|
185
185
|
end,
|
|
186
|
-
read = function
|
|
187
|
-
return unpackValue
|
|
186
|
+
read = function(src: buffer, pos: number, _refs: { Instance }?): (any, number)
|
|
187
|
+
return unpackValue(rfn(src, pos)), bytes
|
|
188
188
|
end,
|
|
189
189
|
})
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
-
return table.freeze
|
|
192
|
+
return table.freeze(Bitfield)
|
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
--!native
|
|
3
3
|
-- User-defined fixed-size codec factory. Public API wrapper over Base.define.
|
|
4
4
|
|
|
5
|
-
local Base = require
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
|
|
7
7
|
local floor = math.floor
|
|
8
8
|
|
|
9
9
|
local Custom = {}
|
|
10
10
|
|
|
11
|
-
function Custom.define
|
|
11
|
+
function Custom.define(
|
|
12
12
|
size: number,
|
|
13
13
|
writeFn: (b: buffer, offset: number, value: any) -> (),
|
|
14
14
|
readFn: (b: buffer, offset: number) -> any
|
|
15
15
|
): any
|
|
16
|
-
if size < 0 or size ~= floor
|
|
17
|
-
error
|
|
16
|
+
if size < 0 or size ~= floor(size) then
|
|
17
|
+
error(`[Lync] Custom codec size must be a non-negative integer, got {size}`)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
if size == 0 then
|
|
21
|
-
return Base.zero
|
|
21
|
+
return Base.zero()
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
return Base.define
|
|
24
|
+
return Base.define(size, writeFn, readFn)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
return table.freeze
|
|
27
|
+
return table.freeze(Custom)
|