@axpecter/lync 2.3.3 → 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.
- package/LICENSE +21 -0
- package/README.md +302 -299
- package/Types.luau +215 -0
- package/api/Define.luau +154 -0
- package/api/Lifecycle.luau +119 -0
- package/api/Packet.luau +108 -0
- package/api/Query.luau +149 -0
- package/api/Set.luau +189 -0
- package/channel/Blocks.luau +124 -0
- package/channel/Group.luau +118 -0
- package/channel/Link.luau +135 -0
- package/channel/Outbox.luau +261 -0
- package/channel/Recipients.luau +129 -0
- package/channel/Transport.luau +138 -0
- package/codec/Base.luau +236 -0
- package/codec/Composites.luau +128 -0
- package/codec/Datatypes.luau +162 -0
- package/codec/Legality.luau +61 -0
- package/codec/Scalars.luau +72 -0
- package/codec/Text.luau +89 -0
- package/codec/init.luau +39 -0
- package/index.d.ts +285 -0
- package/init.luau +91 -0
- package/kernel/Bits.luau +16 -0
- package/kernel/Catalog.luau +121 -0
- package/kernel/Heap.luau +80 -0
- package/kernel/Listeners.luau +95 -0
- package/kernel/Log.luau +197 -0
- package/kernel/Tally.luau +128 -0
- package/kernel/Threads.luau +44 -0
- package/kernel/Wide.luau +267 -0
- package/package.json +15 -32
- package/runtime/Boundary.luau +180 -0
- package/runtime/Dispatch.luau +91 -0
- package/runtime/Handles.luau +114 -0
- package/runtime/Handshake.luau +90 -0
- package/runtime/Pending.luau +196 -0
- package/runtime/Router.luau +379 -0
- package/runtime/Session.luau +731 -0
- package/shape/Compile.luau +340 -0
- package/shape/Folds.luau +332 -0
- package/shape/Frames.luau +170 -0
- package/shape/Grid.luau +169 -0
- package/shape/Ir.luau +540 -0
- package/shape/Joins.luau +125 -0
- package/shape/Legality.luau +273 -0
- package/shape/Lower.luau +419 -0
- package/shape/Order.luau +64 -0
- package/shape/Regions.luau +113 -0
- package/shape/Rotation.luau +472 -0
- package/shape/Serial.luau +258 -0
- package/shape/Words.luau +89 -0
- package/shape/emit/Block.luau +453 -0
- package/shape/emit/Column.luau +338 -0
- package/shape/emit/Leaf.luau +462 -0
- package/shape/emit/Word.luau +234 -0
- package/shape/emit/init.luau +222 -0
- package/shape/init.luau +78 -0
- package/state/Apply.luau +330 -0
- package/state/Audience.luau +126 -0
- package/state/Catchup.luau +218 -0
- package/state/Coalesce.luau +43 -0
- package/state/Fieldset.luau +177 -0
- package/state/Newest.luau +339 -0
- package/state/Plan.luau +441 -0
- package/state/Sections.luau +468 -0
- package/state/Store.luau +188 -0
- package/state/Sync.luau +762 -0
- package/wire/Bytes.luau +118 -0
- package/wire/Clock.luau +37 -0
- package/wire/Protocol.luau +110 -0
- package/wire/Sequence.luau +40 -0
- package/wire/Varint.luau +124 -0
- package/src/Types.luau +0 -180
- package/src/api/Group.luau +0 -156
- package/src/api/Packet.luau +0 -317
- package/src/api/Query.luau +0 -338
- package/src/api/Scope.luau +0 -90
- package/src/api/Signal.luau +0 -193
- package/src/codec/Base.luau +0 -136
- package/src/codec/composite/Array.luau +0 -473
- package/src/codec/composite/Map.luau +0 -485
- package/src/codec/composite/Optional.luau +0 -54
- package/src/codec/composite/Shared.luau +0 -311
- package/src/codec/composite/Struct.luau +0 -494
- package/src/codec/composite/Tagged.luau +0 -103
- package/src/codec/composite/Tuple.luau +0 -143
- package/src/codec/datatype/Buffer.luau +0 -66
- package/src/codec/datatype/CFrame.luau +0 -109
- package/src/codec/datatype/Color.luau +0 -32
- package/src/codec/datatype/Instance.luau +0 -52
- package/src/codec/datatype/IntVector.luau +0 -39
- package/src/codec/datatype/NumberRange.luau +0 -39
- package/src/codec/datatype/Ray.luau +0 -36
- package/src/codec/datatype/Rect.luau +0 -31
- package/src/codec/datatype/Region.luau +0 -62
- package/src/codec/datatype/Sequence.luau +0 -184
- package/src/codec/datatype/String.luau +0 -94
- package/src/codec/datatype/UDim.luau +0 -46
- package/src/codec/datatype/Vector.luau +0 -130
- package/src/codec/meta/Auto.luau +0 -318
- package/src/codec/meta/Bitfield.luau +0 -160
- package/src/codec/meta/Custom.luau +0 -33
- package/src/codec/meta/DeltaScalar.luau +0 -390
- package/src/codec/meta/Enum.luau +0 -50
- package/src/codec/meta/Float.luau +0 -38
- package/src/codec/meta/Nothing.luau +0 -13
- package/src/codec/meta/Unknown.luau +0 -41
- package/src/codec/primitive/Bool.luau +0 -26
- package/src/codec/primitive/Float16.luau +0 -99
- package/src/codec/primitive/Int.luau +0 -59
- package/src/codec/primitive/Number.luau +0 -24
- package/src/codec/primitive/Signed.luau +0 -32
- package/src/codec/primitive/Varint.luau +0 -165
- package/src/codec/primitive/Zint.luau +0 -99
- package/src/index.d.ts +0 -423
- package/src/init.luau +0 -362
- package/src/internal/Baseline.luau +0 -57
- package/src/internal/Channel.luau +0 -484
- package/src/internal/Middleware.luau +0 -100
- package/src/internal/Pool.luau +0 -66
- package/src/internal/Registry.luau +0 -119
- package/src/internal/Transport.luau +0 -28
- package/src/transport/Bridge.luau +0 -110
- package/src/transport/Client.luau +0 -97
- package/src/transport/Gate.luau +0 -488
- package/src/transport/Reader.luau +0 -331
- package/src/transport/Server.luau +0 -233
- package/src/util/Array.luau +0 -18
- package/src/util/Buffer.luau +0 -90
- package/src/util/Constants.luau +0 -30
- package/src/util/Log.luau +0 -68
- package/src/util/Player.luau +0 -14
- package/src/util/Quantize.luau +0 -84
- 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)
|
package/src/codec/meta/Enum.luau
DELETED
|
@@ -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)
|