@axpecter/lync 1.4.0 → 1.4.3
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 +24 -24
- package/package.json +3 -2
- package/src/Types.luau +13 -2
- package/src/api/Group.luau +3 -5
- package/src/api/Namespace.luau +6 -6
- package/src/api/Packet.luau +9 -8
- package/src/api/Query.luau +11 -9
- package/src/api/Scope.luau +2 -2
- package/src/api/Signal.luau +10 -4
- package/src/codec/Base.luau +7 -3
- package/src/codec/composite/Array.luau +18 -15
- package/src/codec/composite/Map.luau +45 -31
- package/src/codec/composite/Optional.luau +3 -2
- package/src/codec/composite/Shared.luau +7 -5
- package/src/codec/composite/Struct.luau +6 -4
- package/src/codec/composite/Tagged.luau +6 -6
- package/src/codec/composite/Tuple.luau +9 -7
- package/src/codec/datatype/Buffer.luau +3 -2
- package/src/codec/datatype/CFrame.luau +2 -1
- package/src/codec/datatype/Instance.luau +3 -2
- package/src/codec/datatype/Sequence.luau +3 -4
- package/src/codec/datatype/String.luau +3 -6
- package/src/codec/meta/Auto.luau +77 -72
- package/src/codec/meta/Bitfield.luau +5 -4
- package/src/codec/meta/Enum.luau +6 -5
- package/src/codec/meta/Quantized.luau +5 -4
- package/src/codec/meta/Unknown.luau +5 -1
- package/src/codec/primitive/Float16.luau +5 -4
- package/src/codec/primitive/Varint.luau +2 -2
- package/src/init.luau +39 -37
- package/src/internal/Baseline.luau +6 -2
- package/src/internal/Channel.luau +11 -6
- package/src/internal/Middleware.luau +13 -12
- package/src/internal/Pool.luau +5 -5
- package/src/internal/Registry.luau +4 -4
- package/src/transport/Bridge.luau +4 -3
- package/src/transport/Client.luau +4 -3
- package/src/transport/Gate.luau +5 -5
- package/src/transport/Reader.luau +3 -3
- package/src/transport/Server.luau +7 -8
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
```toml
|
|
15
15
|
[dependencies]
|
|
16
|
-
Lync = "axp3cter/lync@1.4.
|
|
16
|
+
Lync = "axp3cter/lync@1.4.2"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
**npm (roblox-ts)**
|
|
@@ -33,7 +33,7 @@ Or grab the `.rbxm` from [releases](https://github.com/Axp3cter/Lync/releases/la
|
|
|
33
33
|
|
|
34
34
|
## Example
|
|
35
35
|
|
|
36
|
-
**Shared**
|
|
36
|
+
**Shared**
|
|
37
37
|
|
|
38
38
|
```luau
|
|
39
39
|
local Lync = require(game.ReplicatedStorage.Lync)
|
|
@@ -163,7 +163,7 @@ end
|
|
|
163
163
|
| | What it does |
|
|
164
164
|
|:---------|:------------|
|
|
165
165
|
| `Lync.start()` | Sets up transport. Server creates remotes, client connects. Call once after all definitions. |
|
|
166
|
-
| `Lync.VERSION` | `"1.4.
|
|
166
|
+
| `Lync.VERSION` | `"1.4.2"` |
|
|
167
167
|
|
|
168
168
|
## Packets
|
|
169
169
|
|
|
@@ -198,9 +198,9 @@ packet:send(data) -- send to server
|
|
|
198
198
|
|
|
199
199
|
| Method | What it does |
|
|
200
200
|
|:-------|:------------|
|
|
201
|
-
| `packet:listen(fn(data, sender))` |
|
|
202
|
-
| `packet:once(fn(data, sender))` |
|
|
203
|
-
| `packet:wait()` |
|
|
201
|
+
| `packet:listen(fn(data, sender))` | Sender is `Player` on server, `nil` on client. Returns a Connection. |
|
|
202
|
+
| `packet:once(fn(data, sender))` | Auto-disconnects after one fire. |
|
|
203
|
+
| `packet:wait()` | Returns `(data, sender)`. |
|
|
204
204
|
| `packet:disconnectAll()` | Kills all listeners on this packet. |
|
|
205
205
|
|
|
206
206
|
## Queries
|
|
@@ -248,7 +248,7 @@ Returned by `packet:listen()`, `packet:once()`, `query:listen()`, and `ns:listen
|
|
|
248
248
|
|
|
249
249
|
| | What it does |
|
|
250
250
|
|:-------|:------------|
|
|
251
|
-
| `connection.connected` | `
|
|
251
|
+
| `connection.connected` | `boolean` |
|
|
252
252
|
| `connection:disconnect()` | Stops the listener. |
|
|
253
253
|
|
|
254
254
|
## Scope
|
|
@@ -267,11 +267,11 @@ scope:destroy() -- disconnects everything
|
|
|
267
267
|
|
|
268
268
|
| Method | What it does |
|
|
269
269
|
|:-------|:------------|
|
|
270
|
-
| `scope:listen(source, fn)` | Calls source:listen(fn) and tracks the connection. |
|
|
271
|
-
| `scope:once(source, fn)` | Calls source:once(fn) and tracks the connection. |
|
|
272
|
-
| `scope:listenAll(namespace, fn)` | Calls namespace:listenAll(fn) and tracks the connection. |
|
|
273
|
-
| `scope:add(connection)` |
|
|
274
|
-
| `scope:destroy()` |
|
|
270
|
+
| `scope:listen(source, fn)` | Calls `source:listen(fn)` and tracks the connection. |
|
|
271
|
+
| `scope:once(source, fn)` | Calls `source:once(fn)` and tracks the connection. |
|
|
272
|
+
| `scope:listenAll(namespace, fn)` | Calls `namespace:listenAll(fn)` and tracks the connection. |
|
|
273
|
+
| `scope:add(connection)` | Also accepts RBXScriptConnection. |
|
|
274
|
+
| `scope:destroy()` | Safe to call multiple times. |
|
|
275
275
|
|
|
276
276
|
## Groups
|
|
277
277
|
|
|
@@ -291,11 +291,11 @@ packet:send(data, vips)
|
|
|
291
291
|
|:-------|:--------|:-------------|
|
|
292
292
|
| `group:add(player)` | `boolean` | `true` if added, `false` if already in. |
|
|
293
293
|
| `group:remove(player)` | `boolean` | `true` if removed, `false` if wasnt in there. |
|
|
294
|
-
| `group:has(player)` | `boolean` | |
|
|
295
|
-
| `group:count()` | `number` | |
|
|
296
|
-
| `group:getSet()` | `{ [Player]: true }` | |
|
|
297
|
-
| `group:forEach(fn)` | | Calls `fn(player)` for each member. |
|
|
298
|
-
| `group:destroy()` | | Removes the group and all memberships. |
|
|
294
|
+
| `group:has(player)` | `boolean` | Whether the player is in the group. |
|
|
295
|
+
| `group:count()` | `number` | Number of members. |
|
|
296
|
+
| `group:getSet()` | `{ [Player]: true }` | Snapshot of the internal set. |
|
|
297
|
+
| `group:forEach(fn)` | `()` | Calls `fn(player)` for each member. |
|
|
298
|
+
| `group:destroy()` | `()` | Removes the group and all memberships. |
|
|
299
299
|
|
|
300
300
|
## Middleware
|
|
301
301
|
|
|
@@ -415,10 +415,10 @@ Reliable only. Lync will error if you try to use these with `unreliable = true`.
|
|
|
415
415
|
|
|
416
416
|
| Scenario | Without Lync | With Lync | FPS |
|
|
417
417
|
|:---------|------------:|---------:|----:|
|
|
418
|
-
| Static booleans (1B) | 480 Kbps | **2.
|
|
419
|
-
| Static entities (34B) | 16,320 Kbps | **2.
|
|
420
|
-
| Moving entities | 16,320 Kbps | **3.
|
|
421
|
-
| Chaotic entities | 16,320 Kbps | **4.
|
|
418
|
+
| Static booleans (1B) | 480 Kbps | **2.34 Kbps** | 60.00 |
|
|
419
|
+
| Static entities (34B) | 16,320 Kbps | **2.62 Kbps** | 60.00 |
|
|
420
|
+
| Moving entities | 16,320 Kbps | **3.14 Kbps** | 60.00 |
|
|
421
|
+
| Chaotic entities | 16,320 Kbps | **4.76 Kbps** | 59.99 |
|
|
422
422
|
|
|
423
423
|
### Cross-Library Comparison
|
|
424
424
|
|
|
@@ -437,7 +437,7 @@ Same data shapes and methodology as [Blink's benchmark suite](https://github.com
|
|
|
437
437
|
| Tool (Kbps) | Median | P0 | P80 | P90 | P95 | P100 |
|
|
438
438
|
|:------------|-------:|---:|----:|----:|----:|-----:|
|
|
439
439
|
| roblox | 559,364 | 559,364 | 676,715 | 676,715 | 676,715 | 784,081 |
|
|
440
|
-
| **lync** | **3.
|
|
440
|
+
| **lync** | **3.61** | 3.53 | 3.63 | 3.64 | 3.64 | 4.64 |
|
|
441
441
|
| blink | 41.81 | 26.30 | 42.40 | 42.48 | 42.48 | 42.62 |
|
|
442
442
|
| zap | 41.71 | 25.46 | 42.19 | 42.32 | 42.32 | 42.93 |
|
|
443
443
|
| bytenet | 41.64 | 22.84 | 42.36 | 42.82 | 42.82 | 43.24 |
|
|
@@ -447,7 +447,7 @@ Same data shapes and methodology as [Blink's benchmark suite](https://github.com
|
|
|
447
447
|
| Tool (FPS) | Median | P0 | P80 | P90 | P95 | P100 |
|
|
448
448
|
|:-----------|-------:|---:|----:|----:|----:|-----:|
|
|
449
449
|
| roblox | 21.00 | 22.00 | 20.00 | 19.00 | 19.00 | 19.00 |
|
|
450
|
-
| **lync** | **60.00** | 61.00 | 60.00 |
|
|
450
|
+
| **lync** | **60.00** | 61.00 | 60.00 | 60.00 | 60.00 | 59.00 |
|
|
451
451
|
| blink | 97.00 | 98.00 | 97.00 | 96.00 | 96.00 | 96.00 |
|
|
452
452
|
| zap | 52.00 | 53.00 | 51.00 | 51.00 | 51.00 | 49.00 |
|
|
453
453
|
| bytenet | 35.00 | 37.00 | 35.00 | 35.00 | 35.00 | 34.00 |
|
|
@@ -455,7 +455,7 @@ Same data shapes and methodology as [Blink's benchmark suite](https://github.com
|
|
|
455
455
|
| Tool (Kbps) | Median | P0 | P80 | P90 | P95 | P100 |
|
|
456
456
|
|:------------|-------:|---:|----:|----:|----:|-----:|
|
|
457
457
|
| roblox | 353,107 | 196,826 | 690,747 | 842,240 | 842,240 | 1,124,176 |
|
|
458
|
-
| **lync** | **4.31** | 3.
|
|
458
|
+
| **lync** | **4.31** | 3.85 | 4.36 | 4.38 | 4.38 | 4.44 |
|
|
459
459
|
| blink | 7.91 | 7.41 | 7.93 | 7.99 | 7.99 | 8.00 |
|
|
460
460
|
| zap | 8.10 | 5.75 | 8.17 | 8.22 | 8.22 | 8.27 |
|
|
461
461
|
| bytenet | 8.11 | 5.07 | 8.35 | 8.46 | 8.46 | 8.47 |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axpecter/lync",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "Buffer networking for Roblox. Delta compression, XOR framing, built-in security.",
|
|
5
5
|
"main": "src/init.luau",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"luau"
|
|
29
29
|
],
|
|
30
30
|
"files": [
|
|
31
|
-
"src"
|
|
31
|
+
"src",
|
|
32
|
+
"README.md"
|
|
32
33
|
],
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@rbxts/compiler-types": "^3.0.0-types.0",
|
package/src/Types.luau
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!optimize 2
|
|
3
|
-
-- Shared type definitions.
|
|
3
|
+
-- Shared type definitions for the Lync networking library.
|
|
4
4
|
|
|
5
5
|
export type ChannelState = {
|
|
6
6
|
buff: buffer,
|
|
@@ -10,7 +10,7 @@ export type ChannelState = {
|
|
|
10
10
|
lastId: number,
|
|
11
11
|
countPos: number,
|
|
12
12
|
itemCount: number,
|
|
13
|
-
deltas: { [number]: any },
|
|
13
|
+
deltas: { [number]: any }, -- per-codec delta caches; shape varies by codec kind
|
|
14
14
|
prevDump: buffer?,
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -19,6 +19,17 @@ export type Codec<T> = {
|
|
|
19
19
|
read: (src: buffer, pos: number, refs: { Instance }?) -> (T, number),
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
-- Extended codec exposing internal fast-path metadata used by composite codecs.
|
|
23
|
+
export type InternalCodec<T> = {
|
|
24
|
+
write: (ch: ChannelState, value: T) -> (),
|
|
25
|
+
read: (src: buffer, pos: number, refs: { Instance }?) -> (T, number),
|
|
26
|
+
_size: number?,
|
|
27
|
+
_directWrite: ((b: buffer, offset: number, value: T) -> ())?,
|
|
28
|
+
_directRead: ((b: buffer, offset: number) -> T)?,
|
|
29
|
+
_isDelta: boolean?,
|
|
30
|
+
_isBool: boolean?,
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
export type RateLimitConfig = {
|
|
23
34
|
maxPerSecond: number,
|
|
24
35
|
burstAllowance: number?,
|
package/src/api/Group.luau
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
local Players = game:GetService ("Players")
|
|
6
6
|
|
|
7
|
-
-- State
|
|
7
|
+
-- State --------------------------------------------------------------
|
|
8
8
|
|
|
9
9
|
local _groups = {} :: { [string]: { [Player]: true } }
|
|
10
10
|
local _counts = {} :: { [string]: number }
|
|
11
11
|
local _playerGroups = {} :: { [Player]: { [string]: true } }
|
|
12
12
|
|
|
13
|
-
-- Private
|
|
13
|
+
-- Private ------------------------------------------------------------
|
|
14
14
|
|
|
15
15
|
local function onPlayerRemoving (player: Player): ()
|
|
16
16
|
local memberships = _playerGroups[player]
|
|
@@ -31,8 +31,6 @@ end
|
|
|
31
31
|
|
|
32
32
|
Players.PlayerRemoving:Connect (onPlayerRemoving)
|
|
33
33
|
|
|
34
|
-
-- GroupImpl ---------------------------------------------------------------
|
|
35
|
-
|
|
36
34
|
local GroupImpl = {}
|
|
37
35
|
GroupImpl.__index = GroupImpl
|
|
38
36
|
|
|
@@ -139,7 +137,7 @@ end
|
|
|
139
137
|
|
|
140
138
|
table.freeze (GroupImpl)
|
|
141
139
|
|
|
142
|
-
-- Public
|
|
140
|
+
-- Public -------------------------------------------------------------
|
|
143
141
|
|
|
144
142
|
local Group = {}
|
|
145
143
|
|
package/src/api/Namespace.luau
CHANGED
|
@@ -11,16 +11,16 @@ type Connection = Types.Connection
|
|
|
11
11
|
type PacketConfig<T> = Types.PacketConfig<T>
|
|
12
12
|
type QueryConfig<R, S> = Types.QueryConfig<R, S>
|
|
13
13
|
|
|
14
|
-
-- Constants
|
|
14
|
+
-- Constants ----------------------------------------------------------
|
|
15
15
|
|
|
16
16
|
local MAX_NAMESPACES = 64
|
|
17
17
|
|
|
18
|
-
-- State
|
|
18
|
+
-- State --------------------------------------------------------------
|
|
19
19
|
|
|
20
20
|
local _registered = {} :: { [string]: true }
|
|
21
21
|
local _count = 0
|
|
22
22
|
|
|
23
|
-
-- Private
|
|
23
|
+
-- Private ------------------------------------------------------------
|
|
24
24
|
|
|
25
25
|
type NamespaceConfig = {
|
|
26
26
|
packets: { [string]: PacketConfig<any> }?,
|
|
@@ -47,8 +47,6 @@ local function scopedHandler (
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
-- Namespace --------------------------------------------------------------
|
|
51
|
-
|
|
52
50
|
local NamespaceImpl = {}
|
|
53
51
|
NamespaceImpl.__index = NamespaceImpl
|
|
54
52
|
|
|
@@ -173,7 +171,9 @@ function NamespaceImpl.queryNames (self: any): { string }
|
|
|
173
171
|
return result
|
|
174
172
|
end
|
|
175
173
|
|
|
176
|
-
|
|
174
|
+
table.freeze (NamespaceImpl)
|
|
175
|
+
|
|
176
|
+
-- Public -------------------------------------------------------------
|
|
177
177
|
|
|
178
178
|
local Namespace = {}
|
|
179
179
|
|
package/src/api/Packet.luau
CHANGED
|
@@ -11,9 +11,10 @@ local Signal = require (script.Parent.Signal)
|
|
|
11
11
|
local Types = require (script.Parent.Parent.Types)
|
|
12
12
|
|
|
13
13
|
type Connection = Types.Connection
|
|
14
|
+
type InternalCodec<T> = Types.InternalCodec<T>
|
|
14
15
|
type PacketConfig<T> = Types.PacketConfig<T>
|
|
15
16
|
|
|
16
|
-
-- Constants
|
|
17
|
+
-- Constants ----------------------------------------------------------
|
|
17
18
|
|
|
18
19
|
local IS_SERVER = RunService:IsServer ()
|
|
19
20
|
|
|
@@ -24,7 +25,10 @@ local serverWriteToAllExcept = Server.writeToAllExcept
|
|
|
24
25
|
local serverWriteToSet = Server.writeToSet
|
|
25
26
|
local clientWrite = Client.write
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
local DELTA_TARGETED = 1
|
|
29
|
+
local DELTA_BROADCAST = 2
|
|
30
|
+
|
|
31
|
+
-- Private ------------------------------------------------------------
|
|
28
32
|
|
|
29
33
|
-- Shared methods (both contexts)
|
|
30
34
|
local SharedImpl = {}
|
|
@@ -49,9 +53,6 @@ end
|
|
|
49
53
|
local ServerImpl = setmetatable ({}, { __index = SharedImpl })
|
|
50
54
|
ServerImpl.__index = ServerImpl
|
|
51
55
|
|
|
52
|
-
local DELTA_TARGETED = 1
|
|
53
|
-
local DELTA_BROADCAST = 2
|
|
54
|
-
|
|
55
56
|
local function checkDeltaMode (self: any, mode: number): ()
|
|
56
57
|
if not self._isDelta then
|
|
57
58
|
return
|
|
@@ -122,7 +123,7 @@ end
|
|
|
122
123
|
|
|
123
124
|
table.freeze (ClientImpl)
|
|
124
125
|
|
|
125
|
-
-- Public
|
|
126
|
+
-- Public -------------------------------------------------------------
|
|
126
127
|
|
|
127
128
|
local Packet = {}
|
|
128
129
|
|
|
@@ -136,7 +137,7 @@ function Packet.define (name: string, config: PacketConfig<any>): any
|
|
|
136
137
|
|
|
137
138
|
local isUnreliable = config.unreliable or false
|
|
138
139
|
|
|
139
|
-
if (config.value :: any)._isDelta and isUnreliable then
|
|
140
|
+
if (config.value :: InternalCodec<any>)._isDelta and isUnreliable then
|
|
140
141
|
error (`[Lync] Delta codec requires reliable delivery: "{name}"`)
|
|
141
142
|
end
|
|
142
143
|
|
|
@@ -152,7 +153,7 @@ function Packet.define (name: string, config: PacketConfig<any>): any
|
|
|
152
153
|
config.maxPayloadBytes
|
|
153
154
|
)
|
|
154
155
|
|
|
155
|
-
local isDelta = (config.value :: any)._isDelta == true
|
|
156
|
+
local isDelta = (config.value :: InternalCodec<any>)._isDelta == true
|
|
156
157
|
|
|
157
158
|
return setmetatable ({
|
|
158
159
|
_id = reg.id,
|
package/src/api/Query.luau
CHANGED
|
@@ -14,14 +14,14 @@ local Types = require (script.Parent.Parent.Types)
|
|
|
14
14
|
type Connection = Types.Connection
|
|
15
15
|
type QueryConfig<R, S> = Types.QueryConfig<R, S>
|
|
16
16
|
|
|
17
|
-
-- Constants
|
|
17
|
+
-- Constants ----------------------------------------------------------
|
|
18
18
|
|
|
19
19
|
local IS_SERVER = RunService:IsServer ()
|
|
20
20
|
|
|
21
21
|
-- Wire ceiling: correlationId is u16 in Channel.writeQuery / Reader.process.
|
|
22
22
|
local POOL_SIZE = 65536
|
|
23
23
|
|
|
24
|
-
-- State
|
|
24
|
+
-- State --------------------------------------------------------------
|
|
25
25
|
|
|
26
26
|
type PendingQuery = {
|
|
27
27
|
thread: thread?,
|
|
@@ -33,7 +33,7 @@ local _pending = {} :: { [number]: PendingQuery }
|
|
|
33
33
|
local _nextId = 0
|
|
34
34
|
local _activeCount = 0
|
|
35
35
|
|
|
36
|
-
-- Private
|
|
36
|
+
-- Private ------------------------------------------------------------
|
|
37
37
|
|
|
38
38
|
local function allocCorrelation (): number
|
|
39
39
|
if _activeCount >= POOL_SIZE then
|
|
@@ -53,7 +53,9 @@ local function allocCorrelation (): number
|
|
|
53
53
|
return id
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
-- Decrements the active correlation counter. Does not free a specific slot;
|
|
57
|
+
-- that is handled by nil-ing _pending[id] at the call site.
|
|
58
|
+
local function releaseCorrelation (): ()
|
|
57
59
|
_activeCount -= 1
|
|
58
60
|
end
|
|
59
61
|
|
|
@@ -64,7 +66,7 @@ local function completeQuery (id: number, data: any): ()
|
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
_pending[id] = nil
|
|
67
|
-
|
|
69
|
+
releaseCorrelation ()
|
|
68
70
|
|
|
69
71
|
if entry.timeout then
|
|
70
72
|
task.cancel (entry.timeout)
|
|
@@ -158,7 +160,7 @@ local function requestMulti (self: any, players: { Player }, data: any): { [Play
|
|
|
158
160
|
local entry = _pending[cid]
|
|
159
161
|
if entry then
|
|
160
162
|
_pending[cid] = nil
|
|
161
|
-
|
|
163
|
+
releaseCorrelation ()
|
|
162
164
|
end
|
|
163
165
|
end
|
|
164
166
|
|
|
@@ -176,8 +178,6 @@ local function requestMulti (self: any, players: { Player }, data: any): { [Play
|
|
|
176
178
|
return coroutine.yield ()
|
|
177
179
|
end
|
|
178
180
|
|
|
179
|
-
-- Query ------------------------------------------------------------------
|
|
180
|
-
|
|
181
181
|
local QueryImpl = {}
|
|
182
182
|
QueryImpl.__index = QueryImpl
|
|
183
183
|
|
|
@@ -274,7 +274,9 @@ function QueryImpl.requestGroup (self: any, group: any, data: any): { [Player]:
|
|
|
274
274
|
return requestMulti (self, players, data)
|
|
275
275
|
end
|
|
276
276
|
|
|
277
|
-
|
|
277
|
+
table.freeze (QueryImpl)
|
|
278
|
+
|
|
279
|
+
-- Public -------------------------------------------------------------
|
|
278
280
|
|
|
279
281
|
local Query = {}
|
|
280
282
|
|
package/src/api/Scope.luau
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Batched connection lifecycle management.
|
|
4
4
|
|
|
5
|
-
-- Private
|
|
5
|
+
-- Private ------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
local ScopeImpl = {}
|
|
8
8
|
ScopeImpl.__index = ScopeImpl
|
|
@@ -62,7 +62,7 @@ end
|
|
|
62
62
|
|
|
63
63
|
table.freeze (ScopeImpl)
|
|
64
64
|
|
|
65
|
-
-- Public
|
|
65
|
+
-- Public -------------------------------------------------------------
|
|
66
66
|
|
|
67
67
|
local Scope = {}
|
|
68
68
|
|
package/src/api/Signal.luau
CHANGED
|
@@ -6,12 +6,13 @@ local Types = require (script.Parent.Parent.Types)
|
|
|
6
6
|
|
|
7
7
|
type Connection = Types.Connection
|
|
8
8
|
|
|
9
|
-
--
|
|
9
|
+
-- Constants ----------------------------------------------------------
|
|
10
|
+
|
|
10
11
|
local STATE_DISCONNECTED = 0
|
|
11
12
|
local STATE_CONNECTED = 1
|
|
12
13
|
local STATE_ONCE = 2
|
|
13
14
|
|
|
14
|
-
-- Private
|
|
15
|
+
-- Private ------------------------------------------------------------
|
|
15
16
|
|
|
16
17
|
local _freeThread: thread? = nil
|
|
17
18
|
|
|
@@ -36,7 +37,9 @@ local function spawn (fn: (...any) -> (), ...: any): ()
|
|
|
36
37
|
task.spawn (_freeThread :: thread, fn, ...)
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
-- Entry doubles as the Connection handle
|
|
40
|
+
-- Entry doubles as the Connection handle: 1 alloc per listener instead of 2.
|
|
41
|
+
-- self: any — metatable typing via typeof(setmetatable) is not practical here
|
|
42
|
+
-- because Entry and Signal reference each other circularly.
|
|
40
43
|
local EntryImpl = {}
|
|
41
44
|
EntryImpl.__index = EntryImpl
|
|
42
45
|
|
|
@@ -213,7 +216,10 @@ function SignalImpl.disconnectAll (self: any): ()
|
|
|
213
216
|
self._count = 0
|
|
214
217
|
end
|
|
215
218
|
|
|
216
|
-
|
|
219
|
+
table.freeze (EntryImpl)
|
|
220
|
+
table.freeze (SignalImpl)
|
|
221
|
+
|
|
222
|
+
-- Public -------------------------------------------------------------
|
|
217
223
|
|
|
218
224
|
local Signal = {}
|
|
219
225
|
|
package/src/codec/Base.luau
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
-- Fixed-size codec factory. Every fixed-size codec calls Base.define once.
|
|
4
4
|
|
|
5
5
|
local Channel = require (script.Parent.Parent.internal.Channel)
|
|
6
|
+
local Types = require (script.Parent.Parent.Types)
|
|
7
|
+
|
|
8
|
+
type ChannelState = Types.ChannelState
|
|
9
|
+
|
|
6
10
|
local alloc = Channel.alloc
|
|
7
11
|
|
|
8
|
-
-- Public
|
|
12
|
+
-- Public -------------------------------------------------------------
|
|
9
13
|
|
|
10
14
|
local Base = {}
|
|
11
15
|
|
|
@@ -18,7 +22,7 @@ function Base.define <T>(
|
|
|
18
22
|
_size = size,
|
|
19
23
|
_directWrite = directWrite,
|
|
20
24
|
_directRead = directRead,
|
|
21
|
-
write = function (ch:
|
|
25
|
+
write = function (ch: ChannelState, value: T): ()
|
|
22
26
|
local c = ch.cursor
|
|
23
27
|
if c + size > ch.size then
|
|
24
28
|
alloc (ch, size)
|
|
@@ -39,7 +43,7 @@ function Base.zero (): any
|
|
|
39
43
|
_directRead = function (_b: buffer, _offset: number): any
|
|
40
44
|
return nil
|
|
41
45
|
end,
|
|
42
|
-
write = function (_ch:
|
|
46
|
+
write = function (_ch: ChannelState, _value: any): () end,
|
|
43
47
|
read = function (_src: buffer, _pos: number, _refs: { Instance }?): (any, number)
|
|
44
48
|
return nil, 0
|
|
45
49
|
end,
|
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
local Baseline = require (script.Parent.Parent.Parent.internal.Baseline)
|
|
6
6
|
local Channel = require (script.Parent.Parent.Parent.internal.Channel)
|
|
7
|
-
local alloc = Channel.alloc
|
|
8
7
|
local Shared = require (script.Parent.Shared)
|
|
9
8
|
local Types = require (script.Parent.Parent.Parent.Types)
|
|
9
|
+
local Varint = require (script.Parent.Parent.primitive.Varint)
|
|
10
10
|
|
|
11
11
|
type ChannelState = Types.ChannelState
|
|
12
12
|
type Codec<T> = Types.Codec<T>
|
|
13
|
-
|
|
13
|
+
type InternalCodec<T> = Types.InternalCodec<T>
|
|
14
14
|
|
|
15
|
+
local alloc = Channel.alloc
|
|
15
16
|
local rangeEqual = Shared.rangeEqual
|
|
16
17
|
local acquireScratch = Shared.acquireScratch
|
|
17
18
|
local releaseScratch = Shared.releaseScratch
|
|
@@ -20,7 +21,7 @@ local FLAG_DELTA = Shared.FLAG_DELTA
|
|
|
20
21
|
local FLAG_FULL = Shared.FLAG_FULL
|
|
21
22
|
local FLAG_UNCHANGED = Shared.FLAG_UNCHANGED
|
|
22
23
|
|
|
23
|
-
-- Public
|
|
24
|
+
-- Public -------------------------------------------------------------
|
|
24
25
|
|
|
25
26
|
local Array = {}
|
|
26
27
|
|
|
@@ -30,9 +31,10 @@ function Array.deltaArray (element: Codec<any>, maxCount: number?): Codec<{ any
|
|
|
30
31
|
local writeElement = element.write
|
|
31
32
|
local readElement = element.read
|
|
32
33
|
|
|
33
|
-
local
|
|
34
|
-
local
|
|
35
|
-
local
|
|
34
|
+
local internal = element :: InternalCodec<any>
|
|
35
|
+
local elemSize = internal._size
|
|
36
|
+
local elemWrite = internal._directWrite
|
|
37
|
+
local elemRead = internal._directRead
|
|
36
38
|
|
|
37
39
|
return table.freeze ({
|
|
38
40
|
_isDelta = true,
|
|
@@ -45,13 +47,13 @@ function Array.deltaArray (element: Codec<any>, maxCount: number?): Codec<{ any
|
|
|
45
47
|
local bounds = table.create (len + 1)
|
|
46
48
|
bounds[1] = 0
|
|
47
49
|
|
|
48
|
-
if
|
|
50
|
+
if elemWrite and elemSize then
|
|
49
51
|
local totalBytes = len * elemSize
|
|
50
52
|
alloc (scratch, totalBytes)
|
|
51
53
|
local b = scratch.buff
|
|
52
54
|
local c = 0
|
|
53
55
|
for i = 1, len do
|
|
54
|
-
|
|
56
|
+
elemWrite (b, c, value[i])
|
|
55
57
|
c += elemSize
|
|
56
58
|
bounds[i + 1] = c
|
|
57
59
|
end
|
|
@@ -147,9 +149,9 @@ function Array.deltaArray (element: Codec<any>, maxCount: number?): Codec<{ any
|
|
|
147
149
|
|
|
148
150
|
local result = table.create (len)
|
|
149
151
|
|
|
150
|
-
if
|
|
152
|
+
if elemRead and elemSize then
|
|
151
153
|
for i = 1, len do
|
|
152
|
-
result[i] =
|
|
154
|
+
result[i] = elemRead (src, absPos)
|
|
153
155
|
absPos += elemSize
|
|
154
156
|
end
|
|
155
157
|
else
|
|
@@ -174,8 +176,8 @@ function Array.deltaArray (element: Codec<any>, maxCount: number?): Codec<{ any
|
|
|
174
176
|
local idx, idxBytes = Varint.read (src, absPos)
|
|
175
177
|
absPos += idxBytes
|
|
176
178
|
|
|
177
|
-
if
|
|
178
|
-
result[idx + 1] =
|
|
179
|
+
if elemRead and elemSize then
|
|
180
|
+
result[idx + 1] = elemRead (src, absPos)
|
|
179
181
|
absPos += elemSize
|
|
180
182
|
else
|
|
181
183
|
local val, n = readElement (src, absPos, refs)
|
|
@@ -191,9 +193,10 @@ function Array.deltaArray (element: Codec<any>, maxCount: number?): Codec<{ any
|
|
|
191
193
|
end
|
|
192
194
|
|
|
193
195
|
function Array.array (element: Codec<any>, maxCount: number?): Codec<{ any }>
|
|
194
|
-
local
|
|
195
|
-
local
|
|
196
|
-
local
|
|
196
|
+
local internal = element :: InternalCodec<any>
|
|
197
|
+
local elementSize = internal._size
|
|
198
|
+
local directWrite = internal._directWrite
|
|
199
|
+
local directRead = internal._directRead
|
|
197
200
|
|
|
198
201
|
if elementSize and directWrite and directRead then
|
|
199
202
|
return table.freeze ({
|