@axpecter/lync 2.3.2 → 3.0.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +302 -299
  3. package/Types.luau +215 -0
  4. package/api/Define.luau +154 -0
  5. package/api/Lifecycle.luau +119 -0
  6. package/api/Packet.luau +108 -0
  7. package/api/Query.luau +149 -0
  8. package/api/Set.luau +189 -0
  9. package/channel/Blocks.luau +124 -0
  10. package/channel/Group.luau +118 -0
  11. package/channel/Link.luau +135 -0
  12. package/channel/Outbox.luau +261 -0
  13. package/channel/Recipients.luau +129 -0
  14. package/channel/Transport.luau +138 -0
  15. package/codec/Base.luau +236 -0
  16. package/codec/Composites.luau +128 -0
  17. package/codec/Datatypes.luau +162 -0
  18. package/codec/Legality.luau +61 -0
  19. package/codec/Scalars.luau +72 -0
  20. package/codec/Text.luau +89 -0
  21. package/codec/init.luau +39 -0
  22. package/index.d.ts +285 -0
  23. package/init.luau +91 -0
  24. package/kernel/Bits.luau +16 -0
  25. package/kernel/Catalog.luau +121 -0
  26. package/kernel/Heap.luau +80 -0
  27. package/kernel/Listeners.luau +95 -0
  28. package/kernel/Log.luau +197 -0
  29. package/kernel/Tally.luau +128 -0
  30. package/kernel/Threads.luau +44 -0
  31. package/kernel/Wide.luau +267 -0
  32. package/package.json +15 -32
  33. package/runtime/Boundary.luau +180 -0
  34. package/runtime/Dispatch.luau +91 -0
  35. package/runtime/Handles.luau +114 -0
  36. package/runtime/Handshake.luau +90 -0
  37. package/runtime/Pending.luau +196 -0
  38. package/runtime/Router.luau +379 -0
  39. package/runtime/Session.luau +731 -0
  40. package/shape/Compile.luau +340 -0
  41. package/shape/Folds.luau +332 -0
  42. package/shape/Frames.luau +170 -0
  43. package/shape/Grid.luau +169 -0
  44. package/shape/Ir.luau +540 -0
  45. package/shape/Joins.luau +125 -0
  46. package/shape/Legality.luau +273 -0
  47. package/shape/Lower.luau +419 -0
  48. package/shape/Order.luau +64 -0
  49. package/shape/Regions.luau +113 -0
  50. package/shape/Rotation.luau +472 -0
  51. package/shape/Serial.luau +258 -0
  52. package/shape/Words.luau +89 -0
  53. package/shape/emit/Block.luau +453 -0
  54. package/shape/emit/Column.luau +338 -0
  55. package/shape/emit/Leaf.luau +462 -0
  56. package/shape/emit/Word.luau +234 -0
  57. package/shape/emit/init.luau +222 -0
  58. package/shape/init.luau +78 -0
  59. package/state/Apply.luau +330 -0
  60. package/state/Audience.luau +126 -0
  61. package/state/Catchup.luau +218 -0
  62. package/state/Coalesce.luau +43 -0
  63. package/state/Fieldset.luau +177 -0
  64. package/state/Newest.luau +339 -0
  65. package/state/Plan.luau +441 -0
  66. package/state/Sections.luau +468 -0
  67. package/state/Store.luau +188 -0
  68. package/state/Sync.luau +762 -0
  69. package/wire/Bytes.luau +118 -0
  70. package/wire/Clock.luau +37 -0
  71. package/wire/Protocol.luau +110 -0
  72. package/wire/Sequence.luau +40 -0
  73. package/wire/Varint.luau +124 -0
  74. package/src/Types.luau +0 -180
  75. package/src/api/Group.luau +0 -156
  76. package/src/api/Packet.luau +0 -319
  77. package/src/api/Query.luau +0 -338
  78. package/src/api/Scope.luau +0 -90
  79. package/src/api/Signal.luau +0 -188
  80. package/src/codec/Base.luau +0 -136
  81. package/src/codec/composite/Array.luau +0 -456
  82. package/src/codec/composite/Map.luau +0 -469
  83. package/src/codec/composite/Optional.luau +0 -54
  84. package/src/codec/composite/Shared.luau +0 -291
  85. package/src/codec/composite/Struct.luau +0 -494
  86. package/src/codec/composite/Tagged.luau +0 -103
  87. package/src/codec/composite/Tuple.luau +0 -143
  88. package/src/codec/datatype/Buffer.luau +0 -66
  89. package/src/codec/datatype/CFrame.luau +0 -109
  90. package/src/codec/datatype/Color.luau +0 -32
  91. package/src/codec/datatype/Instance.luau +0 -52
  92. package/src/codec/datatype/IntVector.luau +0 -39
  93. package/src/codec/datatype/NumberRange.luau +0 -39
  94. package/src/codec/datatype/Ray.luau +0 -36
  95. package/src/codec/datatype/Rect.luau +0 -31
  96. package/src/codec/datatype/Region.luau +0 -62
  97. package/src/codec/datatype/Sequence.luau +0 -184
  98. package/src/codec/datatype/String.luau +0 -94
  99. package/src/codec/datatype/UDim.luau +0 -46
  100. package/src/codec/datatype/Vector.luau +0 -130
  101. package/src/codec/meta/Auto.luau +0 -318
  102. package/src/codec/meta/Bitfield.luau +0 -147
  103. package/src/codec/meta/Custom.luau +0 -33
  104. package/src/codec/meta/DeltaScalar.luau +0 -390
  105. package/src/codec/meta/Enum.luau +0 -50
  106. package/src/codec/meta/Float.luau +0 -38
  107. package/src/codec/meta/Nothing.luau +0 -13
  108. package/src/codec/meta/Unknown.luau +0 -41
  109. package/src/codec/primitive/Bool.luau +0 -26
  110. package/src/codec/primitive/Float16.luau +0 -99
  111. package/src/codec/primitive/Int.luau +0 -59
  112. package/src/codec/primitive/Number.luau +0 -24
  113. package/src/codec/primitive/Signed.luau +0 -32
  114. package/src/codec/primitive/Varint.luau +0 -165
  115. package/src/codec/primitive/Zint.luau +0 -99
  116. package/src/index.d.ts +0 -423
  117. package/src/init.luau +0 -362
  118. package/src/internal/Baseline.luau +0 -57
  119. package/src/internal/Channel.luau +0 -390
  120. package/src/internal/Middleware.luau +0 -100
  121. package/src/internal/Pool.luau +0 -65
  122. package/src/internal/Registry.luau +0 -119
  123. package/src/internal/Transport.luau +0 -28
  124. package/src/transport/Bridge.luau +0 -110
  125. package/src/transport/Client.luau +0 -97
  126. package/src/transport/Gate.luau +0 -488
  127. package/src/transport/Reader.luau +0 -331
  128. package/src/transport/Server.luau +0 -211
  129. package/src/util/Array.luau +0 -18
  130. package/src/util/Buffer.luau +0 -90
  131. package/src/util/Constants.luau +0 -30
  132. package/src/util/Log.luau +0 -68
  133. package/src/util/Player.luau +0 -14
  134. package/src/util/Quantize.luau +0 -84
  135. package/src/util/Quat.luau +0 -124
