@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,390 +0,0 @@
1
- --!strict
2
- --!native
3
- -- Delta scalars: zigzag-varint diff against previous frame for ints, floats, vec3, CFrame.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
- local Baseline = require(script.Parent.Parent.Parent.internal.Baseline)
7
- local Log = require(script.Parent.Parent.Parent.util.Log)
8
- local Quantize = require(script.Parent.Parent.Parent.util.Quantize)
9
- local Quat = require(script.Parent.Parent.Parent.util.Quat)
10
- local Shared = require(script.Parent.Parent.composite.Shared)
11
- local Types = require(script.Parent.Parent.Parent.Types)
12
- local Varint = require(script.Parent.Parent.primitive.Varint)
13
- local Zint = require(script.Parent.Parent.primitive.Zint)
14
-
15
- -- Constants --------------------------------------------------------------
16
-
17
- local I32_MIN = -0x80000000
18
- local I32_MAX = 0x7FFFFFFF
19
-
20
- -- deltaCFrame header bits: which components changed since the last frame.
21
- local CF_X = 0x01
22
- local CF_Y = 0x02
23
- local CF_Z = 0x04
24
- local CF_ROT = 0x08
25
- local CF_ALL = 0x0F
26
-
27
- -- Private ----------------------------------------------------------------
28
-
29
- local ensure = Base.ensure
30
- local allocDeltaId = Shared.allocDeltaId
31
- local floor = math.floor
32
- local clamp = math.clamp
33
- local round = math.round
34
- local band = bit32.band
35
- local bor = bit32.bor
36
- local readu8 = buffer.readu8
37
- local writeu8 = buffer.writeu8
38
- local readu32 = buffer.readu32
39
- local writeu32 = buffer.writeu32
40
- local bufLen = buffer.len
41
- local varintWrite = Varint.write
42
- local varintRead = Varint.read
43
- local zigzagEncode = Zint.encode
44
- local zigzagDecode = Zint.decode
45
- local quatPack = Quat.pack
46
- local quatUnpack = Quat.unpack
47
- local quatFromCFrame = Quat.fromCFrame
48
-
49
- local function quantizeVec3(
50
- v: Vector3,
51
- min: number,
52
- delta: number,
53
- scale: number
54
- ): (number, number, number)
55
- return round(clamp(v.X - min, 0, delta) * scale),
56
- round(clamp(v.Y - min, 0, delta) * scale),
57
- round(clamp(v.Z - min, 0, delta) * scale)
58
- end
59
-
60
- -- Reject out-of-range components rather than silently snapping via clamp().
61
- local function validateVec3(v: Vector3, min: number, max: number, label: string): ()
62
- if v.X < min or v.X > max or v.Y < min or v.Y > max or v.Z < min or v.Z > max then
63
- Log.error(`{label} ({v.X}, {v.Y}, {v.Z}) has component out of range [{min}, {max}]`)
64
- end
65
- end
66
-
67
- local function getScalarPrev(ch: Types.ChannelState, id: number, fallback: number): number
68
- local cache = ch.deltas[id] :: any
69
- return if cache then cache.scalar :: number else fallback
70
- end
71
-
72
- local function setScalarCache(ch: Types.ChannelState, id: number, value: number): ()
73
- local cache = ch.deltas[id] :: any
74
- if cache then
75
- cache.scalar = value
76
- else
77
- ch.deltas[id] = { scalar = value } :: any
78
- end
79
- end
80
-
81
- -- Public -----------------------------------------------------------------
82
-
83
- local DeltaScalar = {}
84
-
85
- --[[
86
- Variable-length integer that emits zigzag varint of (current - previous).
87
- First frame uses `min` as the implicit prev so the initial value encodes
88
- as (value - min). Reliable transport only — a dropped frame desyncs prev.
89
-
90
- Wire: 1 byte for unchanged or [-96, 95] mutations; up to 5 bytes for full i32.
91
- ]]
92
- function DeltaScalar.deltaInt(min: number, max: number): Types.InternalCodec<number>
93
- if min > max then
94
- Log.error(`min ({min}) must be <= max ({max})`)
95
- end
96
- if floor(min) ~= min or floor(max) ~= max then
97
- Log.error("bounds must be integers")
98
- end
99
- if max - min > I32_MAX then
100
- Log.error(`range too wide; (max - min) must fit in i32, got {max - min}`)
101
- end
102
-
103
- local deltaId = allocDeltaId()
104
-
105
- return table.freeze({
106
- _isDelta = true,
107
- _typeCheck = "number",
108
- _isInteger = true,
109
- _min = min,
110
- _max = max,
111
-
112
- write = function(ch: Types.ChannelState, value: number): ()
113
- if value < min or value > max then
114
- Log.error(`value {value} out of range [{min}, {max}]`)
115
- end
116
- if floor(value) ~= value then
117
- Log.error(`value {value} must be an integer`)
118
- end
119
- varintWrite(ch, zigzagEncode(value - getScalarPrev(ch, deltaId, min)))
120
- setScalarCache(ch, deltaId, value)
121
- end,
122
-
123
- read = function(src: buffer, pos: number, _refs: { Instance }?): (number, number)
124
- local raw, consumed = varintRead(src, pos)
125
- if consumed == 0 then
126
- Log.error("truncated deltaInt")
127
- end
128
- local cached = Baseline.getCache(deltaId)
129
- local value = (if cached ~= nil then cached :: number else min) + zigzagDecode(raw)
130
- if value < min or value > max then
131
- Log.error(`deltaInt decoded value {value} out of range [{min}, {max}]`)
132
- end
133
- Baseline.setCache(deltaId, value)
134
- return value, consumed
135
- end,
136
- }) :: Types.InternalCodec<number>
137
- end
138
-
139
- --[[
140
- Quantized float with diffs in integer wire space (post-quantize). Storing
141
- the quantized representative — not the float — across frames means
142
- accumulating diffs over thousands of frames cannot drift past the grid.
143
- ]]
144
- function DeltaScalar.deltaFloat(
145
- min: number,
146
- max: number,
147
- precision: number
148
- ): Types.InternalCodec<number>
149
- if max - min == 0 then
150
- return Base.constant(min)
151
- end
152
-
153
- local _, _, _, scale, invScale, delta = Quantize.setup("Lync.deltaFloat", min, max, precision)
154
- local deltaId = allocDeltaId()
155
-
156
- return table.freeze({
157
- _isDelta = true,
158
- _typeCheck = "number",
159
- _min = min,
160
- _max = max,
161
-
162
- write = function(ch: Types.ChannelState, value: number): ()
163
- local q = round(clamp(value - min, 0, delta) * scale)
164
- varintWrite(ch, zigzagEncode(q - getScalarPrev(ch, deltaId, 0)))
165
- setScalarCache(ch, deltaId, q)
166
- end,
167
-
168
- read = function(src: buffer, pos: number, _refs: { Instance }?): (number, number)
169
- local raw, consumed = varintRead(src, pos)
170
- if consumed == 0 then
171
- Log.error("truncated deltaFloat")
172
- end
173
- local cached = Baseline.getCache(deltaId)
174
- local q = (if cached ~= nil then cached :: number else 0) + zigzagDecode(raw)
175
- Baseline.setCache(deltaId, q)
176
- return q * invScale + min, consumed
177
- end,
178
- }) :: Types.InternalCodec<number>
179
- end
180
-
181
- --[[
182
- Quantized Vector3 with per-axis zigzag varint diffs. Static value: 3 bytes
183
- (three zero zigzags); typical < 1 stud motion at 0.01-stud precision: 3-6
184
- bytes. Baseline vec3 = 12 bytes, so 4x reduction at the static end.
185
- ]]
186
- function DeltaScalar.deltaVec3(
187
- min: number,
188
- max: number,
189
- precision: number
190
- ): Types.InternalCodec<Vector3>
191
- if max - min == 0 then
192
- return Base.constant(Vector3.new(min, min, min)) :: Types.InternalCodec<Vector3>
193
- end
194
-
195
- local _, _, _, scale, invScale, delta = Quantize.setup("Lync.deltaVec3", min, max, precision)
196
- local deltaId = allocDeltaId()
197
-
198
- return table.freeze({
199
- _isDelta = true,
200
- _typeCheck = "Vector3",
201
- _min = min,
202
- _max = max,
203
-
204
- write = function(ch: Types.ChannelState, value: Vector3): ()
205
- validateVec3(value, min, max, "Vector3")
206
- local qx, qy, qz = quantizeVec3(value, min, delta, scale)
207
- local cache = ch.deltas[deltaId] :: any
208
- local px, py, pz = 0, 0, 0
209
- if cache then
210
- px, py, pz = cache.qx :: number, cache.qy :: number, cache.qz :: number
211
- end
212
-
213
- varintWrite(ch, zigzagEncode(qx - px))
214
- varintWrite(ch, zigzagEncode(qy - py))
215
- varintWrite(ch, zigzagEncode(qz - pz))
216
-
217
- if cache then
218
- cache.qx, cache.qy, cache.qz = qx, qy, qz
219
- else
220
- ch.deltas[deltaId] = { qx = qx, qy = qy, qz = qz } :: any
221
- end
222
- end,
223
-
224
- read = function(src: buffer, pos: number, _refs: { Instance }?): (Vector3, number)
225
- local rx, cx = varintRead(src, pos)
226
- if cx == 0 then
227
- Log.error("truncated deltaVec3 X")
228
- end
229
- local ry, cy = varintRead(src, pos + cx)
230
- if cy == 0 then
231
- Log.error("truncated deltaVec3 Y")
232
- end
233
- local rz, cz = varintRead(src, pos + cx + cy)
234
- if cz == 0 then
235
- Log.error("truncated deltaVec3 Z")
236
- end
237
-
238
- local cached = Baseline.getCache(deltaId) :: any
239
- local px, py, pz = 0, 0, 0
240
- if cached then
241
- px, py, pz = cached.qx, cached.qy, cached.qz
242
- end
243
- local qx = px + zigzagDecode(rx)
244
- local qy = py + zigzagDecode(ry)
245
- local qz = pz + zigzagDecode(rz)
246
- Baseline.setCache(deltaId, { qx = qx, qy = qy, qz = qz })
247
-
248
- return Vector3.new(qx * invScale + min, qy * invScale + min, qz * invScale + min),
249
- cx + cy + cz
250
- end,
251
- }) :: Types.InternalCodec<Vector3>
252
- end
253
-
254
- --[[
255
- Quantized position + smallest-three quaternion rotation. Wire layout:
256
- byte 0 header bits: bit0=Δx, bit1=Δy, bit2=Δz, bit3=Δrot
257
- For each set position bit: zigzag varint of quantized diff
258
- If rotation bit set: 4-byte packed quat
259
-
260
- Static CFrame: 1 byte. Pos-only motion: 1 + 3 zint bytes (~4-7).
261
- Full update: 1 + 3 zint + 4 quat (~8-13). Baseline lossless: 24 bytes.
262
- ]]
263
- function DeltaScalar.deltaCFrame(
264
- posMin: number,
265
- posMax: number,
266
- posPrecision: number
267
- ): Types.InternalCodec<CFrame>
268
- -- Quantize.setup itself rejects min == max; the redundant guard is gone.
269
- local _, _, _, scale, invScale, delta =
270
- Quantize.setup("Lync.deltaCFrame", posMin, posMax, posPrecision)
271
- local deltaId = allocDeltaId()
272
-
273
- return table.freeze({
274
- _isDelta = true,
275
- _typeCheck = "CFrame",
276
-
277
- write = function(ch: Types.ChannelState, value: CFrame): ()
278
- local pos = value.Position
279
- validateVec3(pos, posMin, posMax, "CFrame position")
280
- local qx, qy, qz = quantizeVec3(pos, posMin, delta, scale)
281
- local packed = quatPack(quatFromCFrame(value))
282
-
283
- -- prev = 0 so the first frame writes absolute values; receiver also defaults to 0.
284
- local cache = ch.deltas[deltaId] :: any
285
- local flag: number
286
- local px, py, pz = 0, 0, 0
287
- if cache then
288
- px = cache.qx :: number
289
- py = cache.qy :: number
290
- pz = cache.qz :: number
291
- local ppacked = cache.qrot :: number
292
- flag = 0
293
- if qx ~= px then
294
- flag = bor(flag, CF_X)
295
- end
296
- if qy ~= py then
297
- flag = bor(flag, CF_Y)
298
- end
299
- if qz ~= pz then
300
- flag = bor(flag, CF_Z)
301
- end
302
- if packed ~= ppacked then
303
- flag = bor(flag, CF_ROT)
304
- end
305
- else
306
- -- First frame: emit everything so the receiver has a baseline.
307
- flag = CF_ALL
308
- end
309
-
310
- ensure(ch, 1)
311
- writeu8(ch.buff, ch.cursor, flag)
312
- ch.cursor += 1
313
-
314
- if band(flag, CF_X) ~= 0 then
315
- varintWrite(ch, zigzagEncode(qx - px))
316
- end
317
- if band(flag, CF_Y) ~= 0 then
318
- varintWrite(ch, zigzagEncode(qy - py))
319
- end
320
- if band(flag, CF_Z) ~= 0 then
321
- varintWrite(ch, zigzagEncode(qz - pz))
322
- end
323
- if band(flag, CF_ROT) ~= 0 then
324
- ensure(ch, 4)
325
- writeu32(ch.buff, ch.cursor, packed)
326
- ch.cursor += 4
327
- end
328
-
329
- if cache then
330
- cache.qx, cache.qy, cache.qz, cache.qrot = qx, qy, qz, packed
331
- else
332
- ch.deltas[deltaId] = { qx = qx, qy = qy, qz = qz, qrot = packed } :: any
333
- end
334
- end,
335
-
336
- read = function(src: buffer, pos: number, _refs: { Instance }?): (CFrame, number)
337
- if pos >= bufLen(src) then
338
- Log.error("truncated deltaCFrame header")
339
- end
340
- local flag = readu8(src, pos)
341
- local total = 1
342
-
343
- local cached = Baseline.getCache(deltaId) :: any
344
- local qx, qy, qz, packed = 0, 0, 0, 0
345
- if cached then
346
- qx, qy, qz, packed = cached.qx, cached.qy, cached.qz, cached.qrot
347
- end
348
-
349
- if band(flag, CF_X) ~= 0 then
350
- local r, c = varintRead(src, pos + total)
351
- if c == 0 then
352
- Log.error("truncated deltaCFrame X")
353
- end
354
- qx += zigzagDecode(r)
355
- total += c
356
- end
357
- if band(flag, CF_Y) ~= 0 then
358
- local r, c = varintRead(src, pos + total)
359
- if c == 0 then
360
- Log.error("truncated deltaCFrame Y")
361
- end
362
- qy += zigzagDecode(r)
363
- total += c
364
- end
365
- if band(flag, CF_Z) ~= 0 then
366
- local r, c = varintRead(src, pos + total)
367
- if c == 0 then
368
- Log.error("truncated deltaCFrame Z")
369
- end
370
- qz += zigzagDecode(r)
371
- total += c
372
- end
373
- if band(flag, CF_ROT) ~= 0 then
374
- if pos + total + 4 > bufLen(src) then
375
- Log.error("truncated deltaCFrame rotation")
376
- end
377
- packed = readu32(src, pos + total)
378
- total += 4
379
- end
380
-
381
- Baseline.setCache(deltaId, { qx = qx, qy = qy, qz = qz, qrot = packed })
382
-
383
- local position =
384
- Vector3.new(qx * invScale + posMin, qy * invScale + posMin, qz * invScale + posMin)
385
- return CFrame.new(position) * quatUnpack(packed), total
386
- end,
387
- }) :: Types.InternalCodec<CFrame>
388
- end
389
-
390
- return table.freeze(DeltaScalar)
@@ -1,50 +0,0 @@
1
- --!strict
2
- --!native
3
- -- String-keyed enum codec. Maps values to u8 indices at definition time.
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
- -- Public -----------------------------------------------------------------
10
-
11
- local EnumCodec = {}
12
-
13
- function EnumCodec.define(...: string): Types.InternalCodec<string>
14
- local values = { ... }
15
- local count = #values
16
- Log.assert(count > 0, "requires at least one variant")
17
- if count > 256 then
18
- Log.error(`exceeds 256 variants ({count})`)
19
- end
20
-
21
- local toIndex: { [string]: number } = {}
22
- local toValue = table.create(count)
23
- for i = 1, count do
24
- local val = values[i]
25
- if toIndex[val] then
26
- Log.error(`duplicate value "{val}"`)
27
- end
28
- toIndex[val] = i - 1
29
- toValue[i] = val
30
- end
31
- table.freeze(toIndex)
32
- table.freeze(toValue)
33
-
34
- return Base.define(1, function(b: buffer, off: number, value: string): ()
35
- local idx = toIndex[value]
36
- if idx == nil then
37
- Log.error(`invalid value "{value}"`)
38
- end
39
- buffer.writeu8(b, off, idx)
40
- end, function(b: buffer, off: number): string
41
- local raw = buffer.readu8(b, off)
42
- local val = toValue[raw + 1]
43
- if val == nil then
44
- Log.error(`invalid index {raw}`)
45
- end
46
- return val
47
- end, { _typeCheck = "string", _isEnum = true, _enumValues = toIndex })
48
- end
49
-
50
- return table.freeze(EnumCodec)
@@ -1,38 +0,0 @@
1
- --!strict
2
- --!native
3
- -- Fixed-point float quantizer. Maps a float range to u8/u16/u32.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
- local Quantize = require(script.Parent.Parent.Parent.util.Quantize)
7
- local Types = require(script.Parent.Parent.Parent.Types)
8
-
9
- -- Private ----------------------------------------------------------------
10
-
11
- local clamp = math.clamp
12
- local round = math.round
13
-
14
- -- Public -----------------------------------------------------------------
15
-
16
- local Float = {}
17
-
18
- function Float.float(
19
- rangeMin: number,
20
- rangeMax: number,
21
- precision: number
22
- ): Types.InternalCodec<number>
23
- -- Degenerate range: emit nothing, decode to the constant.
24
- if rangeMax - rangeMin == 0 then
25
- return Base.constant(rangeMin)
26
- end
27
-
28
- local compBytes, wfn, rfn, scale, invScale, delta =
29
- Quantize.setup("Lync.float", rangeMin, rangeMax, precision)
30
-
31
- return Base.define(compBytes, function(b: buffer, off: number, value: number): ()
32
- wfn(b, off, round(clamp(value - rangeMin, 0, delta) * scale))
33
- end, function(b: buffer, off: number): number
34
- return rfn(b, off) * invScale + rangeMin
35
- end, { _min = rangeMin, _max = rangeMax, _typeCheck = "number" })
36
- end
37
-
38
- return table.freeze(Float)
@@ -1,13 +0,0 @@
1
- --!strict
2
- --!optimize 2
3
- -- 0-byte codec. Reads nil. For fire-and-forget signals.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
-
7
- -- Public -----------------------------------------------------------------
8
-
9
- local Nothing = {}
10
-
11
- Nothing.nothing = Base.constant(nil :: nil)
12
-
13
- return table.freeze(Nothing)
@@ -1,41 +0,0 @@
1
- --!strict
2
- --!native
3
- -- Bypass codec. Stashes the value in the channel sidecar refs (no schema).
4
-
5
- local Channel = require(script.Parent.Parent.Parent.internal.Channel)
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 pushRef = Channel.pushRef
12
- local readu16 = buffer.readu16
13
-
14
- local function writeUnknown(ch: Types.ChannelState, value: any): ()
15
- pushRef(ch, value)
16
- end
17
-
18
- local function readUnknown(src: buffer, pos: number, refs: { Instance }?): (any, number)
19
- local r = refs
20
- if not r then
21
- Log.error("refs array is required")
22
- end
23
- local idx = readu16(src, pos)
24
- if idx < 1 or idx > #r then
25
- Log.error(`ref index {idx} out of bounds`)
26
- end
27
- return r[idx], 2
28
- end
29
-
30
- -- Public -----------------------------------------------------------------
31
-
32
- local Unknown = {}
33
-
34
- -- _hasUnknown propagates upward so containers warn when used without validate.
35
- Unknown.unknown = table.freeze({
36
- _hasUnknown = true,
37
- write = writeUnknown,
38
- read = readUnknown,
39
- })
40
-
41
- return table.freeze(Unknown)
@@ -1,26 +0,0 @@
1
- --!strict
2
- --!optimize 2
3
- -- 1-byte boolean codec. _isBool flag opts struct/array into bit packing.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
-
7
- -- Private ----------------------------------------------------------------
8
-
9
- local function writeBool(b: buffer, off: number, value: boolean): ()
10
- buffer.writeu8(b, off, if value then 1 else 0)
11
- end
12
-
13
- local function readBool(b: buffer, off: number): boolean
14
- return buffer.readu8(b, off) ~= 0
15
- end
16
-
17
- -- Public -----------------------------------------------------------------
18
-
19
- local Bool = {}
20
-
21
- Bool.bool = Base.define(1, writeBool, readBool, {
22
- _isBool = true,
23
- _typeCheck = "boolean",
24
- })
25
-
26
- return table.freeze(Bool)
@@ -1,99 +0,0 @@
1
- --!strict
2
- --!native
3
- -- IEEE 754 binary16 codec. 2 bytes, +/-65504 finite range, ~3 decimal digits.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
-
7
- -- Constants --------------------------------------------------------------
8
-
9
- local MAX_FINITE = 65504
10
- local NAN_BITS = 0x7E00
11
- local INF_BITS = 0x7C00
12
-
13
- -- Private ----------------------------------------------------------------
14
-
15
- local band = bit32.band
16
- local bor = bit32.bor
17
- local lshift = bit32.lshift
18
- local rshift = bit32.rshift
19
- local frexp = math.frexp
20
- local ldexp = math.ldexp
21
- local round = math.round
22
- local huge = math.huge
23
- local isnan = math.isnan
24
-
25
- local function encode(value: number): number
26
- if isnan(value) then
27
- return NAN_BITS
28
- end
29
- if value == 0 then
30
- return 0
31
- end
32
-
33
- local sign = 0
34
- if value < 0 then
35
- sign = 0x8000
36
- value = -value
37
- end
38
-
39
- if value > MAX_FINITE then
40
- return bor(sign, INF_BITS)
41
- end
42
-
43
- local mantissa, exponent = frexp(value)
44
- local biasedExp = exponent + 14
45
-
46
- -- Subnormal: shift mantissa into the 10-bit fraction with the implicit bit gone.
47
- if biasedExp <= 0 then
48
- local frac = round(ldexp(mantissa, biasedExp + 10))
49
- if frac >= 1024 then
50
- return bor(sign, 0x0400)
51
- end
52
- if frac <= 0 then
53
- return sign
54
- end
55
- return bor(sign, frac)
56
- end
57
-
58
- local frac = round((mantissa * 2 - 1) * 1024)
59
- -- Rounding can carry into the exponent; absorb it.
60
- if frac >= 1024 then
61
- frac = 0
62
- biasedExp += 1
63
- end
64
-
65
- if biasedExp >= 31 then
66
- return bor(sign, INF_BITS)
67
- end
68
-
69
- return bor(sign, lshift(biasedExp, 10), frac)
70
- end
71
-
72
- local function decode(raw: number): number
73
- local sign = band(raw, 0x8000)
74
- local exp = band(rshift(raw, 10), 0x1F)
75
- local frac = band(raw, 0x03FF)
76
-
77
- local value: number
78
- if exp == 0 then
79
- value = if frac == 0 then 0 else ldexp(frac, -24)
80
- elseif exp == 31 then
81
- value = if frac == 0 then huge else 0 / 0
82
- else
83
- value = ldexp(frac + 1024, exp - 25)
84
- end
85
-
86
- return if sign ~= 0 then -value else value
87
- end
88
-
89
- -- Public -----------------------------------------------------------------
90
-
91
- local Float16 = {}
92
-
93
- Float16.f16 = Base.define(2, function(b: buffer, off: number, value: number): ()
94
- buffer.writeu16(b, off, encode(value))
95
- end, function(b: buffer, off: number): number
96
- return decode(buffer.readu16(b, off))
97
- end, { _typeCheck = "number" })
98
-
99
- return table.freeze(Float16)