@axpecter/lync 2.1.2 → 2.2.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 +241 -349
- package/package.json +1 -1
- package/src/Types.luau +53 -13
- package/src/api/Group.luau +41 -51
- package/src/api/Packet.luau +163 -152
- package/src/api/Query.luau +224 -211
- package/src/api/Scope.luau +36 -38
- package/src/api/Signal.luau +68 -94
- package/src/codec/Base.luau +43 -23
- package/src/codec/composite/Array.luau +161 -152
- package/src/codec/composite/Map.luau +37 -53
- package/src/codec/composite/Optional.luau +15 -21
- package/src/codec/composite/Shared.luau +78 -41
- package/src/codec/composite/Struct.luau +64 -125
- package/src/codec/composite/Tagged.luau +15 -25
- package/src/codec/composite/Tuple.luau +15 -20
- package/src/codec/datatype/Buffer.luau +44 -51
- package/src/codec/datatype/CFrame.luau +72 -104
- package/src/codec/datatype/Color.luau +14 -10
- package/src/codec/datatype/Instance.luau +32 -42
- package/src/codec/datatype/IntVector.luau +24 -22
- package/src/codec/datatype/NumberRange.luau +21 -12
- package/src/codec/datatype/Ray.luau +13 -7
- package/src/codec/datatype/Rect.luau +13 -7
- package/src/codec/datatype/Region.luau +25 -22
- package/src/codec/datatype/Sequence.luau +144 -118
- package/src/codec/datatype/String.luau +29 -59
- package/src/codec/datatype/UDim.luau +29 -30
- package/src/codec/datatype/Vector.luau +89 -105
- package/src/codec/meta/Auto.luau +194 -246
- package/src/codec/meta/Bitfield.luau +37 -36
- package/src/codec/meta/Custom.luau +10 -10
- package/src/codec/meta/Enum.luau +8 -11
- package/src/codec/meta/Float.luau +16 -20
- package/src/codec/meta/Nothing.luau +2 -2
- package/src/codec/meta/Unknown.luau +22 -32
- package/src/codec/primitive/Bool.luau +9 -5
- package/src/codec/primitive/Float16.luau +13 -23
- package/src/codec/primitive/Int.luau +20 -28
- package/src/codec/primitive/Number.luau +6 -10
- package/src/codec/primitive/Signed.luau +32 -0
- package/src/codec/primitive/Varint.luau +59 -28
- package/src/index.d.ts +8 -2
- package/src/init.luau +133 -143
- package/src/internal/Baseline.luau +17 -18
- package/src/internal/Channel.luau +143 -212
- package/src/internal/Middleware.luau +37 -47
- package/src/internal/Pool.luau +10 -10
- package/src/internal/Registry.luau +38 -34
- package/src/internal/Transport.luau +28 -0
- package/src/internal/Util.luau +26 -0
- package/src/transport/Bridge.luau +32 -24
- package/src/transport/Client.luau +51 -53
- package/src/transport/Gate.luau +183 -113
- package/src/transport/Reader.luau +95 -66
- package/src/transport/Server.luau +130 -125
package/src/index.d.ts
CHANGED
|
@@ -141,7 +141,7 @@ interface LyncModule {
|
|
|
141
141
|
|
|
142
142
|
configure(this: void, options: Lync.ConfigureOptions): void;
|
|
143
143
|
start(this: void): void;
|
|
144
|
-
|
|
144
|
+
isStarted(this: void): boolean;
|
|
145
145
|
|
|
146
146
|
// ── Definitions ─────────────────────────────────────────────────
|
|
147
147
|
|
|
@@ -253,7 +253,13 @@ interface LyncModule {
|
|
|
253
253
|
|
|
254
254
|
enum<T extends string[]>(this: void, ...values: T): Lync.Codec<T[number]>;
|
|
255
255
|
bitfield(this: void, schema: Record<string, { type: "bool" } | { type: "uint"; width: number } | { type: "int"; width: number }>): Lync.Codec<Record<string, boolean | number>>;
|
|
256
|
-
custom<T>(
|
|
256
|
+
custom<T>(
|
|
257
|
+
this: void,
|
|
258
|
+
size: number,
|
|
259
|
+
write: (b: buffer, offset: number, value: T) => void,
|
|
260
|
+
read: (b: buffer, offset: number) => T,
|
|
261
|
+
typeCheck?: string,
|
|
262
|
+
): Lync.Codec<T>;
|
|
257
263
|
readonly nothing: Lync.Codec<undefined>;
|
|
258
264
|
readonly unknown: Lync.Codec<unknown>;
|
|
259
265
|
readonly auto: Lync.Codec<unknown>;
|
package/src/init.luau
CHANGED
|
@@ -15,8 +15,8 @@ local Query = require(script.api.Query)
|
|
|
15
15
|
local Registry = require(script.internal.Registry)
|
|
16
16
|
local Scope = require(script.api.Scope)
|
|
17
17
|
local Types = require(script.Types)
|
|
18
|
+
local Util = require(script.internal.Util)
|
|
18
19
|
|
|
19
|
-
-- Codecs
|
|
20
20
|
local ArrayC = require(script.codec.composite.Array)
|
|
21
21
|
local AutoC = require(script.codec.meta.Auto)
|
|
22
22
|
local BitfieldC = require(script.codec.meta.Bitfield)
|
|
@@ -48,108 +48,138 @@ local UDimC = require(script.codec.datatype.UDim)
|
|
|
48
48
|
local UnknownC = require(script.codec.meta.Unknown)
|
|
49
49
|
local VectorC = require(script.codec.datatype.Vector)
|
|
50
50
|
|
|
51
|
-
--
|
|
51
|
+
-- Public types (re-exported so users can write `Lync.Packet<MyData>`) ---
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
export type Codec<T> = Types.Codec<T>
|
|
54
|
+
export type Connection = Types.Connection
|
|
55
|
+
export type Packet<T> = Packet.PacketHandle<T>
|
|
56
|
+
export type Query<Req, Resp> = Query.QueryHandle<Req, Resp>
|
|
57
|
+
export type Group = Group.GroupHandle
|
|
58
|
+
export type Scope = Scope.ScopeHandle
|
|
59
|
+
export type PacketOptions = Types.PacketOptions
|
|
60
|
+
export type QueryOptions = Types.QueryOptions
|
|
61
|
+
export type ConfigureOptions = Types.ConfigureOptions
|
|
62
|
+
export type RateLimitConfig = Types.RateLimitConfig
|
|
63
|
+
export type PacketStats = Types.PacketStats
|
|
64
|
+
export type PlayerStats = Types.PlayerStats
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
local _flushRate = 60
|
|
59
|
-
local _flushAccum = 0
|
|
60
|
-
local _flushConn: RBXScriptConnection? = nil
|
|
66
|
+
-- Constants --------------------------------------------------------------
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
local IS_SERVER = RunService:IsServer()
|
|
63
69
|
|
|
64
70
|
local DROP = table.freeze({ _lyncDrop = true })
|
|
65
71
|
local ALL = table.freeze({ _lyncAll = true })
|
|
66
72
|
|
|
73
|
+
local CHANNEL_MAX_MIN, CHANNEL_MAX_MAX = 4096, 1048576
|
|
74
|
+
local DEPTH_MIN, DEPTH_MAX = 4, 32
|
|
75
|
+
local POOL_MIN, POOL_MAX = 2, 128
|
|
76
|
+
local FLUSH_HZ_MIN, FLUSH_HZ_MAX = 1, 60
|
|
77
|
+
|
|
78
|
+
-- State ------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
--[[
|
|
81
|
+
Wrap mutable flush state in one table so the Heartbeat closure
|
|
82
|
+
captures a single LCT_VAL upvalue instead of separate LCT_REF
|
|
83
|
+
upvalues for each field.
|
|
84
|
+
]]
|
|
85
|
+
local _flushState = {
|
|
86
|
+
started = false,
|
|
87
|
+
rate = FLUSH_HZ_MAX,
|
|
88
|
+
accum = 0,
|
|
89
|
+
conn = nil :: RBXScriptConnection?,
|
|
90
|
+
transport = nil :: { flush: () -> () }?,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
-- Private ----------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
local isPlayer = Util.isPlayer
|
|
96
|
+
|
|
67
97
|
local function except(...: any): any
|
|
68
98
|
local excluded: { [Player]: boolean } = {}
|
|
69
99
|
|
|
70
100
|
for i = 1, select("#", ...) do
|
|
71
101
|
local arg = select(i, ...)
|
|
72
|
-
if
|
|
102
|
+
if isPlayer(arg) then
|
|
73
103
|
excluded[arg :: Player] = true
|
|
74
|
-
elseif typeof(arg) == "table" and
|
|
75
|
-
for player in
|
|
104
|
+
elseif typeof(arg) == "table" and arg._lyncGroup then
|
|
105
|
+
for player in arg._members :: { [Player]: boolean } do
|
|
76
106
|
excluded[player] = true
|
|
77
107
|
end
|
|
78
108
|
else
|
|
79
|
-
error("[Lync] except: argument must be a Player or Group")
|
|
109
|
+
error("[Lync] Lync.except: argument must be a Player or Group")
|
|
80
110
|
end
|
|
81
111
|
end
|
|
82
112
|
|
|
83
|
-
return table.freeze({
|
|
113
|
+
return table.freeze({
|
|
114
|
+
_lyncExcept = true,
|
|
115
|
+
_excluded = table.freeze(excluded),
|
|
116
|
+
})
|
|
84
117
|
end
|
|
85
118
|
|
|
86
119
|
local function setupFlush(): ()
|
|
87
|
-
local
|
|
88
|
-
|
|
120
|
+
local transport: { flush: () -> () }
|
|
89
121
|
if IS_SERVER then
|
|
90
122
|
local Server = require(script.transport.Server)
|
|
91
|
-
|
|
92
|
-
Server.flush()
|
|
93
|
-
end
|
|
123
|
+
transport = { flush = Server.flush }
|
|
94
124
|
else
|
|
95
125
|
local Client = require(script.transport.Client)
|
|
96
|
-
|
|
97
|
-
Client.flush()
|
|
98
|
-
end
|
|
126
|
+
transport = { flush = Client.flush }
|
|
99
127
|
end
|
|
128
|
+
_flushState.transport = transport
|
|
100
129
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
130
|
+
_flushState.conn = RunService.Heartbeat:Connect(function(dt: number)
|
|
131
|
+
local rate = _flushState.rate
|
|
132
|
+
if rate >= FLUSH_HZ_MAX then
|
|
133
|
+
transport.flush()
|
|
134
|
+
return
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
local accum = _flushState.accum + dt
|
|
138
|
+
local interval = 1 / rate
|
|
139
|
+
if accum >= interval then
|
|
140
|
+
-- Drift guard: if we're more than one interval behind (frame
|
|
141
|
+
-- stall) zero the accumulator instead of catching up.
|
|
142
|
+
accum = if accum >= 2 * interval then 0 else accum - interval
|
|
143
|
+
transport.flush()
|
|
115
144
|
end
|
|
145
|
+
_flushState.accum = accum
|
|
116
146
|
end)
|
|
117
147
|
end
|
|
118
148
|
|
|
119
|
-
-- Public
|
|
120
|
-
|
|
121
|
-
local Lync: any = {}
|
|
149
|
+
-- Public -----------------------------------------------------------------
|
|
122
150
|
|
|
123
|
-
|
|
151
|
+
local Lync = {}
|
|
124
152
|
|
|
125
153
|
function Lync.configure(options: Types.ConfigureOptions): ()
|
|
126
|
-
if
|
|
154
|
+
if _flushState.started then
|
|
127
155
|
error("[Lync] Lync.configure: must be called before Lync.start()")
|
|
128
156
|
end
|
|
129
157
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if size <
|
|
133
|
-
error(
|
|
158
|
+
local size = options.channelMaxSize
|
|
159
|
+
if size then
|
|
160
|
+
if size < CHANNEL_MAX_MIN or size > CHANNEL_MAX_MAX then
|
|
161
|
+
error(
|
|
162
|
+
`[Lync] Lync.configure: channelMaxSize must be {CHANNEL_MAX_MIN}-{CHANNEL_MAX_MAX}`
|
|
163
|
+
)
|
|
134
164
|
end
|
|
135
165
|
Channel.setMaxSize(size)
|
|
136
166
|
Base.setMaxSize(size)
|
|
137
167
|
end
|
|
138
168
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if depth <
|
|
142
|
-
error(
|
|
169
|
+
local depth = options.validationDepth
|
|
170
|
+
if depth then
|
|
171
|
+
if depth < DEPTH_MIN or depth > DEPTH_MAX then
|
|
172
|
+
error(`[Lync] Lync.configure: validationDepth must be {DEPTH_MIN}-{DEPTH_MAX}`)
|
|
143
173
|
end
|
|
144
174
|
Gate.setDepth(depth)
|
|
145
175
|
end
|
|
146
176
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if
|
|
150
|
-
error(
|
|
177
|
+
local poolSize = options.poolSize
|
|
178
|
+
if poolSize then
|
|
179
|
+
if poolSize < POOL_MIN or poolSize > POOL_MAX then
|
|
180
|
+
error(`[Lync] Lync.configure: poolSize must be {POOL_MIN}-{POOL_MAX}`)
|
|
151
181
|
end
|
|
152
|
-
Pool.setMaxSize(
|
|
182
|
+
Pool.setMaxSize(poolSize)
|
|
153
183
|
end
|
|
154
184
|
|
|
155
185
|
if options.bandwidthLimit then
|
|
@@ -170,10 +200,10 @@ function Lync.configure(options: Types.ConfigureOptions): ()
|
|
|
170
200
|
end
|
|
171
201
|
|
|
172
202
|
function Lync.start(): ()
|
|
173
|
-
if
|
|
203
|
+
if _flushState.started then
|
|
174
204
|
error("[Lync] Lync.start: already started")
|
|
175
205
|
end
|
|
176
|
-
|
|
206
|
+
_flushState.started = true
|
|
177
207
|
|
|
178
208
|
if IS_SERVER then
|
|
179
209
|
local Server = require(script.transport.Server)
|
|
@@ -186,57 +216,40 @@ function Lync.start(): ()
|
|
|
186
216
|
setupFlush()
|
|
187
217
|
end
|
|
188
218
|
|
|
189
|
-
|
|
190
|
-
|
|
219
|
+
function Lync.flush(): ()
|
|
220
|
+
if not _flushState.started then
|
|
221
|
+
error("[Lync] Lync.flush: must call Lync.start() first")
|
|
222
|
+
end
|
|
223
|
+
-- start() is the only path that sets transport, so it's non-nil here.
|
|
224
|
+
(_flushState.transport :: { flush: () -> () }).flush()
|
|
225
|
+
_flushState.accum = 0
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
function Lync.flushRate(hz: number): ()
|
|
229
|
+
if hz < FLUSH_HZ_MIN or hz > FLUSH_HZ_MAX then
|
|
230
|
+
error(`[Lync] Lync.flushRate: hz must be {FLUSH_HZ_MIN}-{FLUSH_HZ_MAX}`)
|
|
231
|
+
end
|
|
232
|
+
_flushState.rate = hz
|
|
233
|
+
_flushState.accum = 0
|
|
234
|
+
end
|
|
191
235
|
|
|
192
|
-
|
|
236
|
+
function Lync.isStarted(): boolean
|
|
237
|
+
return _flushState.started
|
|
238
|
+
end
|
|
193
239
|
|
|
194
240
|
Lync.packet = Packet.define
|
|
195
241
|
Lync.query = Query.define
|
|
196
242
|
Lync.group = Group.create
|
|
197
243
|
Lync.scope = Scope.create
|
|
198
244
|
|
|
199
|
-
-- Targeting -----------------------------------------------------------
|
|
200
|
-
|
|
201
245
|
Lync.all = ALL
|
|
202
246
|
Lync.except = except
|
|
203
247
|
Lync.DROP = DROP
|
|
204
248
|
|
|
205
|
-
-- Middleware ----------------------------------------------------------
|
|
206
|
-
|
|
207
249
|
Lync.onSend = Middleware.onSend
|
|
208
250
|
Lync.onReceive = Middleware.onReceive
|
|
209
251
|
Lync.onDrop = Middleware.onDrop
|
|
210
252
|
|
|
211
|
-
-- Runtime control -----------------------------------------------------
|
|
212
|
-
|
|
213
|
-
function Lync.flush(): ()
|
|
214
|
-
if not _started then
|
|
215
|
-
error("[Lync] Lync.flush: must call Lync.start() first")
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
if IS_SERVER then
|
|
219
|
-
local Server = require(script.transport.Server)
|
|
220
|
-
Server.flush()
|
|
221
|
-
else
|
|
222
|
-
local Client = require(script.transport.Client)
|
|
223
|
-
Client.flush()
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
-- Reset accumulator to prevent double-flush
|
|
227
|
-
_flushAccum = 0
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
function Lync.flushRate(hz: number): ()
|
|
231
|
-
if hz < 1 or hz > 60 then
|
|
232
|
-
error("[Lync] Lync.flushRate: hz must be 1-60")
|
|
233
|
-
end
|
|
234
|
-
_flushRate = hz
|
|
235
|
-
_flushAccum = 0
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
-- Stats ---------------------------------------------------------------
|
|
239
|
-
|
|
240
253
|
Lync.stats = table.freeze({
|
|
241
254
|
player = function(player: Player): Types.PlayerStats?
|
|
242
255
|
if not IS_SERVER then
|
|
@@ -251,56 +264,48 @@ Lync.stats = table.freeze({
|
|
|
251
264
|
local Server = require(script.transport.Server)
|
|
252
265
|
Server.resetStats()
|
|
253
266
|
end
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
267
|
+
for i = 1, Registry.count() do
|
|
268
|
+
local reg = Registry.get(i)
|
|
269
|
+
if reg then
|
|
270
|
+
reg.bytesSent = 0
|
|
271
|
+
reg.bytesReceived = 0
|
|
272
|
+
reg.fires = 0
|
|
273
|
+
reg.recvFires = 0
|
|
274
|
+
reg.drops = 0
|
|
275
|
+
end
|
|
262
276
|
end
|
|
263
277
|
end,
|
|
264
278
|
})
|
|
265
279
|
|
|
266
|
-
-- Debug ---------------------------------------------------------------
|
|
267
|
-
|
|
268
280
|
Lync.debug = table.freeze({
|
|
269
|
-
capture = function(_label: string?): ()
|
|
270
|
-
|
|
271
|
-
end,
|
|
272
|
-
|
|
273
|
-
stop = function(): ()
|
|
274
|
-
-- TODO: Implement capture stop
|
|
275
|
-
end,
|
|
276
|
-
|
|
277
|
-
dump = function(): ()
|
|
278
|
-
-- TODO: Implement capture dump
|
|
279
|
-
end,
|
|
281
|
+
capture = function(_label: string?): () end,
|
|
282
|
+
stop = function(): () end,
|
|
283
|
+
dump = function(): () end,
|
|
280
284
|
|
|
281
285
|
pending = function(): number
|
|
282
286
|
return Query.pendingCount()
|
|
283
287
|
end,
|
|
284
288
|
|
|
285
289
|
registrations = function(): { any }
|
|
286
|
-
local
|
|
287
|
-
local result = table.create(
|
|
288
|
-
|
|
289
|
-
for i
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
290
|
+
local count = Registry.count()
|
|
291
|
+
local result = table.create(count)
|
|
292
|
+
local n = 0
|
|
293
|
+
for i = 1, count do
|
|
294
|
+
local reg = Registry.get(i)
|
|
295
|
+
if reg then
|
|
296
|
+
n += 1
|
|
297
|
+
result[n] = table.freeze({
|
|
298
|
+
name = reg.name,
|
|
299
|
+
id = reg.id,
|
|
300
|
+
kind = reg.kind,
|
|
301
|
+
isUnreliable = reg.isUnreliable,
|
|
302
|
+
})
|
|
303
|
+
end
|
|
296
304
|
end
|
|
297
|
-
|
|
298
305
|
return table.freeze(result)
|
|
299
306
|
end,
|
|
300
307
|
})
|
|
301
308
|
|
|
302
|
-
-- Codecs --------------------------------------------------------------
|
|
303
|
-
|
|
304
309
|
Lync.int = IntC.int
|
|
305
310
|
Lync.float = FloatC.float
|
|
306
311
|
Lync.f16 = Float16C.f16
|
|
@@ -341,19 +346,4 @@ Lync.nothing = NothingC.nothing
|
|
|
341
346
|
Lync.unknown = UnknownC.unknown
|
|
342
347
|
Lync.auto = AutoC.auto
|
|
343
348
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
local LyncProxy = setmetatable({}, {
|
|
347
|
-
__index = function(_self: any, key: string): any
|
|
348
|
-
if key == "started" then
|
|
349
|
-
return _started
|
|
350
|
-
end
|
|
351
|
-
return Lync[key]
|
|
352
|
-
end,
|
|
353
|
-
|
|
354
|
-
__newindex = function(): ()
|
|
355
|
-
error("[Lync] Lync: module table is read-only")
|
|
356
|
-
end,
|
|
357
|
-
})
|
|
358
|
-
|
|
359
|
-
return LyncProxy
|
|
349
|
+
return table.freeze(Lync)
|
|
@@ -2,40 +2,39 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Read-side delta cache for delta codecs.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
local Types = require(script.Parent.Parent.Types)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
-- State ------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
local _caches: { [number]: { [Types.BaselineKey]: any } } = {}
|
|
10
|
+
local _currentKey: Types.BaselineKey = false
|
|
9
11
|
local _hasDelta = false
|
|
10
12
|
|
|
11
|
-
-- Public
|
|
13
|
+
-- Public -----------------------------------------------------------------
|
|
12
14
|
|
|
13
15
|
local Baseline = {}
|
|
14
16
|
|
|
15
|
-
function Baseline.setReadKey(key:
|
|
17
|
+
function Baseline.setReadKey(key: Types.BaselineKey): ()
|
|
16
18
|
_currentKey = key
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
function Baseline.getCache(deltaId: number): any?
|
|
20
|
-
local
|
|
21
|
-
if
|
|
22
|
-
return nil
|
|
23
|
-
end
|
|
24
|
-
return perPlayer[_currentKey]
|
|
22
|
+
local perKey = _caches[deltaId]
|
|
23
|
+
return if perKey then perKey[_currentKey] else nil
|
|
25
24
|
end
|
|
26
25
|
|
|
27
26
|
function Baseline.setCache(deltaId: number, value: any): ()
|
|
28
|
-
local
|
|
29
|
-
if not
|
|
30
|
-
|
|
31
|
-
_caches[deltaId] =
|
|
27
|
+
local perKey = _caches[deltaId]
|
|
28
|
+
if not perKey then
|
|
29
|
+
perKey = {}
|
|
30
|
+
_caches[deltaId] = perKey
|
|
32
31
|
end
|
|
33
|
-
|
|
32
|
+
perKey[_currentKey] = value
|
|
34
33
|
end
|
|
35
34
|
|
|
36
|
-
function Baseline.clearPlayer(key:
|
|
37
|
-
for _,
|
|
38
|
-
|
|
35
|
+
function Baseline.clearPlayer(key: Types.BaselineKey): ()
|
|
36
|
+
for _, perKey in _caches do
|
|
37
|
+
perKey[key] = nil
|
|
39
38
|
end
|
|
40
39
|
end
|
|
41
40
|
|