@@ -1,318 +0,0 @@
1
- --!strict
2
- --!native
3
- -- Self-describing codec. u8 type tag + value payload.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
- local BufferC = require(script.Parent.Parent.datatype.Buffer)
7
- local CFrameC = require(script.Parent.Parent.datatype.CFrame)
8
- local Channel = require(script.Parent.Parent.Parent.internal.Channel)
9
- local ColorC = require(script.Parent.Parent.datatype.Color)
10
- local IVC = require(script.Parent.Parent.datatype.IntVector)
11
- local Log = require(script.Parent.Parent.Parent.util.Log)
12
- local NRC = require(script.Parent.Parent.datatype.NumberRange)
13
- local NumberC = require(script.Parent.Parent.primitive.Number)
14
- local RayC = require(script.Parent.Parent.datatype.Ray)
15
- local RectC = require(script.Parent.Parent.datatype.Rect)
16
- local RegionC = require(script.Parent.Parent.datatype.Region)
17
- local SeqC = require(script.Parent.Parent.datatype.Sequence)
18
- local Signed = require(script.Parent.Parent.primitive.Signed)
19
- local Types = require(script.Parent.Parent.Parent.Types)
20
- local UDimC = require(script.Parent.Parent.datatype.UDim)
21
- local Varint = require(script.Parent.Parent.primitive.Varint)
22
- local VecC = require(script.Parent.Parent.datatype.Vector)
23
-
24
- -- Constants --------------------------------------------------------------
25
-
26
- local TAG_NIL = 0
27
- local TAG_BOOL = 1
28
- local TAG_U8 = 2
29
- local TAG_U16 = 3
30
- local TAG_U32 = 4
31
- local TAG_I8 = 5
32
- local TAG_I16 = 6
33
- local TAG_I32 = 7
34
- local TAG_F32 = 8
35
- local TAG_F64 = 9
36
- local TAG_STRING = 10
37
- local TAG_VEC2 = 11
38
- local TAG_VEC3 = 12
39
- local TAG_COLOR3 = 13
40
- local TAG_CFRAME = 14
41
- local TAG_BUFFER = 15
42
- local TAG_UDIM = 16
43
- local TAG_UDIM2 = 17
44
- local TAG_NUMRANGE = 18
45
- local TAG_RECT = 19
46
- local TAG_V2I16 = 20
47
- local TAG_V3I16 = 21
48
- local TAG_REGION3 = 22
49
- local TAG_R3I16 = 23
50
- local TAG_RAY = 24
51
- local TAG_NUMSEQ = 25
52
- local TAG_COLSEQ = 26
53
-
54
- local INLINE_MAX = Varint.INLINE_MAX
55
- local F32_SCRATCH = NumberC._f32Scratch
56
-
57
- -- Tag -> numeric primitive dispatch tables.
58
- local NUM_SIZE: { [number]: number } = table.freeze({
59
- [TAG_U8] = 1,
60
- [TAG_I8] = 1,
61
- [TAG_U16] = 2,
62
- [TAG_I16] = 2,
63
- [TAG_U32] = 4,
64
- [TAG_I32] = 4,
65
- [TAG_F32] = 4,
66
- [TAG_F64] = 8,
67
- })
68
-
69
- local NUM_WRITE: { [number]: (buffer, number, number) -> () } = table.freeze({
70
- [TAG_U8] = buffer.writeu8,
71
- [TAG_U16] = buffer.writeu16,
72
- [TAG_U32] = buffer.writeu32,
73
- [TAG_I8] = Signed.writeI8,
74
- [TAG_I16] = Signed.writeI16,
75
- [TAG_I32] = Signed.writeI32,
76
- [TAG_F32] = buffer.writef32,
77
- [TAG_F64] = buffer.writef64,
78
- })
79
-
80
- local NUM_READ: { [number]: (buffer, number) -> number } = table.freeze({
81
- [TAG_U8] = buffer.readu8,
82
- [TAG_U16] = buffer.readu16,
83
- [TAG_U32] = buffer.readu32,
84
- [TAG_I8] = buffer.readi8,
85
- [TAG_I16] = buffer.readi16,
86
- [TAG_I32] = buffer.readi32,
87
- [TAG_F32] = buffer.readf32,
88
- [TAG_F64] = buffer.readf64,
89
- })
90
-
91
- type TypeEntry = { tag: number, codec: Types.InternalCodec<any> }
92
-
93
- local TYPE_DISPATCH: { [string]: TypeEntry } = table.freeze({
94
- Vector2 = { tag = TAG_VEC2, codec = VecC.vec2 },
95
- Vector3 = { tag = TAG_VEC3, codec = VecC.vec3 },
96
- Color3 = { tag = TAG_COLOR3, codec = ColorC.color3 },
97
- CFrame = { tag = TAG_CFRAME, codec = CFrameC.cframe },
98
- UDim = { tag = TAG_UDIM, codec = UDimC.udim },
99
- UDim2 = { tag = TAG_UDIM2, codec = UDimC.udim2 },
100
- NumberRange = { tag = TAG_NUMRANGE, codec = NRC.numberRange },
101
- Rect = { tag = TAG_RECT, codec = RectC.rect },
102
- Vector2int16 = { tag = TAG_V2I16, codec = IVC.vec2int16 },
103
- Vector3int16 = { tag = TAG_V3I16, codec = IVC.vec3int16 },
104
- Region3 = { tag = TAG_REGION3, codec = RegionC.region3 },
105
- Region3int16 = { tag = TAG_R3I16, codec = RegionC.region3int16 },
106
- Ray = { tag = TAG_RAY, codec = RayC.ray },
107
- NumberSequence = { tag = TAG_NUMSEQ, codec = SeqC.numberSequence },
108
- ColorSequence = { tag = TAG_COLSEQ, codec = SeqC.colorSequence },
109
- })
110
-
111
- local READ_DISPATCH: { [number]: Types.InternalCodec<any> } = table.freeze({
112
- [TAG_VEC2] = VecC.vec2,
113
- [TAG_VEC3] = VecC.vec3,
114
- [TAG_COLOR3] = ColorC.color3,
115
- [TAG_CFRAME] = CFrameC.cframe,
116
- [TAG_UDIM] = UDimC.udim,
117
- [TAG_UDIM2] = UDimC.udim2,
118
- [TAG_NUMRANGE] = NRC.numberRange,
119
- [TAG_RECT] = RectC.rect,
120
- [TAG_V2I16] = IVC.vec2int16,
121
- [TAG_V3I16] = IVC.vec3int16,
122
- [TAG_REGION3] = RegionC.region3,
123
- [TAG_R3I16] = RegionC.region3int16,
124
- [TAG_RAY] = RayC.ray,
125
- [TAG_NUMSEQ] = SeqC.numberSequence,
126
- [TAG_COLSEQ] = SeqC.colorSequence,
127
- })
128
-
129
- -- Private ----------------------------------------------------------------
130
-
131
- local alloc = Base.alloc
132
- local writeByte = Channel.writeByte
133
- local writeu8 = buffer.writeu8
134
- local readu8 = buffer.readu8
135
- local floor = math.floor
136
- local isnan = math.isnan
137
-
138
- --[[
139
- Pick the narrowest tag for a number. NaN forces F64 (no integer or F32
140
- can represent it). Integers walk u8 -> u16 -> u32 / i8 -> i16 -> i32; non-
141
- integers try f32 by round-tripping through scratch (see Number.luau) and
142
- fall through to f64 if precision is lost.
143
- ]]
144
- local function selectNumberTag(value: number): number
145
- if isnan(value) then
146
- return TAG_F64
147
- end
148
-
149
- if floor(value) == value then
150
- if value >= 0 then
151
- if value <= 0xFF then
152
- return TAG_U8
153
- end
154
- if value <= 0xFFFF then
155
- return TAG_U16
156
- end
157
- if value <= 0xFFFFFFFF then
158
- return TAG_U32
159
- end
160
- else
161
- if value >= -0x80 then
162
- return TAG_I8
163
- end
164
- if value >= -0x8000 then
165
- return TAG_I16
166
- end
167
- if value >= -0x80000000 then
168
- return TAG_I32
169
- end
170
- end
171
- end
172
-
173
- buffer.writef32(F32_SCRATCH, 0, value)
174
- if buffer.readf32(F32_SCRATCH, 0) == value then
175
- return TAG_F32
176
- end
177
- return TAG_F64
178
- end
179
-
180
- local function writeAuto(ch: Types.ChannelState, value: any): ()
181
- if value == nil then
182
- writeByte(ch, TAG_NIL)
183
- return
184
- end
185
-
186
- local t = typeof(value)
187
-
188
- if t == "boolean" then
189
- local cursor = ch.cursor
190
- if cursor + 2 > ch.size then
191
- alloc(ch, 2)
192
- end
193
- local b = ch.buff
194
- writeu8(b, cursor, TAG_BOOL)
195
- writeu8(b, cursor + 1, if value then 1 else 0)
196
- ch.cursor = cursor + 2
197
- return
198
- end
199
-
200
- if t == "number" then
201
- local tag = selectNumberTag(value)
202
- local size = NUM_SIZE[tag]
203
- local total = 1 + size
204
- local cursor = ch.cursor
205
- if cursor + total > ch.size then
206
- alloc(ch, total)
207
- end
208
- local b = ch.buff
209
- writeu8(b, cursor, tag)
210
- NUM_WRITE[tag](b, cursor + 1, value)
211
- ch.cursor = cursor + total
212
- return
213
- end
214
-
215
- if t == "string" then
216
- writeByte(ch, TAG_STRING)
217
-
218
- local len = #value
219
- local cursor = ch.cursor
220
- -- Inline single-byte length fast path; matches String.luau.
221
- if len <= INLINE_MAX then
222
- if cursor + 1 + len > ch.size then
223
- alloc(ch, 1 + len)
224
- end
225
- local b = ch.buff
226
- writeu8(b, cursor, len)
227
- if len > 0 then
228
- buffer.writestring(b, cursor + 1, value)
229
- end
230
- ch.cursor = cursor + 1 + len
231
- return
232
- end
233
- Varint.write(ch, len)
234
- cursor = ch.cursor
235
- if cursor + len > ch.size then
236
- alloc(ch, len)
237
- end
238
- buffer.writestring(ch.buff, cursor, value)
239
- ch.cursor = cursor + len
240
- return
241
- end
242
-
243
- if t == "buffer" then
244
- writeByte(ch, TAG_BUFFER)
245
- BufferC.buff.write(ch, value)
246
- return
247
- end
248
-
249
- local entry = TYPE_DISPATCH[t]
250
- if not entry then
251
- Log.error(`unsupported type "{t}"`)
252
- end
253
- local codec = entry.codec
254
- local size = codec._size
255
- local dw = codec._directWrite
256
- -- Fixed-size + direct writer: single alloc + tag + payload.
257
- if size and dw then
258
- local total = 1 + size
259
- local cursor = ch.cursor
260
- if cursor + total > ch.size then
261
- alloc(ch, total)
262
- end
263
- local b = ch.buff
264
- writeu8(b, cursor, entry.tag)
265
- dw(b, cursor + 1, value)
266
- ch.cursor = cursor + total
267
- return
268
- end
269
-
270
- writeByte(ch, entry.tag)
271
- codec.write(ch, value)
272
- end
273
-
274
- local function readAuto(src: buffer, pos: number, refs: { Instance }?): (any, number)
275
- local tag = readu8(src, pos)
276
-
277
- if tag == TAG_NIL then
278
- return nil, 1
279
- end
280
- if tag == TAG_BOOL then
281
- return readu8(src, pos + 1) ~= 0, 2
282
- end
283
-
284
- if tag >= TAG_U8 and tag <= TAG_F64 then
285
- return NUM_READ[tag](src, pos + 1), 1 + NUM_SIZE[tag]
286
- end
287
-
288
- if tag == TAG_STRING then
289
- local len, lenBytes = Varint.readLengthPrefix(src, pos + 1)
290
- if len == 0 then
291
- return "", 1 + lenBytes
292
- end
293
- return buffer.readstring(src, pos + 1 + lenBytes, len), 1 + lenBytes + len
294
- end
295
-
296
- if tag == TAG_BUFFER then
297
- local value, consumed = BufferC.buff.read(src, pos + 1, refs)
298
- return value, 1 + consumed
299
- end
300
-
301
- local codec = READ_DISPATCH[tag]
302
- if not codec then
303
- Log.error(`unknown tag {tag}`)
304
- end
305
- local value, consumed = codec.read(src, pos + 1, refs)
306
- return value, 1 + consumed
307
- end
308
-
309
- -- Public -----------------------------------------------------------------
310
-
311
- local AutoModule = {}
312
-
313
- AutoModule.auto = table.freeze({
314
- write = writeAuto,
315
- read = readAuto,
316
- })
317
-
318
- return table.freeze(AutoModule)
@@ -1,147 +0,0 @@
1
- --!strict
2
- --!native
3
- -- Sub-byte packed bool/uint/int fields. Up to 32 bits total per record.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
- local Log = require(script.Parent.Parent.Parent.util.Log)
7
- local Types = require(script.Parent.Parent.Parent.Types)
8
-
9
- -- Constants --------------------------------------------------------------
10
-
11
- local TYPE_BOOL = 0
12
- local TYPE_UINT = 1
13
- local TYPE_INT = 2
14
-
15
- -- Private ----------------------------------------------------------------
16
-
17
- local band = bit32.band
18
- local bor = bit32.bor
19
- local lshift = bit32.lshift
20
- local rshift = bit32.rshift
21
-
22
- -- bit32.lshift(1, 32) wraps to 0; force all-ones in the 32-bit case.
23
- local function widthMask(width: number): number
24
- if width >= 32 then
25
- return 0xFFFFFFFF
26
- end
27
- return lshift(1, width) - 1
28
- end
29
-
30
- -- Public -----------------------------------------------------------------
31
-
32
- local Bitfield = {}
33
-
34
- export type FieldSpec = { type: "bool" | "uint" | "int", width: number? }
35
-
36
- function Bitfield.define(schema: { [string]: FieldSpec }): Types.InternalCodec<any>
37
- -- Sort field names so bit positions are stable across runs.
38
- local keys: { string } = {}
39
- for key in schema do
40
- table.insert(keys, key)
41
- end
42
- table.sort(keys)
43
-
44
- local fieldCount = #keys
45
- Log.assert(fieldCount > 0, "requires at least one field")
46
-
47
- local fieldKeys = table.create(fieldCount)
48
- local fieldTypes = table.create(fieldCount)
49
- local fieldOffsets = table.create(fieldCount)
50
- local fieldMasks = table.create(fieldCount)
51
- local fieldSignBit = table.create(fieldCount)
52
- local fieldSignExt = table.create(fieldCount)
53
- local totalBits = 0
54
-
55
- for i = 1, fieldCount do
56
- local key = keys[i]
57
- local spec = schema[key]
58
- fieldKeys[i] = key
59
- fieldOffsets[i] = totalBits
60
-
61
- if spec.type == "bool" then
62
- fieldTypes[i] = TYPE_BOOL
63
- fieldMasks[i] = 1
64
- fieldSignBit[i] = 0
65
- fieldSignExt[i] = 0
66
- totalBits += 1
67
- elseif spec.type == "uint" then
68
- local width = spec.width
69
- if not width or width < 1 or width > 32 then
70
- Log.error(`field "{key}" uint width must be 1-32`)
71
- end
72
- fieldTypes[i] = TYPE_UINT
73
- fieldMasks[i] = widthMask(width)
74
- fieldSignBit[i] = 0
75
- fieldSignExt[i] = 0
76
- totalBits += width
77
- elseif spec.type == "int" then
78
- local width = spec.width
79
- -- Min int width is 2: 1 bit can't represent both a sign and a value.
80
- if not width or width < 2 or width > 32 then
81
- Log.error(`field "{key}" int width must be 2-32`)
82
- end
83
- fieldTypes[i] = TYPE_INT
84
- fieldMasks[i] = widthMask(width)
85
- fieldSignBit[i] = 2 ^ (width - 1)
86
- fieldSignExt[i] = 2 ^ width
87
- totalBits += width
88
- else
89
- Log.error(`field "{key}" has unknown type "{spec.type}"`)
90
- end
91
- end
92
-
93
- if totalBits > 32 then
94
- Log.error(`total exceeds 32 bits ({totalBits})`)
95
- end
96
-
97
- -- Pick the narrowest u8/u16/u32 wire form.
98
- local wireBytes: number
99
- local wfn: (buffer, number, number) -> ()
100
- local rfn: (buffer, number) -> number
101
- if totalBits <= 8 then
102
- wireBytes, wfn, rfn = 1, buffer.writeu8, buffer.readu8
103
- elseif totalBits <= 16 then
104
- wireBytes, wfn, rfn = 2, buffer.writeu16, buffer.readu16
105
- else
106
- wireBytes, wfn, rfn = 4, buffer.writeu32, buffer.readu32
107
- end
108
-
109
- table.freeze(fieldKeys)
110
- table.freeze(fieldTypes)
111
- table.freeze(fieldOffsets)
112
- table.freeze(fieldMasks)
113
- table.freeze(fieldSignBit)
114
- table.freeze(fieldSignExt)
115
-
116
- return Base.define(wireBytes, function(b: buffer, off: number, value: any): ()
117
- local packed = 0
118
- for i = 1, fieldCount do
119
- local v = value[fieldKeys[i]]
120
- if fieldTypes[i] == TYPE_BOOL then
121
- if v then
122
- packed = bor(packed, lshift(1, fieldOffsets[i]))
123
- end
124
- else
125
- packed = bor(packed, lshift(band(v, fieldMasks[i]), fieldOffsets[i]))
126
- end
127
- end
128
- wfn(b, off, packed)
129
- end, function(b: buffer, off: number): any
130
- local packed = rfn(b, off)
131
- local result: { [string]: any } = {}
132
- for i = 1, fieldCount do
133
- local raw = band(rshift(packed, fieldOffsets[i]), fieldMasks[i])
134
- if fieldTypes[i] == TYPE_BOOL then
135
- result[fieldKeys[i]] = raw ~= 0
136
- elseif fieldTypes[i] == TYPE_INT then
137
- -- Sign-extend: subtract 2^width when the sign bit is set.
138
- result[fieldKeys[i]] = if raw >= fieldSignBit[i] then raw - fieldSignExt[i] else raw
139
- else
140
- result[fieldKeys[i]] = raw
141
- end
142
- end
143
- return result
144
- end)
145
- end
146
-
147
- return table.freeze(Bitfield)
@@ -1,33 +0,0 @@
1
- --!strict
2
- --!optimize 2
3
- -- User-defined fixed-size codec.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
- local Log = require(script.Parent.Parent.Parent.util.Log)
7
- local Types = require(script.Parent.Parent.Parent.Types)
8
-
9
- -- Private ----------------------------------------------------------------
10
-
11
- local floor = math.floor
12
-
13
- -- Public -----------------------------------------------------------------
14
-
15
- local Custom = {}
16
-
17
- function Custom.define<T>(
18
- size: number,
19
- writeFn: (b: buffer, offset: number, value: T) -> (),
20
- readFn: (b: buffer, offset: number) -> T,
21
- typeCheck: string?
22
- ): Types.InternalCodec<T>
23
- if type(size) ~= "number" or size < 0 or floor(size) ~= size then
24
- Log.error(`size must be a non-negative integer, got {size}`)
25
- end
26
- -- size == 0 collapses to constant(nil): user has no payload to encode.
27
- if size == 0 then
28
- return Base.constant(nil :: any) :: Types.InternalCodec<T>
29
- end
30
- return Base.define(size, writeFn, readFn, if typeCheck then { _typeCheck = typeCheck } else nil)
31
- end
32
-
33
- return table.freeze(Custom)